2016년 1월 25일 월요일

[iOS] Apple Push Notification Service(APNS) Java Server Example

Apple Push Notification Service(APNS) Server 간단 예제.

해당 예제는 javapns를 통해서 간략히 만든 것임을 밝힘.
javapns의 풀 소스를 보시려면 아래의 링크를 따라 가면 됨.
Google Code Archive - JavaPNS

[ 준비 사항 ]
- JavaPNS_2.2.jar (위의 링크에서 다운 가능)


1:  import javapns.Push;  
2:  import javapns.notification.PushNotificationPayload;  
3:    
4:  public class NotificationTest {  
5:    
6:       private static String token = "Device Token";  
7:       private static String keystore = "The path of the .p12 file";  
8:       private static String password = "The password of the .p12 file";  
9:    
10:       public static void main(String[] args) throws Exception {  
11:    
12:            System.out.println("Setting up Push notification");  
13:    
14:            try {  
15:                 // Setup up a simple message  
16:                 PushNotificationPayload payload = new PushNotificationPayload();  
17:                 payload.addAlert("PushTest");  
18:                 payload.addBadge(1);  
19:                 payload.addSound("default");  
20:                 System.out.println(payload);  
21:                 System.out.println("Payload setup successfull.");  
22:    
23:                 // Push.payload(Payload payload, Object keystore, String password, boolean production, Object devices)  
24:                 // production (true/false)  
25:                 // true : Distribute (gateway.push.apple.com)  
26:                 // false : Developer (gateway.sandbox.push.apple.com)  
27:                 Push.payload(payload, keystore, password, false, token);  
28:    
29:            } catch (Exception e) {  
30:                 e.printStackTrace();  
31:            }  
32:       }  
33:  }  
  • private static String token : 토큰의 경우 App에서 APNS 등록 할 때 사용하는 token
  • private static String keystore : .p12 파일의 경로 
  • private static String password : .p12 파일 생성시 설정한 비밀번호
  • APNS 서버 주소는 개발용과 배포용이 다르기 때문에 개발 중인 App의 인증서에 따라 Push.payload의 production의 값 변경 (true:배포용, false:개발용)
iOS 8이전의  경우 서버에서 보내주는 푸시 메시지 형식에 sound에 관련하여 넣지 않으면 default가 적용되었지만 iOS 8부터는 필수로 sound 값을 넣어주어야 한다.


[iOS] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure.

iOS 9 및 OSX 10.11 ElCapitan 업데이트에 App Transport Security(ATS) 가 추가 되었다.

iOS 9 인 iPhone(이하 기기)에서 기존 서버의 웹 페이지에 접속이 안되는 것을 발견하고 급당황
더 당황스러운 것은 이제서야 발견 했다는거 .... (테스트 폰을 iOS 9으로 업데이트를 안했다는 것이 함정)

암튼 기기에서 http:// 로 시작 하는 웹 페이지로 접속 하려고 하면 아래와 같은 로그를 볼 수 있다.

" App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file "

App Transport Security 가 HTTP (암호화 되지 않은 텍스트) 로의 접속을 보안상 안전하지 않은 이유로 막았고 임시 예외처리를 Info.plist를 통해 설정할 수 있다.

Info.plist로 예외처리를 할 수 있다지만 일시적이라는 것이 맘에 걸리긴 하지만 당장 접속이 되어야 하기 때문에 설정을 해 본다

우선 App Transport Security (ATS)가 무엇인고 하니.

iOS Developer Libray에 친절히 적어 놓으셨다. What's New in iOS
결론적으로 말하자면 보안상의 이유로 HTTPS를 기본 접속으로 설정 해 놓았다 머 이런 얘기.

위에서 말한대로 Info.plist에 일시적인 예외처리 설정을 통해서 App Transport Security(ATS)를 비활성화 해줄 수 있다.

NSAppTransportSecurity -> NSAllowsArbitraryLoads : true.


