就最近的形势来看,似乎是不差的?变革即意味?机遇,确实?此?我觉得我似乎在朝着?的?划慢慢靠近?我想很?会有?的答案吧。我静静地等??/p>
?近两天一直在研究Android 信息推?的事情。?习了AndroidPN这个框架,虽然最后不会用这个,项?????但终究有值得借鉴的地方,特?把?习的内?总结在这里??/p>
AndroidPN(Android Push Notification)?国人思密达共???单的框架,基于XMPP协?,实现了信息推?服务??/p>
?:安装测试运?/strong>
1,下载?户?和服务器?序??a href="http://sourceforge.net/projects/androidpn/files/" style="font-size: 12px; font-family: Arial; line-height: 26px; color: #336699;">http://sourceforge.net/projects/androidpn/files/ 程序10?1月上传后就没有再更改过,?已经?分享者放弃了思密达??/p>
2,打?客户?序下的raw/androidpn.properties文件,配??户?信息,将xmppHost配置?0.0.2.2,xmppPort=5222?222 ?务器的xmpp服务监听??/p>
3,运行androidpn-server-0.5.0\bin\run.bat?服务?从浏览器访问http://127.0.0.1:7070/
在模拟器?行?户??/p>
4,从Web?客户?消息?/p>
效果如下?/p>
友情提示?/p>
1,?果出现运行run.bat???过,无法?问http://127.0.0.1:7070/的情况,请配?Java??变量?/p>
2,?户?运?后后提示“Application unfortunately Stopped”,有可能是引用的asmack.jar包的??,重新引?然后Clean,重新Build Project。?大?好运?/p>
二:源代码??/strong>
在项?我是写?户?的,?以我主?学习了?户?的源码?现总结如下?br>
1,程序入?emoAppActivity??务:
// Start the serviceServiceManager serviceManager = new ServiceManager(this);serviceManager.setNotificationIcon(R.drawable.notification);//设置消息的图?serviceManager.startService();
在实例化ServiceManage的过程中,做了以下工作,加载 res/raw/androidpn.properties 配置文件?参数信息,并将其保存在SharedPreferences??然后调用startService()??务??/p>
public void startService() { Thread serviceThread = new Thread(new Runnable() { @Override public void run() { Intent intent = NotificationService.getIntent(); context.startService(intent); } }); serviceThread.start();}
startService()方法????线程去启动真正的信息推?服?/span>NotificationService。?于Service,作者?密达在OnCreate()的时候做了很多工作,OnCreate()方法在服务?创建时调?且只会?调用?次?因此?次的start()并不会产生??例?在OnCreate()方法?作?获取了??重?的参?/span>deviceId设?ID。可?面并没有使用它??/p> 获得设?ID后, 实例化XmappManager,并且调用taskSubmitter,在taskSubmitter方法里实例化NotificationService类,并且调用其start()方法?span style="font-size: 14px; line-height: 1.5;">实例化NotificationService类时会做以下工作?/span> 实例化notificationReceiver,NotificationReceiver继承了BroadcastReceiver类?BroadcastReceiver (广?收?)用于接收广播 Intent 。ConnectivityReceiver同样继承?span style="font-size: 14px; line-height: 1.5;">BroadcastReceiver类?PhoneStateChangeListener继承了PhoneStateListener,用于监?机状态变化?Executors.newSingleThreadExecutor()返回??程池(这?程池???程),这个线程池可以在线程死后(或发生异常时)重新???程来替代原来的线程继?行下去??/span> NotificationService.start()方法 registerNotificationReceiver()方法注册?span style="line-height: 1.5;">notificationReceiver来接收广?registerConnectivityReceiver()方法注册了connectivityReceiver来监?络连接状况?然后调用xmappManager的connect方法?/span> 继续跟踪xmappManager的connect方法又执行了?工作 调用了submitLoginTask()方法,顾名?义,提交登录任务??/span> 提交登录任务?又提交了??册任务,同时将新建的登录任务添加到任务集合中并交?TaskTracker 来?添加的任务进行监视?继??登录任务?行的工作?/span> ?)?果连接没有经过身份验证,根据username和password执?登录操作,然后为连接添加各?监听机制。执行刚刚添加的任务runTask()?)?果连接?过?验证,直接执行任?unTask(); 具体的监?接下来的操作会在下篇进?分析?/p>telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);// Get deviceIddeviceId = telephonyManager.getDeviceId();
xmppManager = new XmppManager(this);taskSubmitter.submit(new Runnable() {public void run() { NotificationService.this.start(); }});
public NotificationService() { notificationReceiver = new NotificationReceiver(); connectivityReceiver = new ConnectivityReceiver(this); phoneStateListener = new PhoneStateChangeListener(this); executorService = Executors.newSingleThreadExecutor(); taskSubmitter = new TaskSubmitter(this); taskTracker = new TaskTracker(this);}
private void start() { Log.d(LOGTAG, "start()..."); registerNotificationReceiver(); registerConnectivityReceiver(); // Intent intent = getIntent(); // startService(intent); xmppManager.connect();}
public void connect() { Log.d(LOGTAG, "connect()..."); submitLoginTask();}
private void submitLoginTask() { Log.d(LOGTAG, "submitLoginTask()..."); submitRegisterTask(); addTask(new LoginTask());}
private LoginTask() { this.xmppManager = XmppManager.this; } public void run() { Log.i(LOGTAG, "LoginTask.run()..."); if (!xmppManager.isAuthenticated()) { Log.d(LOGTAG, "username=" + username); Log.d(LOGTAG, "password=" + password); try { xmppManager.getConnection().login( xmppManager.getUsername(), xmppManager.getPassword(), XMPP_RESOURCE_NAME); Log.d(LOGTAG, "Loggedn in successfully"); // connection listener if (xmppManager.getConnectionListener() != null) { xmppManager.getConnection().addConnectionListener( xmppManager.getConnectionListener()); } // packet filter PacketFilter packetFilter = new PacketTypeFilter( NotificationIQ.class); // packet listener PacketListener packetListener = xmppManager .getNotificationPacketListener(); connection.addPacketListener(packetListener, packetFilter); xmppManager.runTask(); } catch (XMPPException e) { Log.e(LOGTAG, "LoginTask.run()... xmpp error"); Log.e(LOGTAG, "Failed to login to xmpp server. Caused by: " + e.getMessage()); String INVALID_CREDENTIALS_ERROR_CODE = "401"; String errorMessage = e.getMessage(); if (errorMessage != null && errorMessage .contains(INVALID_CREDENTIALS_ERROR_CODE)) { xmppManager.reregisterAccount(); return; } xmppManager.startReconnectionThread(); } catch (Exception e) { Log.e(LOGTAG, "LoginTask.run()... other error"); Log.e(LOGTAG, "Failed to login to xmpp server. Caused by: " + e.getMessage()); xmppManager.startReconnectionThread(); } } else { Log.i(LOGTAG, "Logged in already"); xmppManager.runTask(); } } }