一.jcenter 自动集成步骤
1.确认android studio的 Project 根目录的主 gradle 中配置了jcenter支持。(新建project默认配置就支持,一般不需要配置,只要确认一下就好)
buildscript { repositories { jcenter() } ...... } allprojets { repositories { jcenter() } }
2.在 module 的 gradle 中添加依赖和AndroidManifest的替换变量。
android { ...... defaultConfig { applicationId "com.xxx.xxx" //JPush上注册的包名. ...... ndk { //选择要添加的对应cpu类型的.so库。 abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a' // 还可以添加 'x86', 'x86_64', 'mips', 'mips64' } manifestPlaceholders = [ JPUSH_PKGNAME : applicationId, JPUSH_APPKEY : "你的appkey", //JPush上注册的包名对应的appkey. JPUSH_CHANNEL : "developer-default", //暂时填写默认值即可. ] ...... } ...... } dependencies { ...... compile 'cn.jiguang.sdk:jpush:3.1.1' // 此处以JPush 3.1.1 版本为例。 compile 'cn.jiguang.sdk:jcore:1.1.9' // 此处以JCore 1.1.9 版本为例。 ...... }
注 : 如果在添加以上 abiFilter 配置之后android Studio出现以下提示:
NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin
则在 Project 根目录的gradle.properties文件中添加:
android.useDeprecatedNdk=true
二. AndroidManifest加权限
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.******"> <uses-permission android:name="android.permission.INTERNET"/> <!-- 访问当前网络状态权限 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <!-- 获取手机信息 --> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION"/> <!--2017.5.27 极光推送权限 ym start--> <uses-permission android:name="android.permission.WAKE_LOCK"/> <uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_SETTINGS"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <permission android:name="com.******(包名).permission.JPUSH_MESSAGE" android:protectionLevel="signature"/> <uses-permission android:name="com.******(包名).permission.JPUSH_MESSAGE"/> <!--2017.5.27 极光推送权限 ym end-->
集成 JPush Android SDK 的混淆
请下载4.x及以上版本的proguard.jar, 并替换你Android Sdk "tools\proguard\lib\proguard.jar"
请在工程的混淆文件中添加以下配置:
-dontoptimize -dontpreverify -dontwarn cn.jpush.** -keep class cn.jpush.** { *; } -keep class * extends cn.jpush.android.helpers.JPushMessageReceiver { *; } -dontwarn cn.jiguang.** -keep class cn.jiguang.** { *; }
2.0.5 ~ 2.1.7 版本有引入 gson 和 protobuf ,增加排除混淆的配置。(2.1.8版本不需配置)
#==================gson && protobuf========================== -dontwarn com.google.** -keep class com.google.gson.** {*;} -keep class com.google.protobuf.** {*;}
四. JPushManger极光推送管理类
public class JPushManager { private String TAG = "JPushManager"; private Context context; private static JPushManager jPushManager; public JPushManager(Context context) { this.context = context; } public static JPushManager newInstence(Context context) { if (jPushManager == null) { jPushManager = new JPushManager(context); } return jPushManager; } /** * 初始化极光,一般可以放到程序的启动Activity或是Application的onCreate方法中调用 */ public void initJPush() { JPushInterface.setDebugMode(true); // 设置开启日志,发布时请关闭日志 JPushInterface.init(context); // 初始化 JPush } /** * 退出极光,一般是程序退出登录时候,具体还是需要看项目的实际需求 */ public void stopJPush() { JPushInterface.stopPush(context); //setAliasAndTags("", "");//通过清空别名来停止极光 } /** * 极光推送恢复正常工作 */ public void resumeJPush() { JPushInterface.resumePush(context); } /** * 设置AliasAndTag,设置多组tag,如果不需要设置tag的化,直接将此参数设为null;(这个方法设置别名,tag传null没有问题) * 一般在程序登录成功,注册成功等地方调用。别名一般是用户的唯一标识,如userId等 * * @param alias * @param tags */ public void setAliasAndTags(final String alias, Set<String> tags) { if (TextUtils.isEmpty(alias)) { //Toast.makeText(context, "别名为空", Toast.LENGTH_SHORT).show(); return; } // 调用 Handler 来异步设置别名 AliasAndTagsInfo aliasAndTagsInfo = new AliasAndTagsInfo(); aliasAndTagsInfo.setAlias(alias); aliasAndTagsInfo.setTag(tags); mHandler.sendMessage(mHandler.obtainMessage(MSG_SET_ALIAS, aliasAndTagsInfo)); } // * 设置AliasAndTag,设置一组tag,如果不需要设置tag的化,直接将此参数设为null;(这个方法设置别名,不设置tag,tag传null会走6002,tag参数错误) // */ public void setAliasAndTags(final String alias, String tag) { if (TextUtils.isEmpty(alias)) { // Toast.makeText(context, "别名为空", Toast.LENGTH_SHORT).show(); return; } // 调用 Handler 来异步设置别名 AliasAndTagsInfo aliasAndTagsInfo = new AliasAndTagsInfo(); aliasAndTagsInfo.setAlias(alias); Set<String> tags = new HashSet<String>(); tags.add(tag); aliasAndTagsInfo.setTag(tags); mHandler.sendMessage(mHandler.obtainMessage(MSG_SET_ALIAS, aliasAndTagsInfo)); } private final TagAliasCallback mAliasCallback = new TagAliasCallback() { @Override public void gotResult(int code, String alias, Set<String> tags) { String logs; switch (code) { case 0: logs = "Set tag and alias success"; Log.d(TAG, logs); // 建议这里往 SharePreference 里写一个成功设置的状态。成功设置一次后,以后不必再次设置了。 break; case 6002: logs = "Failed to set alias and tags due to timeout. Try again after 60s."; Log.d(TAG, logs); // 延迟 60 秒来调用 Handler 设置别名 mHandler.sendMessageDelayed( mHandler.obtainMessage(MSG_SET_ALIAS, alias), 1000 * 60); break; default: logs = "Failed with errorCode = " + code; Log.d(TAG, logs); } } }; private static final int MSG_SET_ALIAS = 1001; private final Handler mHandler = new Handler() { @Override public void handleMessage(android.os.Message msg) { super.handleMessage(msg); AliasAndTagsInfo aliasAndTagsInfo = (AliasAndTagsInfo) msg.obj; switch (msg.what) { case MSG_SET_ALIAS: Log.d(TAG, "Set alias in handler."); Log.e("ym", aliasAndTagsInfo.getAlias()); // 调用 JPush 接口来设置别名。 JPushInterface.setAliasAndTags(context, aliasAndTagsInfo.getAlias(), aliasAndTagsInfo.getTag(), mAliasCallback); break; default: Log.d(TAG, "Unhandled msg - " + msg.what); } } }; public class AliasAndTagsInfo implements Serializable { private static final long serialVersionUID = 1L; private String alias; private Set<String> tag; public String getAlias() { return alias; } public void setAlias(String alias) { this.alias = alias; } public Set<String> getTag() { return tag; } public void setTag(Set<String> tag) { this.tag = tag; } } }
五. 在Application的onCreate()中初始化极光
//记得在相关的activity中关闭public class ExampleApplication extends Application { @Override public void onCreate() { super.onCreate(); JPushManager jPushManager = JPushManager.newInstence(getApplicationContext()); jPushManager.initJPush(); } }
@Override protected void onDestroy() { super.onDestroy(); jPushManager.stopJPush(); MyActivityManager.removeActivity(this); }
六. 极光推送自定义的广播接受者,用于获取推送到通知栏的消息内容、消息附加的参数字段处理消息的跳转
public class MyJPushReceiver extends BroadcastReceiver { private static final String TAG = "JPush"; @Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); Log.e(TAG, "[MyReceiver] onReceive - " + intent.getAction() + ", extras: " + printBundle(bundle)); if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) { String regId = bundle.getString(JPushInterface.EXTRA_REGISTRATION_ID); Log.e(TAG, "[MyReceiver] 接收Registration Id : " + regId); } else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) { Log.e(TAG, "[MyReceiver] 接收到推送下来的自定义消息: " + bundle.getString(JPushInterface.EXTRA_MESSAGE)); // processCustomMessage(context, bundle); } else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) { Log.e(TAG, "[MyReceiver] 接收到推送下来的通知"); int notificationId = bundle.getInt(JPushInterface.EXTRA_NOTIFICATION_ID); Log.e(TAG, "[MyReceiver] 接收到推送下来的通知的ID: " + notificationId); } else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) { Log.e(TAG, "[MyReceiver] 用户点击打开了通知"); String message = bundle.getString(JPushInterface.EXTRA_MESSAGE); String content = (String) bundle.get(JPushInterface.EXTRA_ALERT); //打开自定义的Activity Intent i = new Intent(context, Main2Activity.class); i.putExtra("content",content); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(i); } else if (JPushInterface.ACTION_RICHPUSH_CALLBACK.equals(intent.getAction())) { Log.e(TAG, "[MyReceiver] 用户收到到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.e(TAG, "[MyReceiver]" + intent.getAction() + " connected state change to " + connected); } else { Log.e(TAG, "[MyReceiver] 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 if (key.equals(JPushInterface.EXTRA_EXTRA)) { if (TextUtils.isEmpty(bundle.getString(JPushInterface.EXTRA_EXTRA))) { Log.e(TAG, "This message has no Extra data"); continue; } try { JSONObject json = new JSONObject(bundle.getString(JPushInterface.EXTRA_EXTRA)); Iterator<String> it = json.keys(); while (it.hasNext()) { String myKey = it.next().toString(); sb.append("\nkey:" + key + ", value: [" + myKey + " - " + json.optString(myKey) + "]"); } } catch (JSONException e) { Log.e(TAG, "Get message extra JSON error!"); } } else { sb.append("\nkey:" + key + ", value:" + bundle.getString(key)); } } return sb.toString(); } /** * 判断进程是否在后台 * * @param context * @return */ public static boolean isBackground(Context context) { ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses(); for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) { if (appProcess.processName.equals(context.getPackageName())) { Log.i("ym", appProcess.processName + "前台"); return false; } else { Log.i("ym", appProcess.processName + "后台"); return true; } } return false; } }
七. AndroidManifest中加极光推送自定义的广播接受者
<!--2017.5.27 极光推送自定义的广播接收器 ym start--> <receiver android:name=".module.MyJPushReceiver" android:enabled="true" android:exported="false"> <intent-filter> <action android:name="cn.jpush.android.intent.REGISTRATION"/> <!-- Required 用户注册SDK的intent --> <action android:name="cn.jpush.android.intent.MESSAGE_RECEIVED"/> <!-- Required 用户接收SDK消息的intent --> <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED"/> <!-- Required 用户接收SDK通知栏信息的intent --> <action android:name="cn.jpush.android.intent.NOTIFICATION_OPENED"/> <!-- Required 用户打开自定义通知栏的intent --> <action android:name="cn.jpush.android.intent.NOTIFICATION_CLICK_ACTION"/> <action android:name="cn.jpush.android.intent.CONNECTION"/> <!-- 接收网络变化 连接/断开 since 1.6.3 --> <category android:name="com.*******(包名)"/> </intent-filter> </receiver>
在MyJPushReceiver接收器里面,添加以下代码:进行跳转else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) { Log.e(TAG, "[MyReceiver] 用户点击打开了通知"); String message = bundle.getString(JPushInterface.EXTRA_MESSAGE); String content = (String) bundle.get(JPushInterface.EXTRA_ALERT); //打开自定义的Activity Intent i = new Intent(context, Main2Activity.class); i.putExtra("content",content); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(i);
去判断任务栈中存在的Activity个数,如果Activity数都为0了,
那应用肯定退出了,不再运行了。而判断Activity数可以自己创建一个类去管理Activity,
代码如下:使用这个类有两种方法:public class MyActivityManager { private static List<Activity> activityList = new ArrayList<Activity>(); private static MyActivityManager instance; public static MyActivityManager getInstance() { if (instance == null) { instance = new MyActivityManager(); } return instance; } /** * 添加 Activity 到列表 * * @param activity activity */ public static void addActivity(Activity activity) { if (activityList == null) { activityList = new ArrayList<Activity>(); } activityList.add(activity); } /** * 获取界面数量 * * @return activity size */ public static int getActivitySize() { if (activityList != null) { return activityList.size(); } return 0; } /** * 获取当前 Activity - 堆栈中最后一个压入的 * * @return current Activity */ public static Activity getCurrentActivity() { if (activityList != null && activityList.size() > 0) { Activity activity = activityList.get(activityList.size() - 1); return activity; } return null; } /** * 获取指定类名的 Activity * * @param cls 指定的类 * @return Activity */ public static Activity getActivity(Class<?> cls) { if (activityList == null) { return null; } for (Activity activity : activityList) { if (activity.getClass().equals(cls)) { return activity; } } return null; } /** * 结束指定的 Activity * * @param activity Activity */ public static void removeActivity(Activity activity) { if (activity != null) { activityList.remove(activity); } } /** * 结束指定类名的 Activity * * @param cls 指定的类 */ public static void removeActivity(Class<?> cls) { if (activityList == null) { return; } for (Activity activity : activityList) { if (activity.getClass().equals(cls)) { activityList.remove(activity); } } } /** * 结束所有Activity */ public static void finishAllActivity() { if (activityList == null) { return; } int size = activityList.size(); for (int i = 0; i < size; i++) { if (null != activityList.get(i)) { activityList.get(i).finish(); } } activityList.clear(); } /** * 结束其他所有的Activity * * @param activity 不需要销毁的Activity */ public static void finishOtherAllActivity(Activity activity) { if (activityList == null) { return; } for (int i = 0, size = activityList.size(); i < size; i++) { if (activity != activityList.get(i)) { activityList.get(i).finish(); activityList.remove(i); } } } }
(1),在BaseActivity的生命周期中调用
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- MyActivityManager.addActivity(this);
- }
//另一种就是在相对应的activity中调用
- @Override
- protected void onDestroy() {
- MyActivityManager.removeActivity(this);