原 android進階4step3:Android常用框架——極光推送的簡單使用
- 官方文件:https://www.jiguang.cn/push
- SDK下載:http://docs.jiguang.cn/jpush/resources/
- 官方Github:https://github.com/jpush
這篇文章主要介紹是怎麼使用極光推送
其他文章:
推送是用來幹嘛的?
如圖:
如何即使獲取伺服器上的資訊?
-
定時輪詢:
- 實現簡單
- 時效性不高
- 耗電、耗流量
示意圖:
-
使用推送:
- 實現複雜
- 時效性高
- 省電、省流量
示意圖:
常見的推送方式
- 一、Google提供的C2DM服務
- 二、使用MMQT協議實現android推送功能
- 三、使用XMPP協議實現android推送功能
- 四、第三方平臺
- 極光推送
- 百度雲推送
- 友盟
極光推送的使用方法:
第一步:登入極光推送的官網:https://www.jiguang.cn/
第二步:通過郵箱(儘量不用qq郵箱)註冊登入
第三步:開啟Android Studio 新建一個工程,記住包名,預設點選finish即可
- 我這裡的包名是:com.demo.jpdemo
第四步:登入成功後,進入極光推送的開發者服務頁 這裡是網址:https://www.jiguang.cn/dev/#/app/list#dev
第五步:建立應用
點選應用管理——>建立應用——>輸入應用的名稱(任意)
應用建立成功後:有兩個比較重要的東西 記住
- AppKey:客戶端使用的
- Master Secret :想自己實現伺服器時使用
頁面往下拉,看到推送設定,點選完成推送設定
選擇Android平臺,寫上應用包名! 必須和你的工程的包名一致,然後點選完成即可
第六步:下載極光推送的Android的SDK 這是地址:https://docs.jiguang.cn/jpush/resources/
下載完成後解壓:
目錄結構:
- AndroidManifest.xml
- 客戶端嵌入 SDK 參考的配置檔案
- libs/jcore-android.1.x.x.jar
- 極光開發者服務的核心包。
- libs/jpush-android-3.x.y.jar
- JPush SDK 開發包。
- libs/(cpu-type)/libjcore1xx.so
- 各種 CPU 型別的 native 開發包。
- res
- 整合 SDK 必須新增的資原始檔
- example
- 是一個完整的 Android 專案,通過這個演示了 JPush SDK 的基本用法,可以用來做參考。
第七步:將SDK整合到你的工程當中
可以根據開發文件走:https://docs.jiguang.cn/jpush/client/Android/android_guide/
也可以按照我下面粗暴的方法來:
開啟剛剛新建好的工程,將SDK中對應的libs包裡面所有的檔案拷貝工程的libs裡面
拷貝成功後,選中 jpush-android-3.1.8.jar 右鍵 Add as Library 新增到模組的庫中
實際就是模組的在build.gradle中添加了一行程式碼:
implementation files('libs/jpush-android-3.1.8.jar')
然後:在模組的build.gradle 新增以下一塊程式碼,Sync 同步一下
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.demo.jpushdemo"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
//新增這一塊程式碼:這是新增Jni的庫
sourceSets {
main {
jniLibs.srcDir("libs")
}
}
}
同步完成後,將SDK目錄下的res目錄複製替換工程裡面的res目錄(實際就是將SDK目錄下的檔案新增到工程的res目錄下)
就是極光推送的介面佈局檔案
第八步:配置AndroidManifest.xml檔案
以下是工程原生的AndroidManifest.xml檔案
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.demo.jpdemo">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
以下是SDK裡面的AndroidManifest.xml檔案
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="您應用的包名"
android:versionCode="318"
android:versionName="3.1.8"
>
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="21" />
<!-- 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.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.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- Optional for location -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <!-- 用於開啟 debug 版本的應用在6.0 系統上 層疊視窗許可權 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<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" />
<uses-permission android:name="android.permission.GET_TASKS" />
<application
android:icon="@drawable/ic_launcher"
android:allowBackup="false"
android:label="@string/app_name"
android:name="com.example.jpushdemo.ExampleApplication">
<!-- For test only 測試的主程式-->
<activity
android:name="com.example.jpushdemo.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- For test only 測試高階功能 -->
<activity android:name="com.example.jpushdemo.PushSetActivity" android:label="@string/app_name"></activity>
<!-- For test only 測試設定 -->
<activity android:name="com.example.jpushdemo.SettingActivity" android:label="@string/app_name"></activity>
<!-- For test only 測試狀態通知欄,需要開啟的Activity -->
<activity android:name="com.example.jpushdemo.TestActivity" android:exported="false">
<intent-filter>
<action android:name="jpush.testAction" />
<category android:name="jpush.testCategory" />
</intent-filter>
</activity>
<!-- Rich push 核心功能 since 2.0.6-->
<activity
android:name="cn.jpush.android.ui.PopWinActivity"
android:theme="@style/MyDialogStyle"
android:exported="false">
</activity>
<!-- Required SDK核心功能-->
<activity
android:name="cn.jpush.android.ui.PushActivity"
android:configChanges="orientation|keyboardHidden"
android:theme="@android:style/Theme.NoTitleBar"
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 核心功能-->
<!-- 可配置android:process引數將PushService放在其他程序中 -->
<service
android:name="cn.jpush.android.service.PushService"
android:process=":pushcore"
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>
<!-- since 3.0.9 Required SDK 核心功能-->
<provider
android:authorities="您應用的包名.DataProvider"
android:name="cn.jpush.android.service.DataProvider"
android:process=":pushcore"
android:exported="false"
/>
<!-- since 1.8.0 option 可選項。用於同一裝置中不同應用的JPush服務相互拉起的功能。 -->
<!-- 若不啟用該功能可刪除該元件,將不拉起其他應用也不能被其他應用拉起 -->
<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>
<!-- since 3.1.0 Required SDK 核心功能-->
<provider
android:authorities="您應用的包名.DownloadProvider"
android:name="cn.jpush.android.service.DownloadProvider"
android:exported="true"
/>
<!-- 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" android:exported="false"/>
<!-- User defined. For test only 使用者自定義的廣播接收器-->
<receiver
android:name="com.example.jpushdemo.MyReceiver"
android:exported="false"
android:enabled="true">
<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.CONNECTION" /><!-- 接收網路變化 連線/斷開 since 1.6.3 -->
<category android:name="您應用的包名" />
</intent-filter>
</receiver>
<!-- User defined. For test only 使用者自定義接收訊息器,3.0.7開始支援,目前新tag/alias介面設定結果會在該廣播接收器對應的方法中回撥-->
<receiver android:name="com.example.jpushdemo.MyJPushMessageReceiver">
<intent-filter>
<action android:name="cn.jpush.android.intent.RECEIVE_MESSAGE" />
<category android:name="您應用的包名"></category>
</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>
簡單粗暴的方法,直接將SDK中的AndroidManifest.xml替換原生的檔案
你也可以根據下面的方法來配置
根據 SDK 壓縮包裡的 AndroidManifest.xml 樣例檔案,來配置應用程式專案的 AndroidManifest.xml 。
主要步驟為:
- 複製備註為 "Required" 的部分
- 將標註為“您應用的包名”的部分,替換為當前應用程式的包名
- 將標註為“您應用的 Appkey” 的部分,替換為在 Portal 上建立該應用後應用資訊中的 Appkey,例如:9fed5bcb7b9b87413678c407
小帖士
如果使用 android studio,可在 AndroidManifest 中引用 applicationId 的值,在 build.gradle 配置中 defaultConfig 節點下配置,如:
defaultConfig { applicationId "cn.jpush.example" // <--您應用的包名 …… }
在 AndroidManifest 中使用 ${applicationId} 引用 gradle 中定義的包名
替換好原生的配置檔案後,根據上面的小貼士,在build.gradle中定義好包名方便引用
其實預設是有這個 applicationId的
defaultConfig {
applicationId "com.demo.jpdemo"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
- 將涉及有包名的改成自己的包名
- 刪除一些帶有 only test 標籤的
- 新增之前建立好應用的AppKey
- 建立一個MyApplication.java類 初始化
- 建立一個MyReciver.java 接受發過來的資訊
以下是修改好後的配置檔案:
看我上面寫要修改的註釋 一一比對
<?xml version="1.0" encoding="utf-8"?>
<!--修改:包名1-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.demo.jpdemo"
android:versionCode="318"
android:versionName="3.1.8"
>
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="21" />
<!--修改:包名2-->
<!-- Required -->
<permission
android:name="com.demo.jpdemo.permission.JPUSH_MESSAGE"
android:protectionLevel="signature" />
<!--修改:包名3-->
<!-- Required 一些系統要求的許可權,如訪問網路等-->
<uses-permission android:name="com.demo.jpdemo.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.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.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- Optional for location -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <!-- 用於開啟 debug 版本的應用在6.0 系統上 層疊視窗許可權 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<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" />
<uses-permission android:name="android.permission.GET_TASKS" />
<!--修改:包名4-->
<application
android:icon="@mipmap/ic_launcher"
android:allowBackup="false"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:name="com.demo.jpdemo.MyApplication">
<!--修改:包名5-->
<!-- For test only 測試的主程式-->
<activity
android:name="com.demo.jpdemo.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Rich push 核心功能 since 2.0.6-->
<activity
android:name="cn.jpush.android.ui.PopWinActivity"
android:theme="@style/MyDialogStyle"
android:exported="false">
</activity>
<!-- Required SDK核心功能-->
<activity
android:name="cn.jpush.android.ui.PushActivity"
android:configChanges="orientation|keyboardHidden"
android:theme="@android:style/Theme.NoTitleBar"
android:exported="false">
<!--修改:包名6-->
<intent-filter>
<action android:name="cn.jpush.android.ui.PushActivity" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="${applicationId}" />
</intent-filter>
</activity>
<!-- Required SDK 核心功能-->
<!-- 可配置android:process引數將PushService放在其他程序中 -->
<service
android:name="cn.jpush.android.service.PushService"
android:process=":pushcore"
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>
<!--修改:包名7-->
<!-- since 3.0.9 Required SDK 核心功能-->
<provider
android:authorities="com.demo.jpdemo.DataProvider"
android:name="cn.jpush.android.service.DataProvider"
android:process=":pushcore"
android:exported="false"
/>
<!-- since 1.8.0 option 可選項。用於同一裝置中不同應用的JPush服務相互拉起的功能。 -->
<!-- 若不啟用該功能可刪除該元件,將不拉起其他應用也不能被其他應用拉起 -->
<service
android:name="cn.jpush.android.service.DaemonService"
android:enabled="true"
android:exported="true">
<!--修改:包名8-->
<intent-filter>
<action android:name="cn.jpush.android.intent.DaemonService" />
<category android:name="${applicationId}" />
</intent-filter>
</service>
<!--修改:包名9-->
<!-- since 3.1.0 Required SDK 核心功能-->
<provider
android:authorities="com.demo.jpdemo.DownloadProvider"
android:name="cn.jpush.android.service.DownloadProvider"
android:exported="true"
/>
<!-- Required SDK核心功能-->
<receiver
android:name="cn.jpush.android.service.PushReceiver"
android:enabled="true"
android:exported="false">
<!--修改:包名10-->
<intent-filter android:priority="1000">
<action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY" /> <!--Required 顯示通知欄 -->
<category android:name="${applicationId}" />
</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" android:exported="false"/>
<!--修改:包名11-->
<!-- User defined. For test only 使用者自定義的廣播接收器-->
<receiver
android:name="com.demo.jpdemo.MyReceiver"
android:exported="false"
android:enabled="true">
<!--修改:包名12-->
<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.CONNECTION" /><!-- 接收網路變化 連線/斷開 since 1.6.3 -->
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
<!--修改:新增appkey 13-->
<!-- 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="afeeb844639923ab08554464" /> <!-- </>值來自開發者平臺取得的AppKey-->
</application>
</manifest>
MyApplication.java
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//初始化極光推送
JPushInterface.init(this);
//開啟除錯的模式
JPushInterface.setDebugMode(true);
}
}
MyReceiver.java
public class MyReceiver extends BroadcastReceiver {
private static final String TAG = "JPUSH---";
//在onReceive中接收發過來的訊息
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//列印當前action
Log.e(TAG, "onReceive:" + action);
Bundle extras = intent.getExtras();
//如果是發通知的action
if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(action)) {
//通知的內容
String alert = extras.getString(JPushInterface.EXTRA_ALERT);
//通知標題
String title = extras.getString(JPushInterface.EXTRA_NOTIFICATION_TITLE);
Log.e(TAG, "onReceive" + ":通知的內容為:" + alert + ",通知的標題為:" + title);
}
//如果是自定義訊息的action
else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(action)) {
//自定義訊息,沒有通知欄
String msg = extras.getString(JPushInterface.EXTRA_MESSAGE);
Log.e(TAG, "onReceive" + ":自定義訊息為:" + msg);
}
//如果是用點選了通知的action 開啟當前activity
else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(action)) {
//如果是點選通知欄的動作
//點選後跳轉
Intent intent1 = new Intent(context, MainActivity.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent1);
}
}
}
看logcat:
如果出現錯誤:看Logcat的提示:https://docs.jiguang.cn/jpush/client/Android/android_faq/ 看官方問題
檢查包名是否和註冊的一致,還有配置檔案的所有都填寫正確,一般都是填寫錯誤, 或者哪裡忘記了新增
顯示註冊,並且連結上了(證明成功啦)
/com.demo.jpdemo E/JPUSH---: onReceive:cn.jpush.android.intent.REGISTRATION
/com.demo.jpdemo E/JPUSH---: onReceive:cn.jpush.android.intent.CONNECTION
現在傳送一條訊息:
點選之前建立好的應用:推送
點擊發送通知:輸入推送的內容
往下拉,選擇目標的平臺,立即傳送
效果:
此時LogCat的顯示為
先收到通知,然後走開啟通知
/com.demo.jpdemo E/JPUSH---: onReceive:cn.jpush.android.intent.NOTIFICATION_RECEIVED
/com.demo.jpdemo E/JPUSH---: onReceive:通知的內容為:我是第一條推送,通知的標題為:JPDemo
/com.demo.jpdemo E/JPUSH---: onReceive:cn.jpush.android.intent.NOTIFICATION_OPENED
完成了。
實現更多的內容,請可以參考官方整合文件進行學習
https://docs.jiguang.cn/jpush/client/Android/android_guide/
更多的API參考: