推送功能現在在app中已是成常用的功能,而要實現推送功能,為了省時省力一般考慮采用第三方推送sdk來實現,這里總結是極光推送(JPush)這也是本人在項目中經常用到的第三方推送sdk , 總的來說集成起來挺簡單的,只要按照官方的文檔一步步集成還是能夠完成,本人第一次集成的時候也是這樣干的,其實其它的第三方sdk一般都是根據官方的文檔文檔一步步集成的,但對於一些從來沒有用過極光推送或是剛開始的人來說,總會有這樣的那樣的問題,會走一些彎路,會躺過一些坑,現在將以前的集成經驗進行流程化,再此做些記錄,便於以后自己集成時候參照,同時也希望能夠為其他需要的提供一些幫助。
1:前期的准備工作及注意點:
官網創建應用,生成appkey ,這是現在的第三方的sdk通用的准備工作,一般需要填寫程序的包名(有些還需要程序的簽名,如微信開放平台),這個包名一般都是一旦指定就不可更改。如果需要更改一般只能重新創建應用了,這時候的appkey就與之前不一樣了,程序中也需要相應的修改。

然后按照官方的android sdk集成指南進行集成就可以了。
注意幾點:
1 導包;導包完成后的目錄結構應該是:


2.注意權限配置:

配置兩個都需要,而且這兩個配置很相似,容易大意出錯(本人和同事曾在這里坑過)
3.注意查看Log日志,和錯誤信息:
1:打開極光的日志,
JPushInterface.
setDebugMode
(
true
);
// 設置開啟日志,發布時請關閉日志
2:通過JPush tag進行日志過濾

另外遇到問題可以查閱官方文檔中 androi常見問題 中對常見問題的解決方法。
根據在鄰里,新東方項目的集成經驗現總結如下:
主要是參考JPush官方文檔。
1.集成前的准備工作
a.在極光官網注冊開發者賬號。
b.登錄后創建應用,查看應用詳情,獲得AppKey如圖:

c.點擊圖中的綠色按鈕,下載Android Example,即官方Demo
以上步驟可以根據文檔。3分鍾Demo指導完成。

2.在自己的項目中集成。
這是可以根據之前下載的官方demo進行快速集成。
解壓下載的官方demo壓縮文件,打開可以看到如下目錄結構:

在自己的項目中需要集成以下幾部分。
1.jar包,
導入 SDK 開發包到你自己的應用程序項目
這里只需將libs目錄下的所有文件拷貝到我們工程目錄下的libs下即可。

2.
配置 AndroidManifest.xml
打開dmeo的AndroidManifest.xml文件。
拷貝下面代碼到自己項目的AndroidManifes.xml文件中
注意將其中的 "您應用的包名: 修改為自己的程序包名
-
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="您應用的包名" android:versionCode="180" android:versionName="1.8.0" > <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="17"/> <!--Required自定義用來收發消息的相關權限--> <permission android:name="您應用的包名.permission.JPUSH_MESSAGE" android:protectionLevel="signature"/> <!--Required 一些系統要求的權限,如訪問網絡等--> <uses-permission android:name="您應用的包名.permission.JPUSH_MESSAGE"/> <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WAKE_LOCK"/> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_SETTINGS"/> <uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <!--Optionalfor location --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name"> <!--Required SDK核心功能--> <activity android:name="cn.jpush.android.ui.PushActivity" android:configChanges="orientation|keyboardHidden" android:exported="false"> <intent-filter> <action android:name="cn.jpush.android.ui.PushActivity"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="您應用的包名"/> </intent-filter> </activity> <!--Required SDK核心功能--> <service android:name="cn.jpush.android.service.DownloadService" android:enabled="true" android:exported="false"> </service> <!--Required SDK 核心功能--> <service android:name="cn.jpush.android.service.PushService" android:enabled="true" android:exported="false"> <intent-filter> <action android:name="cn.jpush.android.intent.REGISTER"/> <action android:name="cn.jpush.android.intent.REPORT"/> <action android:name="cn.jpush.android.intent.PushService"/> <action android:name="cn.jpush.android.intent.PUSH_TIME"/> </intent-filter> </service> <!--Required SDK 核心功能--> <service android:name="cn.jpush.android.service.DaemonService" android:enabled="true" android:exported="true"> <intent-filter > <action android:name="cn.jpush.android.intent.DaemonService"/> <category android:name="您應用的包名"/> </intent-filter> </service> <!--Required SDK核心功能--> <receiver android:name="cn.jpush.android.service.PushReceiver" android:enabled="true" android:exported="false"> <intent-filter android:priority="1000"> <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY"/> <!--Required 顯示通知欄--> <category android:name="您應用的包名"/> </intent-filter> <intent-filter> <action android:name="android.intent.action.USER_PRESENT"/> <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> </intent-filter> <!--Optional--> <intent-filter> <action android:name="android.intent.action.PACKAGE_ADDED"/> <action android:name="android.intent.action.PACKAGE_REMOVED"/> <data android:scheme="package"/> </intent-filter> </receiver> <!--Required SDK核心功能--> <receiver android:name="cn.jpush.android.service.AlarmReceiver"/> <!--User defined. 用戶自定義的廣播接收器,如果不需要這個對推送消息進行處理,這個廣播接收器不用定義--> <receiver android:name="您自己定義的Receiver" android:enabled="true"> <intent-filter> <action android:name="cn.jpush.android.intent.REGISTRATION"/><!--Required 用戶注冊SDK的intent--> <action android:name="cn.jpush.android.intent.UNREGISTRATION"/> <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.ACTION_RICHPUSH_CALLBACK"/><!--Optional用戶接受RichPushJavascript回調函數的intent--> <action android:name="cn.jpush.android.intent.CONNECTION"/><!--接收網絡變化連接/斷開 since 1.6.3--> <category android:name="您應用的包名"/> </intent-filter> </receiver> <!--Required .Enable it you can get statistics data with channel --> <meta-data android:name="JPUSH_CHANNEL" android:value="developer-default"/> <meta-data android:name="JPUSH_APPKEY" android:value="您的Appkey"/><!-- </>值來自開發者平台取得的AppKey--> </application> </manifest>
3.拷貝相關java代碼。(主要是MyReceiver類,如果不需要對推送的通知進行特殊處理,可以不用拷貝相關java代碼,
在
AndroidManifest文件中也不需要定義自定義Receiver,這時候點擊推送的通知,默認是打開應用
)
在自己項目包名目錄下建立一個jpush包名:將demo的src目錄下的所有java代碼拷貝到jpush包目錄下。這樣整體拷貝,不用更改包名,比較方便。這里我需要是關注MyReceiver中的代碼,這個是核心,這個是極光廣播的監聽,通過這個類可以針對推送的消息進行處理,比如實現點擊消息通知跳轉到特定的界面等功能。

