Android/App개발2010. 11. 29. 17:49

Package의 Add와 Remove시를 알고 싶다면 아래와 같이 한다.

1. Manifest에 receiver등록

<receiver android:name=".IntentReceiver">

<intent-filter>

<action android:name="android.intent.action.PACKAGE_ADDED" />

<action android:name="android.intent.action.PACKAGE_REMOVED" />

<data android:scheme="package" />

</intent-filter>

</receiver>


2. Receiver class구현


public class IntentReceiver extends BroadcastReceiver {


@Override

public void onReceive(Context context, Intent intent) {

Log.d("_PACKAGE_OBSERVER_", "intent : ");

Log.d("_PACKAGE_OBSERVER_", "  action = " + intent.getAction());

Log.d("_PACKAGE_OBSERVER_", "  data = " + intent.getData());

}


}


위와 같이 하면 data에 package명을 확인하여 어떤 패키지가 추가되거나 삭제되었는지 알 수 있다.




Posted by 삼스
Android/App개발2010. 11. 15. 17:40

하마터면 삽질할 뻔 했는데.. HashMap은 Parcelable을 implement하려고 하면 런타임에 에러가 남.
이에 대한 대안은 그냥  Bundle을 사용하면 되는데 Bundle은 내부에 hashmap을 데이터구조로 사용중임.

따라서 hashmap형태의 데이터를 다른 프로세스와 공유하고자 할 때는 Bundle을 사용할것~!

Posted by 삼스
Android2010. 11. 3. 09:52


kandroid와 여기저기서 주워들은 이야기를 모아봄.

Native Activity와 Native event dispatching

 - 이벤트처리 단계를 축소하여 반응속도를 획기적으로높였다고 한다. 진정으로 아이폰을 능가하는 반응속도를 볼 수 있을듯하다.

OpenSL ES - The Standard for Enhanced Audio

http://www.khronos.org/opensles/
 
OpenAL (Open Audio Library)
http://en.wikipedia.org/wiki/OpenAL

 - native에서 오디오를 조작할수 있다고 한다.
 
SIP (Session Initiation Protocol)
http://en.wikipedia.org/wiki/Session_Initiation_Protocol
- 구글의 전략적인 선택 


stagefright supports
- RTSP, 
WebM, VP8 (http://dreamgoer.net/175)

- PacketVideo의 OpenCore를 버리는 단계이다. PacketVideo는 높은 라이선스료를 요구한것으로 알려져 있다.



Posted by 삼스
Android/XMPP2010. 10. 28. 21:11


http://blog.jayway.com/2008/11/21/give-back-my-xmpp-in-android/

SASL 관련 XMPPConnection클래스의 버그를 수정한 패치가 올려져 있다.

아래와 같은 에러 발생시 이 패치가 유용할 것이다.

10-28 19:40:09.640: ERROR/AndroidRuntime(2342): java.lang.VerifyError: org.jivesoftware.smack.sasl.SASLMechanism
10-28 19:40:09.640: ERROR/AndroidRuntime(2342):     at java.lang.Class.getDeclaredConstructors(Native Method)
10-28 19:40:09.640: ERROR/AndroidRuntime(2342):     at java.lang.Class.getConstructor(Class.java:477)
10-28 19:40:09.640: ERROR/AndroidRuntime(2342):     at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:303)

10-28 19:40:09.640: ERROR/AndroidRuntime(2342):     at
org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:395)
10-28 19:40:09.640: ERROR/AndroidRuntime(2342):     at
org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:349)
10-28 19:40:09.640: ERROR/AndroidRuntime(2342):     at com.yamaia.mobilebridge.delivery.PushService$LoginThread.run(PushService.java:404)
10-28 19:40:09.640: ERROR/AndroidRuntime(2342):     at java.lang.Thread.run(Thread.java:1102)



Posted by 삼스
Android/XMPP2010. 10. 28. 19:47


http://davanum.wordpress.com/2007/12/31/android-just-use-smack-api-for-xmpp/


Android – Just Use Smack API For XMPP

Filed under: Uncategorized — Davanum Srinivas @ 9:36 am

OUTDATED SAMPLE – Updated code is here:


http://davanum.wordpress.com/2008/12/29/updated-xmpp-client-for-android/

Using Smack XMPP API From Android

Once you get tired of the limitations of android’s built-in IMProvider and the corresponding API – IXmppSession and IXmppService, try the sample below. Inside the source/binary zip (bottom of this article) you will find a smack.jar that works with android. To build the jar yourself, You can download the Smack 3.0.4 sources from here and apply the patch here.

