androidpn客户端深析

step1:配置客户端
位于工程 ->res->raw->androidpn.properties文件
apiKey=1234567890  #key
xmppHost=192.168.1.1 #ip
xmppPort=5222 #端口

step2:

//创建新的服务
ServiceManager serviceManager = new ServiceManager(this);
//设置通知栏图标
serviceManager.setNotificationIcon(R.drawable.notification);
//启动服务
serviceManager.startService();

详细分析

初始化ServiceManager:

this.context = context;

//这里获取调用者activity得包名类名
if (context instanceof Activity) {
    Log.i(LOGTAG, "Callback Activity...");
    Activity callbackActivity = (Activity) context;
    callbackActivityPackageName = callbackActivity.getPackageName();
    callbackActivityClassName = callbackActivity.getClass().getName();
}

//loadProperties()读取raw中androidpn.properties文件的内容,并返回Properties对象

props = loadProperties();
apiKey = props.getProperty("apiKey", "");
xmppHost = props.getProperty("xmppHost", "127.0.0.1");
xmppPort = props.getProperty("xmppPort", "5222");

//将上面获取的Properties存入SharedPreferences方便以后直接调用
sharedPrefs = context.getSharedPreferences(
        Constants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE);
Editor editor = sharedPrefs.edit();
...
...
...
editor.commit();

启动服务startService()

//用一个线程开启服务
Thread serviceThread = new Thread(new Runnable() {
    @Override
    public void run() {
        Intent intent = NotificationService.getIntent();
        context.startService(intent);
    }
});
serviceThread.start();

NotificationService类分析,它是Service的子类,着重分析一下这个Service

public NotificationService() {

    /*NotificationReceiver为BroadcastReceiver的子类
    *用于接收推送广播并用NotificationManager通知用户
    *也就是系统通知栏的通知
    */
    notificationReceiver = new NotificationRece

    /*ConnectivityReceiver接收手机网络状态的广播
    *来管理xmppManager与服务器的连接与断开
    */
    connectivityReceiver = new ConnectivityReceiver(this);

    /*集成于android.telephony.PhoneStateListener,
    *同上,用于监听数据链接的状态
    */
    phoneStateListener = new PhoneStateChangeListener(this);

    //线程池
    executorService = Executors.newSingleThreadExecutor();

    /*TaskSubmitter类包含了向上面的线程池提交一个Task任务
    *的方法
    */
    taskSubmitter = new TaskSubmitter(this);

    /*任务计数器
    *用以维护当前工作的Task    
    */
    taskTracker = new TaskTracker(this);
}

一切声明好以后,就开始执行服务了

private void start() {
    Log.d(LOGTAG, "start()...");

    //注册通知广播接收者
    registerNotificationReceiver();

    //注册手机网络连接状态接收者
    registerConnectivityReceiver();
    // Intent intent = getIntent();
    // startService(intent);

    //开始与服务器进行xmpp长链接
    //关于XmppManager后面会有分析
    xmppManager.connect();
}

XmppManager 管理Xmpp链接:

public XmppManager(NotificationService notificationService) {
    context = notificationService;

    //获取Task提交管理器,这里用于维护并行任务
    taskSubmitter = notificationService.getTaskSubmitter();

    //Task的计数器
    taskTracker = notificationService.getTaskTracker();

    //下面都是获取配置信息
    sharedPrefs = notificationService.getSharedPreferences();
    xmppHost = sharedPrefs.getString(Constants.XMPP_HOST, "localhost");
    xmppPort = sharedPrefs.getInt(Constants.XMPP_PORT, 5222);
    username = sharedPrefs.getString(Constants.XMPP_USERNAME, "");
    password = sharedPrefs.getString(Constants.XMPP_PASSWORD, "");

   /*设置xmpp链接状态的监听器,查看代码发现Xmpp链接状态有5种
    * 1 connectionClosed
    * 2 connectionClosedOnError
    * 3 reconnectingIn
    * 4 reconnectionFailed
    * 5 reconnectionSuccessful
    */
    connectionListener = new PersistentConnectionListener(this);

    /* 服务器推送监听器
    * 服务器如果有消息推送,NotificationPacketListener会
    * 自己解析好,并通过XmppManager发送广播
    */
    notificationPacketListener = new NotificationPacketListener(this);

    //当xmpp因异常重新连接服务器时,这期间发生异常的话,会在这个handler中处理
    handler = new Handler();

    //任务队列
    taskList = new ArrayList<Runnable>();

    /* 当xmppManager因异常与服务器断开链接时
    * ReconnectionThread会在一定的时间内尝试重新连接
    * 也就是说,当PersistentConnectionListener监听器监听到异常断开连接
    * 会调用ReconnectionThread中重新连接的方法以进行连接尝试
    reconnection = new ReconnectionThread(this);
}

androidpn与服务器连接流程

这里涉及很多smack包的操作,下篇会分析android下xmpp协议的封装smack。

Runable 1: ConnectTask
与服务器建立链接

Runable 1.5: RegisterTask
如果没有配置androidpn客户端的账户信息,它会自动生成一个随机账户并注册到服务器

Runalbe 2: LoginTask
读取本地的账户信息,并登录,开始等待服务器推送消息

 

最后就是大家最关心的,接受消息类NotificationReceiver

可能很多人讨厌服务器给自己弹出一个消息,注释这块代码就可以将它取消,根据自己需要进行修改

public void onReceive(Context context, Intent intent) {
        Log.d(LOGTAG, "NotificationReceiver.onReceive()...");
        String action = intent.getAction();
        Log.d(LOGTAG, "action=" + action);

        if (Constants.ACTION_SHOW_NOTIFICATION.equals(action)) {
            String notificationId = intent
                    .getStringExtra(Constants.NOTIFICATION_ID);
            String notificationApiKey = intent
                    .getStringExtra(Constants.NOTIFICATION_API_KEY);
            String notificationTitle = intent
                    .getStringExtra(Constants.NOTIFICATION_TITLE);
            String notificationMessage = intent
                    .getStringExtra(Constants.NOTIFICATION_MESSAGE);
            String notificationUri = intent
                    .getStringExtra(Constants.NOTIFICATION_URI);
            String notificationFrom = intent
              .getStringExtra(Constants.NOTIFICATION_FROM);
            String packetId = intent
        .getStringExtra(Constants.PACKET_ID);
           
            Log.d(LOGTAG, "notificationId=" + notificationId);
            Log.d(LOGTAG, "notificationApiKey=" + notificationApiKey);
            Log.d(LOGTAG, "notificationTitle=" + notificationTitle);
            Log.d(LOGTAG, "notificationMessage=" + notificationMessage);
            Log.d(LOGTAG, "notificationUri=" + notificationUri);

           
            System.out.println("notificationId=" + notificationId);
            System.out.println("notificationApiKey=" + notificationApiKey);
            System.out.println("notificationTitle=" + notificationTitle);
            System.out.println("notificationMessage=" + notificationMessage);
            System.out.println("notificationUri=" + notificationUri);
           
           
//            Notifier notifier = new Notifier(context);
//            notifier.notify(notificationId, notificationApiKey,
//                    notificationTitle, notificationMessage, notificationUri,notificationFrom,packetId);
        }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值