634 lines
23 KiB
Java
Raw Normal View History

2013-10-18 11:14:33 +08:00
package cn.jpush.phonegap;
import android.annotation.TargetApi;
2016-03-12 16:50:51 +08:00
import android.app.Activity;
import android.app.AppOpsManager;
2016-03-12 22:46:59 +08:00
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.os.Build;
2016-04-20 12:50:26 +08:00
import android.text.TextUtils;
2016-03-12 16:50:51 +08:00
import android.util.Log;
2016-03-04 15:36:07 +08:00
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
2016-03-12 16:50:51 +08:00
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
2016-04-17 18:11:43 +08:00
import java.util.Iterator;
2016-03-12 16:50:51 +08:00
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
2016-03-04 15:36:07 +08:00
2013-10-18 11:14:33 +08:00
import cn.jpush.android.api.BasicPushNotificationBuilder;
import cn.jpush.android.api.JPushInterface;
2016-03-04 15:36:07 +08:00
import cn.jpush.android.api.TagAliasCallback;
2016-03-12 16:50:51 +08:00
import cn.jpush.android.data.JPushLocalNotification;
2013-10-18 11:14:33 +08:00
public class JPushPlugin extends CordovaPlugin {
private final static List<String> methodList =
Arrays.asList(
2016-04-20 12:50:26 +08:00
"addLocalNotification",
2016-07-12 13:34:08 +08:00
"areNotificationEnabled",
2016-04-20 12:50:26 +08:00
"clearAllNotification",
"clearLocalNotifications",
"clearNotificationById",
"getNotification",
"getRegistrationID",
"init",
"isPushStopped",
"onPause",
"onResume",
"requestPermission",
"removeLocalNotification",
"reportNotificationOpened",
"resumePush",
"setAlias",
"setBasicPushNotificationBuilder",
"setCustomPushNotificationBuilder",
"setDebugMode",
"setLatestNotificationNum",
"setPushTime",
"setTags",
"setTagsWithAlias",
"setSilenceTime",
"setStatisticsOpen",
"stopPush"
);
private ExecutorService threadPool = Executors.newFixedThreadPool(1);
private static JPushPlugin instance;
2016-03-10 13:44:24 +08:00
private static Activity cordovaActivity;
2015-12-11 00:34:55 +08:00
private static String TAG = "JPushPlugin";
private static boolean shouldCacheMsg = false;
private static boolean isStatisticsOpened = false; // 是否开启统计分析功能
2013-10-18 11:14:33 +08:00
public static String notificationTitle;
public static String notificationAlert;
public static Map<String, Object> notificationExtras = new HashMap<String, Object>();
public static String openNotificationTitle;
public static String openNotificationAlert;
public static Map<String, Object> openNotificationExtras = new HashMap<String, Object>();
2013-10-18 11:14:33 +08:00
public JPushPlugin() {
instance = this;
}
2015-12-11 00:34:55 +08:00
@Override
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
2016-09-19 10:17:56 +08:00
Log.i(TAG, "JPush initialize.");
2013-10-18 11:14:33 +08:00
2016-09-19 10:17:56 +08:00
super.initialize(cordova, webView);
JPushInterface.init(cordova.getActivity().getApplicationContext());
2015-12-11 00:34:55 +08:00
2016-04-20 12:50:26 +08:00
cordovaActivity = cordova.getActivity();
2015-12-11 00:34:55 +08:00
//如果同时缓存了打开事件 openNotificationAlert 和 消息事件 notificationAlert只向 UI 发打开事件。
//这样做是为了和 iOS 统一。
if (openNotificationAlert != null) {
notificationAlert = null;
transmitNotificationOpen(openNotificationTitle, openNotificationAlert,
2016-04-20 12:50:26 +08:00
openNotificationExtras);
}
if (notificationAlert != null) {
transmitNotificationReceive(notificationTitle, notificationAlert,
2016-04-20 12:50:26 +08:00
notificationExtras);
}
}
public void onPause(boolean multitasking) {
Log.i(TAG, "---------------- onPause");
shouldCacheMsg = true;
2016-03-22 23:39:42 +08:00
if (isStatisticsOpened && multitasking) {
2016-04-20 12:50:26 +08:00
JPushInterface.onPause(this.cordova.getActivity());
}
}
2015-12-11 00:34:55 +08:00
public void onResume(boolean multitasking) {
shouldCacheMsg = false;
Log.i(TAG, "---------------- onResume" + "-" + openNotificationAlert
2016-04-20 12:50:26 +08:00
+ "-" + notificationAlert);
2016-03-22 23:39:42 +08:00
if (isStatisticsOpened && multitasking) {
2016-04-20 12:50:26 +08:00
JPushInterface.onResume(this.cordova.getActivity());
}
if (openNotificationAlert != null) {
notificationAlert = null;
transmitNotificationOpen(openNotificationTitle, openNotificationAlert,
2016-04-20 12:50:26 +08:00
openNotificationExtras);
}
if (notificationAlert != null) {
transmitNotificationReceive(notificationTitle, notificationAlert,
2016-04-20 12:50:26 +08:00
notificationExtras);
}
}
@Override
public void onDestroy() {
super.onDestroy();
cordovaActivity = null;
instance = null;
}
private static JSONObject getMessageObject(String message,
Map<String, Object> extras) {
JSONObject data = new JSONObject();
try {
data.put("message", message);
JSONObject jExtras = new JSONObject();
for (Entry<String, Object> entry : extras.entrySet()) {
if (entry.getKey().equals("cn.jpush.android.EXTRA")) {
2016-04-20 12:50:26 +08:00
JSONObject jo = null;
if (TextUtils.isEmpty((String) entry.getValue())) {
jo = new JSONObject();
} else {
jo = new JSONObject((String) entry.getValue());
String key;
Iterator keys = jo.keys();
while (keys.hasNext()) {
key = keys.next().toString();
jExtras.put(key, jo.getString(key));
}
}
jExtras.put("cn.jpush.android.EXTRA", jo);
} else {
jExtras.put(entry.getKey(), entry.getValue());
}
2015-12-09 17:55:10 +08:00
}
if (jExtras.length() > 0) {
data.put("extras", jExtras);
2015-12-09 17:55:10 +08:00
}
} catch (JSONException e) {
e.printStackTrace();
}
return data;
}
private static JSONObject getNotificationObject(String title,
String alert, Map<String, Object> extras) {
JSONObject data = new JSONObject();
try {
data.put("title", title);
data.put("alert", alert);
JSONObject jExtras = new JSONObject();
for (Entry<String, Object> entry : extras.entrySet()) {
if (entry.getKey().equals("cn.jpush.android.EXTRA")) {
JSONObject jo;
2016-04-20 12:50:26 +08:00
if (TextUtils.isEmpty((String) entry.getValue())) {
jo = new JSONObject();
} else {
jo = new JSONObject((String) entry.getValue());
String key;
Iterator keys = jo.keys();
while (keys.hasNext()) {
key = keys.next().toString();
jExtras.put(key, jo.getString(key));
}
}
jExtras.put("cn.jpush.android.EXTRA", jo);
} else {
jExtras.put(entry.getKey(), entry.getValue());
}
}
if (jExtras.length() > 0) {
data.put("extras", jExtras);
}
} catch (JSONException e) {
e.printStackTrace();
}
return data;
}
static void transmitMessageReceive(String message, Map<String, Object> extras) {
if (instance == null) {
return;
}
JSONObject data = getMessageObject(message, extras);
2016-03-15 11:06:09 +08:00
String format = "window.plugins.jPushPlugin.receiveMessageInAndroidCallback(%s);";
2016-03-10 13:44:24 +08:00
final String js = String.format(format, data.toString());
cordovaActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
instance.webView.loadUrl("javascript:" + js);
}
});
}
2015-12-11 00:34:55 +08:00
static void transmitNotificationOpen(String title, String alert,
Map<String, Object> extras) {
if (instance == null) {
return;
}
JSONObject data = getNotificationObject(title, alert, extras);
2016-03-15 11:06:09 +08:00
String format = "window.plugins.jPushPlugin.openNotificationInAndroidCallback(%s);";
2016-03-10 13:44:24 +08:00
final String js = String.format(format, data.toString());
cordovaActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
instance.webView.loadUrl("javascript:" + js);
}
});
JPushPlugin.openNotificationTitle = null;
JPushPlugin.openNotificationAlert = null;
}
static void transmitNotificationReceive(String title, String alert,
Map<String, Object> extras) {
if (instance == null) {
return;
}
JSONObject data = getNotificationObject(title, alert, extras);
2016-03-15 11:06:09 +08:00
String format = "window.plugins.jPushPlugin.receiveNotificationInAndroidCallback(%s);";
2016-03-10 13:44:24 +08:00
final String js = String.format(format, data.toString());
cordovaActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
instance.webView.loadUrl("javascript:" + js);
}
});
JPushPlugin.notificationTitle = null;
JPushPlugin.notificationAlert = null;
}
@Override
public boolean execute(final String action, final JSONArray data,
final CallbackContext callbackContext) throws JSONException {
if (!methodList.contains(action)) {
return false;
}
threadPool.execute(new Runnable() {
@Override
public void run() {
try {
Method method = JPushPlugin.class.getDeclaredMethod(action,
JSONArray.class, CallbackContext.class);
method.invoke(JPushPlugin.this, data, callbackContext);
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}
});
return true;
}
void init(JSONArray data, CallbackContext callbackContext) {
2016-04-20 12:50:26 +08:00
JPushInterface.init(this.cordova.getActivity().getApplicationContext());
}
void setDebugMode(JSONArray data, CallbackContext callbackContext) {
boolean mode;
try {
mode = data.getBoolean(0);
JPushInterface.setDebugMode(mode);
callbackContext.success();
} catch (JSONException e) {
e.printStackTrace();
}
}
void stopPush(JSONArray data, CallbackContext callbackContext) {
2016-04-20 12:50:26 +08:00
JPushInterface.stopPush(this.cordova.getActivity().getApplicationContext());
callbackContext.success();
}
void resumePush(JSONArray data, CallbackContext callbackContext) {
2016-04-20 12:50:26 +08:00
JPushInterface.resumePush(this.cordova.getActivity().getApplicationContext());
callbackContext.success();
}
void isPushStopped(JSONArray data, CallbackContext callbackContext) {
boolean isStopped = JPushInterface.isPushStopped(
2016-04-20 12:50:26 +08:00
this.cordova.getActivity().getApplicationContext());
if (isStopped) {
callbackContext.success(1);
} else {
callbackContext.success(0);
}
}
2016-07-12 13:34:08 +08:00
void areNotificationEnabled(JSONArray data, final CallbackContext callback) {
int isEnabled;
if (hasPermission("OP_POST_NOTIFICATION")) {
2016-07-12 13:34:08 +08:00
isEnabled = 1;
} else {
isEnabled = 0;
2016-07-12 13:34:08 +08:00
}
callback.success(isEnabled);
}
void setLatestNotificationNum(JSONArray data, CallbackContext callbackContext) {
int num = -1;
try {
num = data.getInt(0);
} catch (JSONException e) {
e.printStackTrace();
callbackContext.error("error reading num json");
}
if (num != -1) {
JPushInterface.setLatestNotificationNumber(
2016-04-20 12:50:26 +08:00
this.cordova.getActivity().getApplicationContext(), num);
} else {
callbackContext.error("error num");
}
}
void setPushTime(JSONArray data, CallbackContext callbackContext) {
2016-04-20 12:50:26 +08:00
Set<Integer> days = new HashSet<Integer>();
JSONArray dayArray;
int startHour = -1;
int endHour = -1;
try {
2016-04-20 12:50:26 +08:00
dayArray = data.getJSONArray(0);
for (int i = 0; i < dayArray.length(); i++) {
days.add(dayArray.getInt(i));
}
2016-04-20 12:50:26 +08:00
} catch (JSONException e) {
e.printStackTrace();
callbackContext.error("error reading days json");
}
try {
startHour = data.getInt(1);
endHour = data.getInt(2);
} catch (JSONException e) {
2016-04-20 12:50:26 +08:00
callbackContext.error("error reading hour json");
}
2016-04-20 12:50:26 +08:00
Context context = this.cordova.getActivity().getApplicationContext();
JPushInterface.setPushTime(context, days, startHour, endHour);
callbackContext.success();
}
void getRegistrationID(JSONArray data, CallbackContext callbackContext) {
2016-04-20 12:50:26 +08:00
Context context = this.cordova.getActivity().getApplicationContext();
String regID = JPushInterface.getRegistrationID(context);
callbackContext.success(regID);
}
void onResume(JSONArray data, CallbackContext callbackContext) {
2016-04-20 12:50:26 +08:00
JPushInterface.onResume(this.cordova.getActivity());
}
void onPause(JSONArray data, CallbackContext callbackContext) {
2016-04-20 12:50:26 +08:00
JPushInterface.onPause(this.cordova.getActivity());
}
void reportNotificationOpened(JSONArray data, CallbackContext callbackContext) {
try {
String msgID;
msgID = data.getString(0);
2016-04-20 12:50:26 +08:00
JPushInterface.reportNotificationOpened(this.cordova.getActivity(), msgID);
} catch (JSONException e) {
e.printStackTrace();
}
}
void setTags(JSONArray data, CallbackContext callbackContext) {
try {
HashSet<String> tags = new HashSet<String>();
for (int i = 0; i < data.length(); i++) {
tags.add(data.getString(i));
}
2016-04-20 12:50:26 +08:00
JPushInterface.setTags(this.cordova.getActivity().getApplicationContext(),
tags, mTagWithAliasCallback);
callbackContext.success();
} catch (JSONException e) {
e.printStackTrace();
callbackContext.error("Error reading tags JSON");
}
}
void setAlias(JSONArray data, CallbackContext callbackContext) {
try {
String alias = data.getString(0);
2016-04-20 12:50:26 +08:00
JPushInterface.setAlias(this.cordova.getActivity().getApplicationContext(),
alias, mTagWithAliasCallback);
callbackContext.success();
} catch (JSONException e) {
e.printStackTrace();
callbackContext.error("Error reading alias JSON");
}
}
void setTagsWithAlias(JSONArray data, CallbackContext callbackContext) {
HashSet<String> tags = new HashSet<String>();
String alias;
try {
alias = data.getString(0);
JSONArray tagsArray = data.getJSONArray(1);
for (int i = 0; i < tagsArray.length(); i++) {
tags.add(tagsArray.getString(i));
}
2016-04-20 12:50:26 +08:00
JPushInterface.setAliasAndTags(this.cordova.getActivity().getApplicationContext(),
alias, tags, mTagWithAliasCallback);
callbackContext.success();
} catch (JSONException e) {
e.printStackTrace();
callbackContext.error("Error reading tagAlias JSON");
}
}
2013-10-18 11:14:33 +08:00
void setBasicPushNotificationBuilder(JSONArray data,
CallbackContext callbackContext) {
BasicPushNotificationBuilder builder = new BasicPushNotificationBuilder(
2016-04-20 12:50:26 +08:00
this.cordova.getActivity());
builder.developerArg0 = "Basic builder 1";
JPushInterface.setPushNotificationBuilder(1, builder);
JSONObject obj = new JSONObject();
try {
obj.put("id", 1);
} catch (JSONException e) {
e.printStackTrace();
}
}
/**
* 自定义推送通知栏样式需要自己实现具体代码
* http://docs.jiguang.cn/client/android_tutorials/#_11
*/
void setCustomPushNotificationBuilder(JSONArray data,
CallbackContext callbackContext) {
// CustomPushNotificationBuilder builder = new CustomPushNotificationBuilder(
// this.cordova.getActivity(), R.layout.test_notification_layout,
// R.id.icon, R.id.title, R.id.text);
// JPushInterface.setPushNotificationBuilder(2, builder);
// JPushInterface.setDefaultPushNotificationBuilder(builder);
}
void clearAllNotification(JSONArray data, CallbackContext callbackContext) {
2016-04-20 12:50:26 +08:00
JPushInterface.clearAllNotifications(this.cordova.getActivity());
}
void clearNotificationById(JSONArray data, CallbackContext callbackContext) {
int notificationId = -1;
try {
notificationId = data.getInt(0);
} catch (JSONException e) {
e.printStackTrace();
callbackContext.error("error reading id json");
}
if (notificationId != -1) {
2016-04-20 12:50:26 +08:00
JPushInterface.clearNotificationById(this.cordova.getActivity(), notificationId);
} else {
callbackContext.error("error id");
}
}
void addLocalNotification(JSONArray data, CallbackContext callbackContext)
throws JSONException {
int builderId = data.getInt(0);
String content = data.getString(1);
String title = data.getString(2);
int notificationID = data.getInt(3);
int broadcastTime = data.getInt(4);
String extrasStr = data.isNull(5) ? "" : data.getString(5);
JSONObject extras = new JSONObject();
if (!extrasStr.isEmpty()) {
2016-04-20 12:50:26 +08:00
extras = new JSONObject(extrasStr);
}
JPushLocalNotification ln = new JPushLocalNotification();
ln.setBuilderId(builderId);
ln.setContent(content);
ln.setTitle(title);
ln.setNotificationId(notificationID);
ln.setBroadcastTime(System.currentTimeMillis() + broadcastTime);
ln.setExtras(extras.toString());
2016-04-20 12:50:26 +08:00
JPushInterface.addLocalNotification(this.cordova.getActivity(), ln);
}
void removeLocalNotification(JSONArray data, CallbackContext callbackContext)
throws JSONException {
int notificationID = data.getInt(0);
2016-04-20 12:50:26 +08:00
JPushInterface.removeLocalNotification(this.cordova.getActivity(), notificationID);
}
void clearLocalNotifications(JSONArray data, CallbackContext callbackContext) {
2016-04-20 12:50:26 +08:00
JPushInterface.clearLocalNotifications(this.cordova.getActivity());
}
/**
* 决定是否启用统计分析功能
*/
void setStatisticsOpen(JSONArray data, CallbackContext callbackContext) {
try {
isStatisticsOpened = data.getBoolean(0);
} catch (JSONException e) {
e.printStackTrace();
}
}
2014-06-11 11:08:17 +08:00
2016-04-20 12:50:26 +08:00
/**
* 设置通知静默时间
* http://docs.jpush.io/client/android_api/#api_5
*/
void setSilenceTime(JSONArray data, CallbackContext callbackContext) {
try {
int startHour = data.getInt(0);
int startMinute = data.getInt(1);
int endHour = data.getInt(2);
int endMinute = data.getInt(3);
if (!isValidHour(startHour) || !isValidMinute(startMinute)) {
callbackContext.error("开始时间数值错误");
return;
}
if (!isValidHour(endHour) || !isValidMinute(endMinute)) {
callbackContext.error("结束时间数值错误");
return;
}
JPushInterface.setSilenceTime(this.cordova.getActivity(), startHour, startMinute,
endHour, endMinute);
} catch (JSONException e) {
e.printStackTrace();
callbackContext.error("error: reading json data.");
}
}
private boolean isValidHour(int hour) {
return !(hour < 0 || hour > 23);
}
private boolean isValidMinute(int minute) {
return !(minute < 0 || minute > 59);
}
/**
* 用于 Android 6.0 以上系统申请权限具体可参考
* http://docs.Push.io/client/android_api/#android-60
*/
void requestPermission(JSONArray data, CallbackContext callbackContext) {
JPushInterface.requestPermission(this.cordova.getActivity());
}
private final TagAliasCallback mTagWithAliasCallback = new TagAliasCallback() {
2014-06-11 11:08:17 +08:00
@Override
public void gotResult(int code, String alias, Set<String> tags) {
if (instance == null) {
return;
}
JSONObject data = new JSONObject();
try {
data.put("resultCode", code);
data.put("tags", tags);
data.put("alias", alias);
2016-03-15 15:09:40 +08:00
final String jsEvent = String.format(
"cordova.fireDocumentEvent('jpush.setTagsWithAlias',%s)",
data.toString());
2016-04-20 12:50:26 +08:00
cordova.getActivity().runOnUiThread(new Runnable() {
2016-03-15 11:06:09 +08:00
@Override
public void run() {
instance.webView.loadUrl("javascript:" + jsEvent);
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
};
@TargetApi(Build.VERSION_CODES.KITKAT)
private boolean hasPermission(String appOpsServiceId) {
Context context = cordova.getActivity().getApplicationContext();
AppOpsManager mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
ApplicationInfo appInfo = context.getApplicationInfo();
String pkg = context.getPackageName();
int uid = appInfo.uid;
Class appOpsClazz = null;
try {
appOpsClazz = Class.forName(AppOpsManager.class.getName());
Method checkOpNoThrowMethod = appOpsClazz.getMethod("checkOpNoThrow",
Integer.TYPE, Integer.TYPE, String.class);
Field opValue = appOpsClazz.getDeclaredField(appOpsServiceId);
int value = opValue.getInt(Integer.class);
Object result = checkOpNoThrowMethod.invoke(mAppOps, value, uid, pkg);
return Integer.parseInt(result.toString()) == AppOpsManager.MODE_ALLOWED;
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return true;
}
2013-10-18 11:14:33 +08:00
}