Here Is A Screen Shot Of The XMPP Settings Dialog.

1

Notes



  • For GTalk, use “gtalk.google.com” as host with port 5222. The service name is “gmail.com”

  • Don’t add “@gmail.com” in the user name, just the id will do

Here’s The Code For The Settings Dialog

01 package org.apache.android.xmpp;
02  
03 import android.app.Dialog;
04 import android.util.Log;
05 import android.view.View;
06 import android.widget.Button;
07 import android.widget.EditText;
08 import org.jivesoftware.smack.ConnectionConfiguration;
09 import org.jivesoftware.smack.XMPPConnection;
10 import org.jivesoftware.smack.XMPPException;
11 import org.jivesoftware.smack.packet.Presence;
12  
13 /**
14  * Gather the xmpp settings and create an XMPPConnection
15  */
16 public class SettingsDialog extends Dialog implements android.view.View.OnClickListener {
17     private XMPPClient xmppClient;
18  
19     public SettingsDialog(XMPPClient xmppClient) {
20         super(xmppClient);
21         this.xmppClient = xmppClient;
22     }
23  
24     protected void onStart() {
25         super.onStart();
26         setContentView(R.layout.settings);
27         getWindow().setFlags(44);
28         setTitle("XMPP Settings");
29         Button ok = (Button) findViewById(R.id.ok);
30         ok.setOnClickListener(this);
31     }
32  
33     public void onClick(View v) {
34         String host = getText(R.id.host);
35         String port = getText(R.id.port);
36         String service = getText(R.id.service);
37         String username = getText(R.id.userid);
38         String password = getText(R.id.password);
39  
40         // Create a connection
41         ConnectionConfiguration connConfig =
42                 new ConnectionConfiguration(host, Integer.parseInt(port), service);
43         XMPPConnection connection = new XMPPConnection(connConfig);
44  
45         try {
46             connection.connect();
47             Log.i("XMPPClient""[SettingsDialog] Connected to " + connection.getHost());
48         catch (XMPPException ex) {
49             Log.e("XMPPClient""[SettingsDialog] Failed to connect to " + connection.getHost());
50             xmppClient.setConnection(null);
51         }
52         try {
53             connection.login(username, password);
54             Log.i("XMPPClient""Logged in as " + connection.getUser());
55  
56             // Set the status to available
57             Presence presence = new Presence(Presence.Type.available);
58             connection.sendPacket(presence);
59             xmppClient.setConnection(connection);
60         catch (XMPPException ex) {
61             Log.e("XMPPClient""[SettingsDialog] Failed to log in as " + username);
62             xmppClient.setConnection(null);
63         }
64         dismiss();
65     }
66  
67     private String getText(int id) {
68         EditText widget = (EditText) this.findViewById(id);
69         return widget.getText().toString();
70     }
71 }

Here Is A Screen Shot Of The Main Window.

1

Notes



  • In the Recipient field, make sure you add the “@gmail.com”, not just the user id

Here’s The Code For The Main Activity

001 package org.apache.android.xmpp;
002  
003 import android.app.Activity;
004 import android.os.Bundle;
005 import android.os.Handler;
006 import android.util.Log;
007 import android.view.View;
008 import android.widget.ArrayAdapter;
009 import android.widget.Button;
010 import android.widget.EditText;
011 import android.widget.ListView;
012 import org.jivesoftware.smack.PacketListener;
013 import org.jivesoftware.smack.XMPPConnection;
014 import org.jivesoftware.smack.filter.MessageTypeFilter;
015 import org.jivesoftware.smack.filter.PacketFilter;
016 import org.jivesoftware.smack.packet.Message;
017 import org.jivesoftware.smack.packet.Packet;
018 import org.jivesoftware.smack.util.StringUtils;
019  
020 import java.util.ArrayList;
021  
022 public class XMPPClient extends Activity {
023  
024     private ArrayList<String> messages = new ArrayList();
025     private Handler mHandler = new Handler();
026     private SettingsDialog mDialog;
027     private EditText mRecipient;
028     private EditText mSendText;
029     private ListView mList;
030     private XMPPConnection connection;
031  
032     /**
033      * Called with the activity is first created.
034      */
035     @Override
036     public void onCreate(Bundle icicle) {
037         super.onCreate(icicle);
038         setContentView(R.layout.main);
039  
040         mRecipient = (EditText) this.findViewById(R.id.recipient);
041         mSendText = (EditText) this.findViewById(R.id.sendText);
042         mList = (ListView) this.findViewById(R.id.listMessages);
043         setListAdapter();
044  
045         // Dialog for getting the xmpp settings
046         mDialog = new SettingsDialog(this);
047  
048         // Set a listener to show the settings dialog
049         Button setup = (Button) this.findViewById(R.id.setup);
050         setup.setOnClickListener(new View.OnClickListener() {
051             public void onClick(View view) {
052                 mHandler.post(new Runnable() {
053                     public void run() {
054                         mDialog.show();
055                     }
056                 });
057             }
058         });
059  
060         // Set a listener to send a chat text message
061         Button send = (Button) this.findViewById(R.id.send);
062         send.setOnClickListener(new View.OnClickListener() {
063             public void onClick(View view) {
064                 String to = mRecipient.getText().toString();
065                 String text = mSendText.getText().toString();
066  
067                 Log.i("XMPPClient""Sending text [" + text + "] to [" + to + "]");
068                 Message msg = new Message(to, Message.Type.chat);
069                 msg.setBody(text);
070                 connection.sendPacket(msg);
071                 messages.add(connection.getUser() + ":");
072                 messages.add(text);
073                 setListAdapter();
074             }
075         });
076     }
077  
078     /**
079      * Called by Settings dialog when a connection is establised with the XMPP server
080      *
081      * @param connection
082      */
083     public void setConnection
084             (XMPPConnection
085                     connection) {
086         this.connection = connection;
087         if (connection != null) {
088             // Add a packet listener to get messages sent to us
089             PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
090             connection.addPacketListener(new PacketListener() {
091                 public void processPacket(Packet packet) {
092                     Message message = (Message) packet;
093                     if (message.getBody() != null) {
094                         String fromName = StringUtils.parseBareAddress(message.getFrom());
095                         Log.i("XMPPClient""Got text [" + message.getBody() + "] from [" + fromName + "]");
096                         messages.add(fromName + ":");
097                         messages.add(message.getBody());
098                         // Add the incoming message to the list view
099                         mHandler.post(new Runnable() {
100                             public void run() {
101                                 setListAdapter();
102                             }
103                         });
104                     }
105                 }
106             }, filter);
107         }
108     }
109  
110     private void setListAdapter
111             () {
112         ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
113                 R.layout.multi_line_list_item,
114                 messages);
115         mList.setAdapter(adapter);
116     }
117 }

Download Source And APK From Here – XMPPClient.Zip


Posted by 삼스
Android/App개발2010. 10. 28. 14:18

코드 난독화툴을 안드로이드 프로젝트에 적용하는 포스트를 이미 올린바 있습니다.
이번에는 프로젝트에서 일부 클래스들만 묶어서 배포하고자 하는 경우 jar파일로 만드는 경우가 있을 것인데 이 경우 jar file하나만 proguard를 적용하는 방법에 대해 설명하겠습니다.

프로가드 gui툴을 이용하면 편하게 진행이 가능합니다.
프로가드 사용시 중요한 것이 옵션을 어떻게 지정할 것인가에 대한 것인데.. 그 중에도 -keep옵션이 아주 중요하다 할 것입니다.
안드로이드 소스코드 난독화를 위해서 레퍼런스로 사용할 만한 옵션을 아래 나열해 보았습니다.

# 각종 옵션들 : 설명은 생략~~ proguard site의 설명을 참조하시길...

-dontskipnonpubliclibraryclassmembers

-optimizationpasses 5

-dontusemixedcaseclassnames

-dontpreverify

-verbose


# keep option들.. 

# keep옵션이란 난독화시 난독화를 하지 않아야 하는 코드들을 미리 지정하는 것으로 

# 안드로이드 jar파일이나 프로젝트의 경우 아래의 keep옵션들이 필요할 것입니다.

-keep public class * extends android.app.Activity

-keep public class * extends android.app.Application

-keep public class * extends android.app.Service

-keep public class * extends android.content.BroadcastReceiver

-keep public class * extends android.content.ContentProvider

-keep public class com.android.vending.licensing.ILicensingService

-keepclasseswithmembers,allowshrinking class * {

    public <init>(android.content.Context,android.util.AttributeSet);

}

-keepclasseswithmembers,allowshrinking class * {

    public <init>(android.content.Context,android.util.AttributeSet,int);

}

# Also keep - Enumerations. Keep the special static methods that are required in

# enumeration classes.

-keepclassmembers enum  * {

    public static **[] values();

    public static ** valueOf(java.lang.String);

}

# Keep names - Native method names. Keep all native class/method names.

-keepclasseswithmembers,allowshrinking class * {

    native <methods>;

}


위 옵션들과 함께 입력파일과 출력파일을 지정하고 참조하고 있는 라이브러리까지 지정하는 스크립트 코드는 아래와 같습니다.


# 난독화를 진행할 입력 파일명

-injars myjar.jar

# 난독화를 거친 출력 파일명

-outjars out_myjar.jar


# 입력파일이 참조하는 라이브러리들...

# 안드로이드용 jar라면 android.jar를 반드시 포함해야 할것이다.

# 그 외에 혹시 추가로 참조하는 라이브러리가 있다면 추가해 주어야 한다.

-libraryjars /Users/yosamlee/Desktop/android-sdk-mac_x86/platforms/android-7/android.jar

-libraryjars /Users/yosamlee/_TOOL/workspace/MyJar/lib/referencelib.jar



위의 스크립트를 모두 모아서 확장자 *.pro로 저장한다.


proguard설치 폴더로 가서 bin폴더의 proguardgui를 실행한다. 아래와 같은 커맨드라인 명령을 콘솔에서 입력하면 됩니다.


java -jar ../lib/proguardgui.jar




위 화면에서 "Load configuration ..."을 선택 후 앞서 저장해 둔 스크립트파일을 오픈합니다


스크립트 파일이 성공적으로 열렸다면 Process tab에서 "Process!"버튼을 선택하면 난독화 과정을 거칩니다.


...

  Number of branch peephole optimizations:     0

  Number of simplified instructions:           0

  Number of removed instructions:              0

  Number of removed local variables:           0

  Number of removed exception blocks:          0

  Number of optimized local variable frames:   0

Shrinking...

Removing unused program classes and class elements...

  Original number of program classes: 26

  Final number of program classes:    26

Obfuscating...

Writing output...

Preparing output jar [/Users/yosamlee/_TOOL/workspace/MyJar/bin/out_myjar.jar]

  Copying resources from program jar [/Users/yosamlee/_TOOL/workspace/MyJar/bin/myjar.jar]

Processing completed successfully


정상적으로 과정이 진행되었다면 위와 같은 성공하였다는 메세지를 보게 될것입니다.


이제 out_myjar.jar파일을 리버스엔지니어링 해보길 바랍니다.

원하는 만큼 난독화가 진행되었는지 말이죠~!

만족할 만한 결과가 나왔기를 바랍니다.


ps) 이미 느끼신 분들도 계시겠지만 위 과정은 proguardgui버전에서 그대로 수행이 가능합니다. 저는 왜 수동으로 스크립트를 만들었냐면요.... 옵션들이 하도 많아서 헤깔려서요. GUI버전이 편하신 분들은 그걸 사용하셔도 됩니다.