Info.plist에서 해당 항목이 보이지 않으면 Info.plist를 Source code로 열면 xml 형식으로 보여준다.


위의 항목을 추가 시켜 주면 끝.

하나 해결 했굼.

2014년 3월 7일 금요일

[Android][번역] Intents and Intent Filters - 2.1

원본 : http://developer.android.com/guide/components/intents-filters.html

Building and Intent
Intnet 객체는 시스템이 어떠한 component를 실행 시킬 지 결정 하는 정보를 가지고 있다 (정확한 클래스 이름 또는 Intent를 받을 수 있는 component 항목과 같은 정보), 추가로 Intent를 받는 component가 제대로 된 기능을 수행 할 수 있도록 하는 정보(기능을 수행하고, 데이터에 따라 수행 하도록 하는 것)도 가지고 있다.

Intent가 가지고 있는 주요한 정보는 다음과 같다.

 - Component name
실행하는 Component의 이름

이것은 부가적인 것이지만, Intent를 explicit 하게 만드는 매우 중요한 정보 중의 하나 이다. Intent가 오직 component 이름으로 정의된 app component에 전달 될 수 있음을 뜻한다.
Component 이름이 없는 Intent는 implicit이고 시스템은 component가 다른 Intent 정보를 기반으로 한 Intent를 받을 수 있도록 결정 한다.(action, data 그리고 category - 아래에 나열된 것들). 그래서 만약 App에서 특정 component를 실행 할 필요가 있다면, component 이름을 명시해 주어야 한다.

Note : Service를 실행 할 때에는, 항상 component 이름으로 실행 하여야 한다. 그렇지 않으면 Service가 Intent에 응답 하는 것을 확신치 못하며, Service가 실행 되는 것을 알 수가 없다.

이 Intent의 부분은 ComponentName 객체 이다. app의 패키지 이름을 포함한 목표 component의 완전히 증명된 클래스 이름을 명시 할 수 있다. 예) com.example.ExampleActivity. component 이름은 setComponent(), setClass(), setClassName() 또는 Intent 생성자로 설정 할 수 있다.

 - Action
일반적인 기능 수행(view 또는 pick)을 명시한 String.

broadcast Intent의 경우, 이것은 실행하고 보고 하는 action 이다. 그 action 은 주로 나머지 intent가 어떻게 구성되어졌는데 알아낸다. - 특히 어떤 data와 extra가 포함되어 있는지.

App에서 intent를 이용한 자신만의 action을 명시 할 수 있다. (또는 다른 앱의 component를 적용 하기 위한 action), 하지만 Intent 클래스 또는 다른 framework 클래스에 정의된 action 상수를 사용하는 것이 좋다.

Activity를 실행하기 위한 일반적인 action들이 있다.

 ACTION_VIEW
갤러리 App의 사진 또는 맵 App의 주소와 같은 정보를 Activity에서 사용자에게 보여줘야 할 때 이 Action을 가지고 있는 Intent와 startActivity()를 사용 하면 된다.

 ACTION_SEND
이것 역시 "공유" Intent로 알고 있는것으로, 사용자가 Email App 또는 소셜 공유 App을 통해서 공유 할 수 있는 어떠한 데이터를 가지고 있다면 이 때 이 Action을 포함한 Intent와 startActivity()를 사용 하면 된다.

일반적으로 사용되는 Action을 정의한 더 많은 상수들은 Intent 클래스 참조를 통해 볼 수 있다. 시스템의 설정 App에서 특정 화면을 보여주는 Action이 Setting 클래스에 정의 되어 있는것과 같이 안드로이드 framework의 어딘가에 다른 Action들이 정의되어 있다.

Action은 setAction() 또는 Intent 생성자로 명시 할 수 있다.

만약 자신만의 Action들을 정의 한다면, 접두에 App의 패키지 이름을 포함 하여야 한다.

예)







2014년 3월 3일 월요일

[Android][번역] Intents and Intent Filters - 1

