推送通知消息在一个与网络交互的app中是很常见的功能,那具体如何处理呢?当然,我们可以自己实现推送的功能,但是比较复杂,不是重量级应用也没那个必要,用第三方的推送平台就够了。
目前我了解到的不错的第三方推送有信鸽、友盟、个推等推送平台,我使用信鸽和友盟推送封装了一个推送消息通知管理类,方便外部使用推送功能,也很容易加入新的推送平台。
下面以代码进行简要讲解,代码中有较详细注释,说明信鸽推送、友盟推送的使用:

1.PushDemoActivity.java:

/**
 * 演示页面
 * 
 * @author vv
 * @mail xu_vv@foxmail.com
 * @date 2015-10-9下午1:34:55
 * @version 1.0
 */
public class PushDemoActivity extends Activity {

    // PushManager mPushManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_push_demo);
        // mPushManager = new PushManager();

        PushManager.initPushManager(getApplicationContext());
        PushManager.setIMessageListener(new IMessageListener() {

            @Override
            public void getMessageContent(String messageContent) {

                Log.v("######################", "activity收到消息:" + messageContent);

            }

        });

    }

}

2.PushManager.java:

/**
 * 封装的推送通知消息的管理器
 * 
 * @author vv
 * @mail xu_vv@foxmail.com
 * @date 2015-10-9上午9:54:39
 * @version 1.0
 */
public class PushManager {

    /**
     * 消息监听器实例
     */
    public static IMessageListener mmIMessageListener;

    /**
     * 设置推送消息监听
     * 
     * @param mIMessageListener
     */
    public static void setIMessageListener(IMessageListener mIMessageListener) {
        mmIMessageListener = mIMessageListener;
    }

    /**
     * 初始化推送管理器
     * 
     * @param applicationContext
     */
    public static void initPushManager(Context applicationContext) {
        XGPush.initXgPushManager(applicationContext);
        UMengPush.initUmengPushManager(applicationContext);
    }

    /**
     * 初始化信鸽推送管理器
     * 
     * @param applicationContext
     */
    public static void initXgPushManager(Context applicationContext) {
        XGPush.initXgPushManager(applicationContext);
    }

    /**
     * 初始化友盟推送管理器
     * 
     * @param applicationContext
     */
    public static void initUmengPushManager(Context applicationContext) {
        UMengPush.initUmengPushManager(applicationContext);
    }

}

3.XGPush.java:

/**
 * 信鸽推送管理器
 * 
 * @author vv
 * @mail xu_vv@foxmail.com
 * @date 2015-10-9下午1:35:11
 * @version 1.0
 */
public class XGPush {

    /**
     * 初始化信鸽推送
     * 
     * @param context
     */
    public static void initXgPushManager(Context context) {
        // 开启logcat输出,方便debug,发布时请关闭
        // XGPushConfig.enableDebug(this, true);
        // 如果需要知道注册是否成功,请使用registerPush(getApplicationContext(),
        // XGIOperateCallback)带callback版本
        // 如果需要绑定账号,请使用registerPush(getApplicationContext(),account)版本
        // 具体可参考详细的开发指南
        // 传递的参数为ApplicationContext
        XGPushManager.registerPush(context);

        // 2.36(不包括)之前的版本需要调用以下2行代码。还有,已知MIUI
        // V6上会禁用所有静态广播,若出现有类似的情况,添加以下代码兼容该系统。
        Intent service = new Intent(context, XGPushService.class);
        context.startService(service);

        // 其它常用的API:
        // 绑定账号(别名)注册:registerPush(context,account)或registerPush(context,account,
        // XGIOperateCallback),其中account为APP账号,可以为任意字符串(qq、openid或任意第三方),业务方一定要注意终端与后台保持一致。
        // 取消绑定账号(别名):registerPush(context,"*"),即account="*"为取消绑定,解绑后,该针对该账号的推送将失效
        // 反注册(不再接收消息):unregisterPush(context)
        // 设置标签:setTag(context, tagName)
        // 删除标签:deleteTag(context, tagName)
    }

}