Posted by 삼스
Android/App개발2010. 10. 20. 11:20

상용이던 개인용이던 안드로이드는 자바코드를 사용하기 때문에 dex tool과 jad tool등을 이용하면 decompile을 통한 reverse engineering이 가능하다.
이를 해결하기 위해 코드난독화툴을 이용하여 reverse를 어렵게 하는 방법을 사용하게 된다. proguard는 코딩을 어떻게 하느냐에 따라 난독이 아니라 불독(?)하게도 가능하다. 즉 전혀 해독이 불가하게 할수도 있다는 것이다.

proguard툴은 stand-alone형태로 사용해도 되나 android project에 포함시켜서 구동시키면 좀더 쉽게 사용이 가능해진다. 
이 포스트는 그 방법에 대해 설명한다.

요구사항
1. Android SDK version 7이상을 사용해야 함
  -> ANT 빌드규칙에 컴파일이전과 이후단계에서 일정한 작업을 추가할 수 있는 구조를 지원한다.
2. Proguard 설치

절차
커맨드라인에서 수행함.
1. 특정프로젝트에 대한 build.xml을 만듦
    android update project --path ./MyAndroidProject
  build.xml파일이 생성됨. 실제 빌드를 아래와 같이 수행.
    ant release
  빌드가 되고 서명되지 않은 앱이 생성됨. 이 후 서명툴을 이용하여 서명된 앱을 만들수 있슴.
