推送是现在应用中经常要用到的一个功能 不管是IM体系还是其他的 提醒/通知什么的 甚至是有些厌恶的广告……
极光推送做得一直还可以而且还是免费的,集成也相对来说比较简单。
(本文主要讲的是Android的集成,服务端的话主要是调用相关的极光Api,大部分功能需要两者协调才能走通)

主要步骤

  1. 注册开发者账号
  2. 添加应用,下载example
  3. 配置资源和manifest
  4. 自定义Receiver
  5. 初始化代码
  6. 封装JpushUtil

注册开发者账号

登录官网 极光推送,注册开发者账号(这个账号需要记住的,如果忘掉,就没法看推送相关的后台信息了)

添加应用

登陆控制台后在左侧添加应用

其中包名最好与你要集成的项目包名一致,否则可能会引起不可预知的问题。

PS:IOS的那边推送也可以加进来,不过除了统一统计推送数据也没啥意义了吧。什么?你说WinPhone?

AndroidManifest文件中的包名

<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.ysdemo.jpushdemo" //你的包名      android:versionCode="181"    android:versionName="1.8.1"

配置资源和manifest

manifest文件很长,看着麻烦,但是其实Jpush做得真的很人性化,在这一步博主几乎没花什么力气。
Jpush官方文档有一些说明:

这里无论是从 example直接复制过去,还是下载sdk复制进去都可以。
其中so文件如果不需要适配多个CPU版本的话 只复制armeabi目录下的就可以了。

这里主要是 复制过去把包名替换掉,然后在最后将Key换成你刚刚注册所得的AppKey(不是Secret)

自定义Receiver

example的manifest中有一段这样的代码,替换其中的包名,也直接复制进自己的项目。

                <receiver            android:name="com.example.jpushdemo.MyJpushReceiver"            android:enabled="true"            android:exported="false" >            <intent-filter>                <action android:name="cn.jpush.android.intent.REGISTRATION" />                 <action android:name="cn.jpush.android.intent.UNREGISTRATION" />                  <action android:name="cn.jpush.android.intent.MESSAGE_RECEIVED" />                 <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED" />                 <action android:name="cn.jpush.android.intent.NOTIFICATION_OPENED" />                 <action android:name="cn.jpush.android.intent.ACTION_RICHPUSH_CALLBACK" />                 <action android:name="cn.jpush.android.intent.CONNECTION" />                <category android:name="com.zhong.jplus.example" />            intent-filter>        receiver>

报错了?当然报错啦,去创建一个对应的MyJpushReceiver吧~

MyJpushReceiver.java