원문 : http://developer.android.com/guide/components/intents-filters.html

Intents and Intent Filters

Intent는 다른 app component에 기능을 요청 할 수 있는 메시징 객체이다.
비록 Intent가 components 간의 Communication을 가능 하게 하는 여러 방법이 있지만
세가지의 근본적인 사용 방법이 있다.

 - Activity 시작
Activity는 App에서 단일 화면을 표현해 준다. 새로운 Activity 객체를 시작할 땐 startActivity()로 Intent를 전달 해 준다. Intent는 Activity를 시작하기위한 설명과 필요한 데이터를 가지고 있다. 만약 새로 시작 한 Activity가 끝날 때 결과를 받고 싶다면 startActivityForResult()를 호출 하면 된다. 결과를 받고자 하는 Activity에서는 Intent 객체와는 별개로 onActivityResult() callback을 통해서 결과를 받을 수 있다.

 - Service 시작
Service는 UI가 없이 백그라운드에서 기능을 수행하는 Component이다.
Service에서 one-time operation(파일 다운로드와 같은) 기능을 startService()로 Intent를 전달 하여 시작할 수 있다. Intent는 Service를 시작하기위한 설명과 필요한 데이터를 가지고 있다. 만약 Service가 client-server 로 디자인 되어있다면, Intent를 bindService()를 통해 전달 하여 다른 app component와 묶을 수 있다.

 - Broadcast 전달
broadcast는 어떠한 App에서도 받을 수 있는 메시지 이다. 시스템은 시스템 전원 켜짐 또는 기기가 충전을 시작하는 등 과 같은 시스템 이벤트를 위한 여러가지 broadcast들을 전달 한다. broadcast는 sendBroadcast(), sendOrderedBroadcast() 또는 sendStickyBroadcast()로 Intent를 전달하여 다른 app에 broadcast를 전달 할 수 있다.


Intent Types

두 가지의 Intent 타입이 있다.

 - Explicit intents는 이름 (완전히 증명된 클래스 이름)으로 시작하는 component를 명시한다. 일반적으로 앱에서 explicit intent로 component를 시작한다, 시작 하고 싶은 Activity 또는 Service의 클래스 이름을 알기 때문이다. 예로, 사용자의 행동에 응답하는 새로운 Activity를 시작 하거나 백그라운드에서 파일을 다운받는 Service를 시작하는게 있다.

 - Implicit intents는 component의 이름을 명시하것이 아니라, 다른 app의 component가 기본적인 기능을 수행 할 수 있도록 허용하는 것이다. 예로, 만약 사용자의 위치를 지도에 표시 해 주고 싶다면 implicit intent로 지도에 구체적인 위치를 보여줄 수 있는 다른 app에 요청 하는 것이다.

Activity 또는 Service를 explicit intent로 생성 할 때, 시스템은 즉시 intent 객체에 명시 된 app component를 시작 한다.

implicit intent를 생성 할 때, 안드로이드 시스템은 기기의 다른 앱의 manifest 파일에 선언된 intent filter와 intent의 내용을 비교하여 적절한 component를 찾는다. 만약 그 intent가 intent filter와 일치 한다면 component를 실행하고 intent를 전달 해 준다. 만약 여러 intent filter와 호환이 된다면, 시스템은 사용자가 고를 수 있도록 실행 가능 한 목록을 보여준다.

intent filter는 app의 manifest 파일에 component가 받을 수 있는 intent 종류를 명시한 식(expression)이다. 나아가서 하나의 Activity에 intent filter를 선언 하면, 다른 app에서 intent filter에 명시한 종류의 intent로 intent filter가 선언된 Activity를 직접 실행 시키도록 만들 수 있다.  비슷하게 Activity에 아무런 intent filter를 선언하지 않으면 이 Activity는 explicit intent로만 실행 할 수 있다.