2. 서명된 앱 빌드하기
  ant release명령으로 빌드하면 빌드과정에서 생성된 local.properties파일을 수정
    key.store=/Path/to/my/keystore/MyKeystore.ks
    key.alias=myalias
  ant release
3. 코드 난독화과정 
  add-proguard-release.xml, procfg.txt파일을 build.xml파일 위치에 복사
  local.properties에 proguard설치 경로 지정
    proguard.dir=/Directory/Proguard/proguard4.5.1/lib
  build.xml에(최상단에위치) 아래 내용 추가
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE project [
      <!ENTITY add-proguard-release SYSTEM "add-proguard-release.xml">
    ]>
  build.xml의 project tag안에 위에서 선언한 XML entity를 포함시킴
    <project name="MyProjectName" default="help">
    &add-proguard-release;
  위의 모든과정이 완료되었으면 빌드
    ant release

**  주의 사항  **
난독화 도구를 사용하는 경우 빌드후 앱이 정상적으로 동작하지 않을 수있다. 이는 난독화를 하지 않아야 하는 부분들까지도 난독화가 이루어져서 코드가 동작하지 못하는 경우가 발생하는 경우이다. 예를 들어 AndroidManifest나 class name, jni or reflection등을 통해 실제 메소드의 이름을 참조하고 있는 메소드들까지도 난독화를 통해서 작업이 이루어질 수 있다.
첨부된 procfg.txt에는 이런 룰을 지정할수가 있습니다. 이는 proguard 인자들중 keep인자 파라메터를 지정하는 방법에 따름인데 아래와 같은 명령을 추가하면 클래스이름을 찾지 못하는 문제는 방지 가능하다.