package com.yedemo.jpushdemo.receiver;import org.json.JSONObject;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.os.Bundle;import android.util.Log;import cn.jpush.android.api.JPushInterface;public class MyJpushReceiver extends BroadcastReceiver {    private static final String TAG = "JPush";    private SharedPreferenceUtil spu;    @Override    public void onReceive(final Context context, Intent intent) {        final Bundle bundle = intent.getExtras();        Log.d(TAG, "[MyJpushReceiver] onReceive - " + intent.getAction() + ", extras: " + printBundle(bundle));        if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {            String regId = bundle.getString(JPushInterface.EXTRA_REGISTRATION_ID);            Log.d(TAG, "[MyJpushReceiver] 接收Registration Id : " + regId);            //send the Registration Id to your server...        } else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {            Log.d(TAG, "[MyJpushReceiver] 接收到推送下来的自定义消息: " + bundle.getString(JPushInterface.EXTRA_MESSAGE));            //需要自定义通知展示        } else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {            Log.d(TAG, "[MyJpushReceiver] 接收到推送下来的通知");            int notifactionId = bundle.getInt(JPushInterface.EXTRA_NOTIFICATION_ID);            Log.d(TAG, "[MyJpushReceiver] 接收到推送下来的通知的ID: " + notifactionId);        } else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {            Log.d(TAG, "[MyJpushReceiver] 用户点击打开了通知");    //这里可以写一些跳转到某界面的代码,用户点击后就会进行跳转        } else if (JPushInterface.ACTION_RICHPUSH_CALLBACK.equals(intent.getAction())) {            Log.d(TAG, "[MyJpushReceiver] 用户收到到RICH PUSH CALLBACK: " + bundle.getString(JPushInterface.EXTRA_EXTRA));            //在这里根据 JPushInterface.EXTRA_EXTRA 的内容处理代码,比如打开新的Activity, 打开一个网页等..        } else if(JPushInterface.ACTION_CONNECTION_CHANGE.equals(intent.getAction())) {            boolean connected = intent.getBooleanExtra(JPushInterface.EXTRA_CONNECTION_CHANGE, false);            Log.w(TAG, "[MyJpushReceiver]" + intent.getAction() +" connected state change to "+connected);        } else {            Log.d(TAG, "[MyJpushReceiver] Unhandled intent - " + intent.getAction());        }    }    // 打印所有的 intent extra 数据    private static String printBundle(Bundle bundle) {        StringBuilder sb = new StringBuilder();        for (String key : bundle.keySet()) {            if (key.equals(JPushInterface.EXTRA_NOTIFICATION_ID)) {                sb.append("\nkey:" + key + ", value:" + bundle.getInt(key));            }else if(key.equals(JPushInterface.EXTRA_CONNECTION_CHANGE)){                sb.append("\nkey:" + key + ", value:" + bundle.getBoolean(key));            }             else {                sb.append("\nkey:" + key + ", value:" + bundle.getString(key));            }        }        return sb.toString();    }}

其实这个文件example里面也有,你也可以把那个复制进去稍加改动。

初始化代码

Jpush建议在Application中进行初始化:
MyApplication.java

import android.app.Application;import android.util.Log;import cn.jpush.android.api.JPushInterface;/** * For developer startup JPush SDK *  * 一般建议在自定义 Application 类里初始化。也可以在主 Activity 里。 */public class MyApplication extends Application {    private static final String TAG = "JPush";    @Override    public void onCreate() {                      Log.d(TAG, "[ExampleApplication] onCreate");         super.onCreate();         JPushInterface.setDebugMode(true);     // 设置开启日志,发布时请关闭日志         JPushInterface.init(this);             // 初始化 JPush    }}

到这里你的应用就可以接受到广播推送了。
但是请注意,只是广播推送。

然而个别推送需要向你自己的服务器提供别名Alias(可以用类似用户名/用户Id这样的)或者Jpush初始化时候获得的Registration ID(初始化后可以通过JPushInterface.getRegistrationID(context) 获取)。

但如果是这样的话,你得保证用户每次进入/登陆应用都进行设置别名从而能够正常地接受推送,所以往往需要一个JpushUtil来封装一些操作。

封装JpushUtil(可选)

目前这个JpushUtil呢我写的也不是很完善,只是在原来基础上增添了一个设置别名的方法。你可以把其他代码也放进来。

public class JpushUtil {//    public static final String PREFS_NAME = "JPUSH_EXAMPLE";//    public static final String PREFS_DAYS = "JPUSH_EXAMPLE_DAYS";//    public static final String PREFS_START_TIME = "PREFS_START_TIME";//    public static final String PREFS_END_TIME = "PREFS_END_TIME";    public static final String KEY_APP_KEY = "JPUSH_APPKEY";    public static final String TAG = JpushUtil.class.getName().toString();    public static boolean isEmpty(String s) {        if (null == s)            return true;        if (s.length() == 0)            return true;        if (s.trim().length() == 0)            return true;        return false;    }    // 校验Tag Alias 只能是数字,英文字母和中文    public static boolean isValidTagAndAlias(String s) {        Pattern p = Pattern.compile("^[\u4E00-\u9FA50-9a-zA-Z_-]{0,}$");        Matcher m = p.matcher(s);        return m.matches();    }    // 取得AppKey    public static String getAppKey(Context context) {        Bundle metaData = null;        String appKey = null;        try {            ApplicationInfo ai = context.getPackageManager().getApplicationInfo(                    context.getPackageName(), PackageManager.GET_META_DATA);            if (null != ai)                metaData = ai.metaData;            if (null != metaData) {                appKey = metaData.getString(KEY_APP_KEY);                if ((null == appKey) || appKey.length() != 24) {                    appKey = null;                }            }        } catch (NameNotFoundException e) {        }        return appKey;    }    // 取得版本号    public static String GetVersion(Context context) {        try {            PackageInfo manager = context.getPackageManager().getPackageInfo(                    context.getPackageName(), 0);            return manager.versionName;        } catch (NameNotFoundException e) {            return "Unknown";        }    }    public static void showToast(final String toast, final Context context)    {        new Thread(new Runnable() {            @Override            public void run() {                Looper.prepare();                Toast.makeText(context, toast, Toast.LENGTH_SHORT).show();                Looper.loop();            }        }).start();    }    public static boolean isConnected(Context context) {        ConnectivityManager conn = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);        NetworkInfo info = conn.getActiveNetworkInfo();        return (info != null && info.isConnected());    }    public static String getImei(Context context, String imei) {        try {            TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);            imei = telephonyManager.getDeviceId();        } catch (Exception e) {            Log.e(JpushUtil.class.getSimpleName(), e.getMessage());        }        return imei;    }    /* 以上内容example中有,以下内容为本人添加 */       public static TagAliasCallback getCallBack(final Context context){        return new TagAliasCallback() {            public void gotResult(int code,final String alias, Set tags) {                String logs ;                switch (code) {                case 0:                    logs = "Set tag and alias success" + alias;                    SharedPreferenceUtil spu = SharedPreferenceUtil.getInstance(context);                    spu.save("jpushAlias", alias);                    spu.save("jpushAliasLogin", true);                    Log.i(TAG, logs);                    break;                case 6002:                    logs = "Failed to set alias and tags due to timeout. Try again after 60s.";                    Log.i(TAG, logs);                    if (JpushUtil.isConnected(context)) {                        new Handler().postDelayed(new Runnable() {                            public void run() {                                JPushInterface.setAliasAndTags(context, alias, null, getCallBack(context));                            }                        }, 1000 * 60);                    } else {                        Log.i(TAG, "No network");                    }                    break;                default:                    logs = "Failed with errorCode = " + code;                    Log.e(TAG, logs);                }//              JpushUtil.showToast(logs, context);            }        };    }    //设置别名    public static void setAlias(Context context,String alias) {        if (!SharedPreferenceUtil.getInstance(context).loadStrPrefer("jpushAlias").equals(alias)                &&!SharedPreferenceUtil.getInstance(context).loadBooleanPrefer("jpushAliasLogin")) {            JPushInterface.setAliasAndTags(context, alias+"", null, JpushUtil.getCallBack(context));        }else {            Log.i(TAG,"alias has been set as "+alias);        }    }    //如果停止了推送服务并允许推送,开启    public static void resetPushState(Context context) {        SharedPreferenceUtil spu = SharedPreferenceUtil.getInstance(context);        if (JPushInterface.isPushStopped(context) && !spu.loadBooleanPrefer("jpushSetUp")) {            JPushInterface.resumePush(context);        }else if (spu.loadBooleanPrefer("jpushSetUp")) {            JPushInterface.stopPush(context);        }    }}

其中SharedPreferenceUtil 这个单例类主要是封装了一些对SharedPreference的操作,如果你应用中没有的话,你可以取一个SharedPreference出来进行操作。

总结

本文没有demo,一切API调用可参考下载下来的push-example这个例子。遇到其他问题可以留言提问。

总体来说,极光还算是简单易用的第三方推送。

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. activity的生命周期——第一行代码阅读笔记
  3. 换一种方式理解 Android协程
  4. 如何正确的在 Android(安卓)上使用协程 ?
  5. Android(安卓)LitePal的简单使用
  6. WeakReference在android中的使用场景
  7. Android(安卓)APK签名对比及说明
  8. Android混淆代码proguard,内存溢出
  9. Android小项目之二 代码的组织结构

随机推荐

  1. Android(安卓)Makefile 编译过程分析
  2. radiobutton设置自定义样式
  3. Android的MediaPlayer架构介绍
  4. Android(安卓)数组,集合,字典排序
  5. Android中的线程与进程模型
  6. Android获取CPU使用率的几种方式
  7. Android(安卓)源码结构【搜集】
  8. Android的传感器应用
  9. Android牟利之道(一)--界面嵌入有米广告
  10. Android(安卓)APK 签名比对