* 주의 : App의 보안을 보장하려면 항상 Activity 또는 Service를 시작하려면 explicit intent를 사용하고 Service에 intent filter를 선언하지 마라. implicit intent로 Service를 시작하는 것은 보안의 위험 요소이다. Service가 intent에 응답 할 것을 확신하지 못하고, 사용자는 Service가 실행되는것을 보지 못하기 때문이다.







2013년 6월 13일 목요일

[Android] Dynamic Search ListView

< EditText과 Filter를 이용한 Search >

EditText의 addTextChangedListener를 통해서 EditText에 입력되는 값을 실시간으로 처리해줄수 있게 된다.

1:  et_search_word.addTextChangedListener(new TextWatcher() {  
2:        @Override  
3:        public void onTextChanged(CharSequence s, int start, int before, int count) {  
4:             _listAdapter.getFilter().filter(s);  
5:        }  
6:        @Override  
7:        public void beforeTextChanged(CharSequence s, int start, int count, int after) {  
8:             // TODO Auto-generated method stub  
9:        }  
10:        @Override  
11:        public void afterTextChanged(Editable s) {  
12:             // TODO Auto-generated method stub  
13:        }  
14:  });  

onTextChanged를 통해서 입력되는 값에 대해서 실시간으로 처리해준다.

ListView를 구성하는 Adapter에 implements Filterable 를 통해서 Filtering을 할 수 있게 된다.

Adapter 내에
1:  @Override  
2:  public Filter getFilter() {  
3:     if (valueFilter == null) {  
4:          valueFilter = new ValueFilter();  
5:     }  
6:     return valueFilter;  
7:  }  

구현해주고
Filter에 해당하는 class를 구현해서 적용하면 끝.

1:  class ValueFilter extends Filter {  
2:    @Override  
3:    protected FilterResults performFiltering (CharSequence constraint) {  
4:         FilterResults results = new FilterResults();  
5:         if(constraint != null && constraint.length() > 0) {  
6:              List<ItemContainer> filterList = new ArrayList<ChatFriendFragment.ItemContainer>();  
7:         for (RosterContact contact : _contacts) {  
8:              if (contact.getName().contains(constraint) || contact.getPhoneNumber().contains(constraint)) {  
9:                   ItemContainer item = new ItemContainer();  
10:                   item.Type = ItemContainer.TYPE_ITEM;  
11:                   item.Item = contact;  
12:                   filterList.add(item);  
13:              }  
14:         }  
15:         results.count = filterList.size();  
16:         results.values = filterList;  
17:         } else {  
18:              setupListItems();  
19:              results.count = _itemList.size();  
20:              results.values = _itemList;  
21:         }  
22:         return results;  
23:    }  
24:    @Override  
25:    protected void publishResults(CharSequence constraint, FilterResults results) {  
26:         _itemList = (List<ItemContainer>) results.values;  
27:         _listAdapter.notifyDataSetChanged();  
28:    }  
29:  }  

2013년 6월 6일 목요일

[Eclipse][Android][Windows] 스마트폰 인식을 못 할때

eclipse로 작업중 apk를 install 하려고 하니까
계속 loading 만 하고 아무 작업도 하지 않는듯 하여

혹시나 폰으로 apk 파일 자체를 옮기지 못하는가 싶어
스마트폰으로 아무 파일이나 복사 붙여넣기를 해봤지만.

역시나!! 안됨.

그래서 찾고 찾고 또 찾아봤지만 답을 알 수 없던 그때.

컴퓨터 본체에 있는 USB 포트 중에 마더보드 쪽 USB 포트를 사용하면 어떨가 싶어서
마더보드쪽 USB 포트를 사용 했더니

매끄럽게 진행이 된다.

<< 해결 방법 >>

스마트폰 인식을 못 할 경우 USB 포트를 어떤것을 사용하고 있는것인가 보고
마더보드쪽 USB 포트를 사용하고 있지 않다면

마더보드쪽 USB 포트를 사용하면 해결됨.

 ** 왜 그런지 아직 이유는 모르겠음.