-keep public class * [my classname]

** 빌드중 obj directory가 생성되는데 여기에는 디버깅을 위한 다양한 출력파일들이 저장된다. 디버깅시 이용가능한다.
** mapping.txt 은 클래스가 어떤식으로 난독화 되었는지 기록한다.
** mac에서만 발생하는지 확인되지 않았으나 위 과정 진행중.. 아래와 같은 에러메세지가 나올수 있다.
add-proguard-release.xml:31: Expecting class path separator ':' before ';' in argument number 1
  이 경우 add-proguard-release.xml파일의 line35을 아래와 같이 수정하면 된다.
-libraryjars ${external.libs.dir};${libraryjarpath} -> -libraryjars ${external.libs.dir}:${libraryjarpath}


Posted by 삼스
Android/App개발2010. 10. 14. 18:20

안드로이드는 사정에 따라 서비스를 죽이기도 하며 나중에 다시 살리기도 한다.
만일 항상 떠있는 서비스를 구현하고자 하는 경우에는 이런 일이 발생하는것에 대해 아주 당황할것이다.
이럴경우 서비스를 죽지 않도록 하고자 할것인데.
이런 경우 알람서비스를 이용하여 서비스가 죽으면 다시 살리는 방법이 있다.
많은 경우 이런 방식을 이용하는것으로 보인다.

PersistentService가 죽지 않아야 할 서비스이다. 아래 예제에서 보면 onCreate시 기존 알람이 있으면 제거하고 onDestroy시 알람을 기동한다. 
알람은 일정시간이 지나면 PendingIntent를 날리는 알람이며 이 인텐트를 받을 수 있는 BroadcastReceiver가 있게 된다. 여기서는 RestartService receiver가 해당 인텐트를 받아서 이 때 종료된 PersistentService를 재기동 시키는 역할을 한다.

PersistentService.java
class PersistentService extends Service {

  onCreate(..) {
    unregisterRestartAlram(); //이미 등록된 알람이 있으면 제거
  }

  onDestroy(..) {
    registerRestartAlram(); // 서비스가 죽을때 알람을 등록
  }
 
  // support persistent of Service 
  void registerRestartAlarm() {
    Log.d(TAG"registerRestartAlarm");
    Intent intent = new Intent(PersistentService.this, RestartService.class);
    intent.setAction(RestartService. ACTION_RESTART_PERSISTENTSERVICE);
    PendingIntent sender = PendingIntent.getBroadcast(PersistentService.this, 0, intent, 0);
    long firstTime = SystemClock.elapsedRealtime();
    firstTime += 10*1000; // 10초 후에 알람이벤트 발생
    AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
    am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, 10*1000, sender);
  }

  void unregisterRestartAlarm() {
    Log.d(TAG"unregisterRestartAlarm");
    Intent intent = new Intent(PersistentService.this, RestartService.class);
    intent.setAction(RestartService.ACTION_RESTART_PERSISTENTSERVICE);
    PendingIntent sender = PendingIntent.getBroadcast(PersistentService.this, 0, intent, 0);
    AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
    am.cancel(sender);
  }
}

