文档
说明 1:若没有 res/drawable-xxxx/jpush_notification_icon 这个资源默认使用应用图标作为通知 icon,在 5.0 以上系统将应用图标作为 statusbar icon 可能显示不正常,用户可定义没有阴影和渐变色的 icon 替换这个文件,文件名不要变。
说明 2:使用 android studio 的开发者,如果使用 jniLibs 文件夹导入 so 文件,则仅需将所有 cpu 类型的文件夹拷进去;如果将 so 文件添加在 module的libs 文件夹下,注意在 module 的 gradle 配置中添加一下配置:
android {
......
sourceSets {
main {
jniLibs.srcDirs = ['libs']
......
}
......
}
......
}
根据 SDK 压缩包里的 AndroidManifest.xml 样例文件,来配置应用程序项目的 AndroidManifest.xml 。
主要步骤为:
复制备注为 "Required" 的部分
将标注为“您应用的包名”的部分,替换为当前应用程序的包名
将标注为“您应用的 Appkey” 的部分,替换为在 Portal 上创建该应用后应用信息中的 Appkey,例如:9fed5bcb7b9b87413678c407
defaultConfig {
applicationId "cn.jpush.example" // <--您应用的包名
……
}
在 AndroidManifest 中使用 ${applicationId} 引用 gradle 中定义的包名
AndroidManifest 示例
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="您应用的包名"
android:versionCode="316"
android:versionName="3.1.6"
>
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="23" />
<!-- 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.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- Optional. Required for location feature -->
<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" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:name="Your Application Name">
<!-- Required SDK 核心功能-->
<!-- 可配置 android:process 参数将 PushService 放在其他进程中 -->
<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>
<!-- since 3.0.9 Required SDK 核心功能-->
<provider
android:authorities="您应用的包名.DataProvider"
android:name="cn.jpush.android.service.DataProvider"
android:exported="true"
/>
<!-- since 1.8.0 option 可选项。用于同一设备中不同应用的 JPush 服务相互拉起的功能。 -->
<!-- 若不启用该功能可删除该组件,或把 enabled 设置成 false ;App 不会被其他 App 拉起,但会拉起其他的 App。 -->
<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" >
<intent-filter android:priority="1000">
<action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY" />
<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 核心功能-->
<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>
<!-- SDK 核心功能-->
<activity
android:name="cn.jpush.android.ui.PopWinActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:theme="@style/MyDialogStyle">
<intent-filter>
<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 核心功能-->
<receiver android:name="cn.jpush.android.service.AlarmReceiver" />
<!-- Required since 3.0.7 -->
<!-- 新的 tag/alias 接口结果返回需要开发者配置一个自定的广播 -->
<!-- 该广播需要继承 JPush 提供的 JPushMessageReceiver 类, 并如下新增一个 Intent-Filter -->
<receiver
android:name="自定义 Receiver"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="cn.jpush.android.intent.RECEIVE_MESSAGE" />
<category android:name="您应用的包名" />
</intent-filter>
</receiver>
<!-- User defined. 用户自定义的广播接收器-->
<receiver
android:name="您自己定义的 Receiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<!--Required 用户注册 SDK 的 intent-->
<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 用户打开自定义通知栏的 intent-->
<action android:name="cn.jpush.android.intent.NOTIFICATION_OPENED" />
<!-- 接收网络变化 连接/断开 since 1.6.3 -->
<action android:name="cn.jpush.android.intent.CONNECTION" />
<category android:name="您应用的包名" />
</intent-filter>
</receiver>
<!-- User defined. 用户自定义 Receiver 接收被拉起回调-->
<!-- 自定义 Receiver 组件,继承cn.jpush.android.service.WakedResultReceiver类,复写onWake(int wakeType)或 onWake(Context context, int wakeType)方法以监听被拉起 -->
<receiver android:name="xx.xx.xx.MyWakedResultReceiver">
<intent-filter>
<action android:name="cn.jpush.android.intent.WakedReceiver" />
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
<!-- Required. For publish channel feature -->
<!-- JPUSH_CHANNEL 是为了方便开发者统计 APK 分发渠道。-->
<!-- 例如: -->
<!-- 发到 Google Play 的 APK 可以设置为 google-play; -->
<!-- 发到其他市场的 APK 可以设置为 xxx-market。 -->
<meta-data android:name="JPUSH_CHANNEL" android:value="developer-default"/>
<!-- Required. AppKey copied from Portal -->
<meta-data android:name="JPUSH_APPKEY" android:value="您应用的 Appkey"/>
</application>
</manifest>
代码
public class BaseApp extends Application {
@Override
public void onCreate() {
super.onCreate();
JPushInterface.setDebugMode(true);
JPushInterface.init(this);
}
}
public class CustomReceiver extends BroadcastReceiver {
private static final String TAG = "MyReceiver";
private NotificationManager nm;
@Override
public void onReceive(Context context, Intent intent) {
//用户自定义的广播接收器
if (null == nm) {
nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
Bundle bundle = intent.getExtras();
Log.d(TAG, "[MyReceiver] onReceive - " + intent.getAction() + ", extras: " + printBundle(bundle));
if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {
Log.d(TAG, "JPush 用户注册成功");
} else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {
Log.d(TAG, "接受到推送下来的自定义消息");
sendNotification(context,bundle.getString(JPushInterface.EXTRA_MESSAGE));
} else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {
Log.d(TAG, "接受到推送下来的通知");
} else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {
Log.d(TAG, "用户点击打开了通知");
} else {
Log.d(TAG, "Unhandled intent - " + intent.getAction());
}
}
private void sendNotification(Context context, String msg) {
//data是1,跳转Activity展示美女
//如果是2,点击跳转到主页
String data = "";
String message = "";
String url = "";
try {
JSONObject extrasJson = new JSONObject(msg);
data = extrasJson.optString("data");
message = extrasJson.optString("msg");
url = extrasJson.optString("url");
} catch (Exception e) {
Log.w(TAG, "Unexpected: extras is not a valid json", e);
return;
}
//发送自己的通知
String channelId = "me";
CharSequence channelName = "msg";
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT);
nm.createNotificationChannel(channel);
}
Intent intent;
//data是1,跳转Activity展示美女
//如果是2,点击跳转到主页
if ("1".equals(data)) {
intent = new Intent(context, MeiNvActivity.class);
} else{
intent = new Intent(context, MainActivity.class);
}
intent.putExtra("url",url);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//延时意图
PendingIntent pendingIntent = PendingIntent.getActivity(context,100,
intent,PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.mipmap.ic_launcher)//小图标,必要
.setContentText(message)//消息内容,必要
.setContentTitle(message)//通知标题,必要
.setContentIntent(pendingIntent)//延时意图
.setAutoCancel(true)//点击消失,和延时意图配合使用
.build();
nm.notify(1,notification);
}
// 打印所有的 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.i(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("key:" + key + ", value:" + bundle.getString(key));
}
}
return sb.toString();
}
}
···
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initPer();
}
private void initPer() {
String[] strings = {Manifest.permission.READ_PHONE_STATE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
};
ActivityCompat.requestPermissions(this,strings,100);
}
}
···
···
public class MeiNvActivity extends AppCompatActivity {
private ImageView mIv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mei_nv);
initView();
String url = getIntent().getStringExtra("url");
RequestOptions options = new RequestOptions()
.placeholder(R.mipmap.ic_launcher).circleCrop();
Glide.with(this).load(url).apply(options).into(mIv);
}
private void initView() {
mIv = (ImageView) findViewById(R.id.iv);
}
}
···
5·.
public class MyReceiver extends JPushMessageReceiver {
}
public class WakeReceiver extends WakedResultReceiver {
@Override
public void onWake(int i) {
super.onWake(i);
}
}