4.拷貝res目錄下的資源文件到自己的項目中。
將demo目錄下res下所有的res資源文件與自己的項目資源文件進行合並。
5.在自己項目進行jpush初始化,別名,tag等設置。
在登錄Activity或歡迎Activity等合適的Activity中進行JPush初始化以及別名,或tag設置。
這里將這些代碼統一寫一個管理類,以便在以后的項目中使用。
-
package com.centrvideo.parkapp.jpush; import java.io.Serializable; import java.util.HashSet; import java.util.Set; import android.content.Context; import android.os.Handler; import android.text.TextUtils; import android.util.Log; import android.widget.Toast; import cn.jpush.android.api.JPushInterface; import cn.jpush.android.api.TagAliasCallback; import com.centrvideo.parkapp.util.SharedPreferenceUtil; /** * 極光推送封裝,極光管理類 * @ClassName: JPushManager * @Description: * @author xiaoxiao * @date modify by 2015-9-2 上午11:12:10 * */ public class JPushManager { private String TAG = "JPushManager"; private final String KEY = "JpushConfig"; private static JPushManager jPushManager; private static Context context; public static JPushManager newInstence(Context context) { JPushManager.context = context; if (jPushManager == null) { jPushManager = new JPushManager(); } return jPushManager; } /** * 初始化極光,一般可以放到程序的啟動Activity或是Application的onCreate方法中調用 */ public void initJPush() { JPushInterface.setDebugMode(true); // 設置開啟日志,發布時請關閉日志 JPushInterface.init(context); // 初始化 JPush } /** * 退出極光,一般是程序退出登錄時候,具體還是需要看項目的實際需求 */ public void stopJPush() { // JPushInterface.stopPush(context);// setAliasAndTags("","");//通過清空別名來停止極光 } /** * 設置AliasAndTag,設置多組tag,如果不需要設置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 來異步設置別名 // TODO Auto-generated method stub AliasAndTagsInfo aliasAndTagsInfo = new AliasAndTagsInfo(); aliasAndTagsInfo.setAlias(alias); aliasAndTagsInfo.setTag(tags); mHandler.sendMessage(mHandler.obtainMessage(MSG_SET_ALIAS, aliasAndTagsInfo)); } /** * 設置AliasAndTag,設置一組tag,如果不需要設置tag的化,直接將此參數設為null; * @param alias * @param tags */ public void setAliasAndTags(final String alias, String tag) { if (TextUtils.isEmpty(alias)) { Toast.makeText(context, "別名為空", Toast.LENGTH_SHORT).show(); return; } // 調用 Handler 來異步設置別名 // TODO Auto-generated method stub 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 里寫一個成功設置的狀態。成功設置一次后,以后不必再次設置了。 saveAlias(alias); 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); } } }; /** * 保存別名到屬性文件。 * * @param alias */ private void saveAlias(String alias) { SharedPreferenceUtil.saveString(context, KEY, alias); } /** * 從屬性文件取得別名 * * @param userName * @return */ private String getAlias(String userName) { return SharedPreferenceUtil.getString(context, KEY, null); } 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."); // 調用 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; } } }
附件列表