RestartService.java
public class RestartService extends BroadcastReceiver {
  public static final String ACTION_RESTART_PERSISTENTSERVICE = "ACTION.Restart. PersistentService";

@Override
  public void onReceive(Context context, Intent intent) {
    Log.d("RestartService""RestartService called!@!@@@@@#$@$@#$@#$@#");
    if(intent.getAction().equals(ACTION_RESTART_PERSISTENTSERVICE)) {
      Intent i = new Intent(ctx, PushService.class);
      context.startService(i);
  }
}

manifest.xml
<application android:icon="@drawable/icon" android:label="@string/app_name">
<receiver android:name="RestartService" android:process=":remote"/>
Posted by 삼스
Android/XMPP2010. 10. 6. 17:17
smack project site -> http://www.igniterealtime.org/projects/smack/index.jsp
javadoc -> http://www.igniterealtime.org/builds/smack/docs/latest/javadoc/
android project talkmyphone -> http://code.google.com/p/talkmyphone/
Posted by 삼스
Android/XMPP2010. 10. 6. 16:55
http://www.igniterealtime.org/builds/smack/docs/latest/documentation/processing.html
Processing Incoming Packets 

수신되는 패킷을 처리하는데 두가지 방식을 지원한다.

  • org.jivesoftware.smack.PacketCollector -- 새로운 패킷이 올때까지 동기적으로 대기하는 클래스
  • org.jivesoftware.smack.PacketListener -- 수신되는 패킷을 비동기적으로 받는 인터페이스
패킷리스너는 이벤트스타일의 프로그래밍이다. 반면에 패킷콜렉터는 당신이 폴링으로 수집한 데이터를 큐잉하여 받게되며 그 동작은 블럭된다. 패킷리스너는 수신중에 언제든지 다른 작업이 가능하며 콜렉터는 원하는 패킷이 올때가지 대기할때 유용하다. 이 두가지는 모두 XMPPConnection의 인스턴스로부터 얻을수 있다.

org.jivesoftware.smack.filter.PacketFilter인터페이스는 패킷리스너와 패킷콜렉터가 전달받을킷을러주는 역할을 한다. org.jivesoftware.smack.filter패키지에 미리정의된 많은 사용가능한 필터들이 정의되어 있다.

아래 코드는 패킷리스너와 패킷콜렉터를 모두 사용하는 데모이다.

 // Create a packet filter to listen for new messages from a particular
// user. We use an AndFilter to combine two other filters.
PacketFilter filter = new AndFilter(new PacketTypeFilter(Message.class), 
        new FromContainsFilter("mary@jivesoftware.com"));
// Assume we've created an XMPPConnection name "connection".

// First, register a packet collector using the filter we created.
PacketCollector myCollector = connection.createPacketCollector(filter);
// Normally, you'd do something with the collector, like wait for new packets.

// Next, create a packet listener. We use an anonymous inner class for brevity.
PacketListener myListener = new PacketListener() {
        public void processPacket(Packet packet) {
            // Do something with the incoming packet here.
        }
    };
// Register the listener.
connection.addPacketListener(myListener, filter);



Standard Packet Filters

아래는 Smack에서 제공하는 패킷필터들의 셋이다. PacketFilter인터페이스로 새로운 필터를 정의할수도 있다. 디폴트셋은 아래와 같다.
  • PacketTypeFilter -- 클래스타입을 지정할 수 있다. 
  • PacketIDFilter -- 패킷 ID별로 지정할 수 있다.
  • ThreadFilter -- 메세지패킷의 스레드 ID별로 지정할 수 있다.
  • ToContainsFilter -- 받는 주소로 지정할 수 있다.
  • FromContainsFilter -- 보내는 주소로 지정할 수 있다.
  • PacketExtensionFilter -- 패킷의 확장부분을 지정할 수 있다.
  • AndFilter -- 논리적 AND 연산을 두개이상의 필터로 지정할 수 있도록 해준다.
  • OrFilter -- 논리적 OR 연산을 두개이상의 필터로 지정할 수 있도록 해준다.
  • NotFilter -- 논리적 NOT 연산을 두개이상의 필터로 지정할 수 있도록 해준다.

Posted by 삼스