4.信鸽消息接收XGMessageReceiver.java:

该类在配置文件中进行了静态注册,继承自XGPushBaseReceiver,实现其中的方法如下,使用接口获取数据,在设置推送消息监听器时实现接口即可获取到数据:
@Override
    public void onTextMessage(Context context, XGPushTextMessage message) {

        String text = message.toString();
//      // 获取自定义key-value
//      String customContent = message.getCustomContent();
//      if (customContent != null && customContent.length() != 0) {
//          try {
//              JSONObject obj = new JSONObject(customContent);
//              // key1为前台配置的key
//              if (!obj.isNull("key")) {
//                  String value = obj.getString("key");
//                  Log.d("+++++++++++++++++++++", "get custom value:" + value);
//              }
//              // ...
//          } catch (JSONException e) {
//              e.printStackTrace();
//          }
//      }

        String content = message.getContent();
        if (content != null && content.length() != 0) {
            try {
                JSONObject obj = new JSONObject(content);
                // key1为前台配置的key
                if (!obj.isNull("key")) {
                    String value = obj.getString("key");
                    Log.d("+++++++++++++++++++++", "get content value:" + value);
                }
                // ...
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        // APP自主处理消息的过程...
        Log.d("******************", "XG消息:" + content);
        Log.d("=====================", text);

        /**
         * 通过消息监听接口获取数据
         */
        mIMessageListener.getMessageContent(content);

    }

5.UMengPush.java:

/**
 * 友盟推送管理器
 * 
 * @author vv
 * @mail xu_vv@foxmail.com
 * @date 2015-10-9下午2:44:20
 * @version 1.0
 */
public class UMengPush {

    /**
     * 初始化友盟推送
     * 
     * @param context
     */
    public static void initUmengPushManager(Context context) {
        PushAgent mPushAgent = PushAgent.getInstance(context);
        PushAgent.getInstance(context).onAppStart();

        UmengMessageHandler messageHandler = new UmengMessageHandler() {
            @Override
            public void dealWithCustomMessage(final Context context,
                    final UMessage msg) {
                new Handler(context.getMainLooper()).post(new Runnable() {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub

                        // 对自定义消息的处理方式,点击或者忽略
                        boolean isClickOrDismissed = true;
                        if (isClickOrDismissed) {
                            // 自定义消息的点击统计
                            UTrack.getInstance(context).trackMsgClick(msg);
                        } else {
                            // 自定义消息的忽略统计
                            UTrack.getInstance(context).trackMsgDismissed(msg);
                        }
                        Toast.makeText(context, msg.custom, Toast.LENGTH_LONG)
                                .show();
                        Log.v("*******************", "umeng消息:" + msg.custom);

                        /**
                         * 通过消息监听接口获取数据
                         */
                        PushManager.mmIMessageListener
                                .getMessageContent(msg.custom);
                    }
                });
            }
        };
        mPushAgent.setMessageHandler(messageHandler);

        mPushAgent.enable();
    }

}

6.AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="xyz.vv.pushdemo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="9"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".PushDemoActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- 【必须】 信鸽receiver广播接收 -->
        <receiver
            android:name="com.tencent.android.tpush.XGPushReceiver"
            android:process=":xg_service_v2" >
            <intent-filter android:priority="0x7fffffff" >

                <!-- 【必须】 信鸽SDK的内部广播 -->
                <action android:name="com.tencent.android.tpush.action.SDK" />
                <action android:name="com.tencent.android.tpush.action.INTERNAL_PUSH_MESSAGE" />
                <!-- 【必须】 系统广播:开屏和网络切换 -->
                <action android:name="android.intent.action.USER_PRESENT" />
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />

                <!-- 【可选】 一些常用的系统广播,增强信鸽service的复活机会,请根据需要选择。当然,你也可以添加APP自定义的一些广播让启动service -->
                <action android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
            </intent-filter>
            <!-- 【可选】 usb相关的系统广播,增强信鸽service的复活机会,请根据需要添加 -->
            <intent-filter android:priority="0x7fffffff" >
                <action android:name="android.intent.action.MEDIA_UNMOUNTED" />
                <action android:name="android.intent.action.MEDIA_REMOVED" />
                <action android:name="android.intent.action.MEDIA_CHECKING" />
                <action android:name="android.intent.action.MEDIA_EJECT" />

                <data android:scheme="file" />
            </intent-filter>
        </receiver>

        <!-- 【必须】 (2.30及以上版新增)展示通知的activity -->
        <!-- 【注意】 如果被打开的activity是启动模式为SingleTop,SingleTask或SingleInstance,请根据通知的异常自查列表第8点处理 -->
        <activity
            android:name="com.tencent.android.tpush.XGPushActivity"
            android:exported="true" >
            <intent-filter>

                <!-- 若使用AndroidStudio,请设置android:name="android.intent.action" -->
                <action android:name="" />
            </intent-filter>
        </activity>

        <!-- 【必须】 信鸽service -->
        <service
            android:name="com.tencent.android.tpush.service.XGPushService"
            android:exported="true"
            android:persistent="true"
            android:process=":xg_service_v2" />

        <!-- 【必须】 通知service,此选项有助于提高抵达率 -->
        <service
            android:name="com.tencent.android.tpush.rpc.XGRemoteService"
            android:exported="true" >
            <intent-filter>
                <action android:name="cn.com.servyou.pushdemo.PUSH_ACTION" />
            </intent-filter>
        </service>

        <!-- 【可选】APP实现的Receiver,用于接收消息透传和操作结果的回调,请根据需要添加 -->
        <!-- YOUR_PACKAGE_PATH.CustomPushReceiver需要改为自己的Receiver: -->
        <receiver android:name="cn.com.servyou.pushdemo.xg.XGMessageReceiver" >
            <intent-filter>
                <!-- 接收消息透传 -->
                <action android:name="com.tencent.android.tpush.action.PUSH_MESSAGE" />
                <!-- 监听注册、反注册、设置/删除标签、通知被点击等处理结果 -->
                <action android:name="com.tencent.android.tpush.action.FEEDBACK" />
            </intent-filter>
        </receiver>

        <!-- 【必须】 请将YOUR_ACCESS_ID修改为APP的AccessId,“21”开头的10位数字,中间没空格 -->
        <meta-data
            android:name="XG_V2_ACCESS_ID"
            android:value="YOUR_ACCESS_ID" />
        <!-- 【必须】 请将YOUR_ACCESS_KEY修改为APP的AccessKey,“A”开头的12位字符串,中间没空格 -->
        <meta-data
            android:name="XG_V2_ACCESS_KEY"
            android:value="YOUR_ACCESS_KEY" />

        <!-- 监听通知点击或者忽略处理的广播 -->
        <receiver
            android:name="com.umeng.message.NotificationProxyBroadcastReceiver"
            android:exported="false" >
        </receiver>

        <!-- 监听开机运行、网络连接变化、卸载的广播 -->
        <receiver
            android:name="com.umeng.message.SystemReceiver"
            android:process=":push" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_REMOVED" />

                <data android:scheme="package" />
            </intent-filter>
        </receiver>

        <!-- 监听消息到达的广播 -->
        <receiver
            android:name="com.umeng.message.MessageReceiver"
            android:exported="false"
            android:process=":push" >
            <intent-filter>
                <action android:name="org.agoo.android.intent.action.RECEIVE" />
            </intent-filter>
        </receiver>

        <!-- 监听宿主选举的广播 -->
        <receiver
            android:name="com.umeng.message.ElectionReceiver"
            android:process=":push" >
            <intent-filter>
                <action android:name="org.agoo.android.intent.action.ELECTION_RESULT_V4" />

                <category android:name="umeng" />
            </intent-filter>
        </receiver>

        <!-- 监听注册的广播 -->
        <!-- 【应用包名】字符串需要替换成本应用的应用包名 -->
        <receiver
            android:name="com.umeng.message.RegistrationReceiver"
            android:exported="false" >
            <intent-filter>
                <action android:name="cn.com.servyou.pushdemo.intent.action.COMMAND" />
            </intent-filter>
        </receiver>
        <receiver android:name="com.umeng.message.UmengMessageBootReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <!-- Umeng的长连服务,用来建立推送的长连接的 -->
        <!-- 【应用包名】字符串需要替换成本应用的应用包名 -->
        <service
            android:name="com.umeng.message.UmengService"
            android:exported="true"
            android:label="PushService"
            android:process=":push" >
            <intent-filter>
                <action android:name="cn.com.servyou.pushdemo.intent.action.START" />
            </intent-filter>
            <intent-filter>
                <action android:name="cn.com.servyou.pushdemo.intent.action.COCKROACH" />
            </intent-filter>
            <intent-filter>
                <action android:name="org.agoo.android.intent.action.PING_V4" />

                <category android:name="umeng" />
            </intent-filter>
        </service>

        <!-- Umeng的消息接收服务 -->
        <service
            android:name="com.umeng.message.UmengIntentService"
            android:process=":push" />

        <!-- Umeng的消息路由服务 -->
        <service
            android:name="com.umeng.message.UmengMessageIntentReceiverService"
            android:exported="true"
            android:process=":push" >
            <intent-filter>
                <action android:name="org.android.agoo.client.MessageReceiverService" />
            </intent-filter>
            <intent-filter>
                <action android:name="org.android.agoo.client.ElectionReceiverService" />
            </intent-filter>
        </service>

        <!-- v2.4.1添加的Service,Umeng的消息接收后的处理服务 -->
        <service
            android:name="com.umeng.message.UmengMessageCallbackHandlerService"
            android:exported="false" >
            <intent-filter>
                <action android:name="com.umeng.messge.registercallback.action" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.umeng.message.unregistercallback.action" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.umeng.message.message.handler.action" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.umeng.message.autoupdate.handler.action" />
            </intent-filter>
        </service>

        <!-- V1.3.0添加的service,负责下载通知的资源 -->
        <service android:name="com.umeng.message.UmengDownloadResourceService" />

        <!-- V2.5.0添加的Service,用于本地通知 -->
        <!-- 如果不使用本地通知,可以注释掉本地通知服务的配置 -->
        <service
            android:name="com.umeng.message.local.UmengLocalNotificationService"
            android:exported="false" />

        <meta-data
            android:name="UMENG_APPKEY"
            android:value="YOUR_APPKEY" >
        </meta-data>
        <meta-data
            android:name="UMENG_MESSAGE_SECRET"
            android:value="YOUR_MESSAGE_SECRET" >
        </meta-data>
    </application>

    <!-- 【必须】 信鸽SDK所需权限 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.RESTART_PACKAGES" />
    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
    <!-- 【必选】用以设置前台是否显示通知> -->
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.READ_LOGS" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <!-- 【可选】 信鸽SDK所需权限 -->
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BATTERY_STATS" />

    <!-- 必选 -->
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <!-- 可选 -->
    <uses-permission android:name="android.permission.BROADCAST_PACKAGE_ADDED" />
    <uses-permission android:name="android.permission.BROADCAST_PACKAGE_CHANGED" />
    <uses-permission android:name="android.permission.BROADCAST_PACKAGE_INSTALL" />
    <uses-permission android:name="android.permission.BROADCAST_PACKAGE_REPLACED" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />

</manifest>

以上为供大家了解学习信鸽推送和友盟推送使用,定义的接口因为很简单就不贴出来了。还有,因为使用了第三方平台,所以需要导入一些第三方架包和库文件。如果需要直接运行,可以下载项目后,注册需要的key等加入配置文件中即可。