From 2978e13c3cc2c9e54257ffcb55c5730347eb8b1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BF=9C=E6=96=B9=E5=A4=95=E9=98=B3?= Date: Wed, 10 Jul 2019 17:46:08 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84android=20SDK=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cim/sdk/android/CIMCacheManager.java | 1 - .../android/CIMEventBroadcastReceiver.java | 18 ++- .../cim/sdk/android/CIMPushManager.java | 103 +++++++----------- .../cim/sdk/android/CIMPushService.java | 70 ++++++------ .../app/libs/cim-android-sdk-3.7.0.jar | Bin 94767 -> 94781 bytes 5 files changed, 92 insertions(+), 100 deletions(-) diff --git a/cim-client-sdk/cim-android-sdk/src/com/farsunset/cim/sdk/android/CIMCacheManager.java b/cim-client-sdk/cim-android-sdk/src/com/farsunset/cim/sdk/android/CIMCacheManager.java index fd4db09..fb895d8 100644 --- a/cim-client-sdk/cim-android-sdk/src/com/farsunset/cim/sdk/android/CIMCacheManager.java +++ b/cim-client-sdk/cim-android-sdk/src/com/farsunset/cim/sdk/android/CIMCacheManager.java @@ -69,7 +69,6 @@ class CIMCacheManager { Cursor cursor = resolver.query(Uri.parse(String.format(CONTENT_URI,context.getPackageName())), new String[] { key }, null, null, null); if (cursor != null && cursor.moveToFirst()) { value = cursor.getString(0); - cursor.close(); } closeQuietly(cursor); return value; diff --git a/cim-client-sdk/cim-android-sdk/src/com/farsunset/cim/sdk/android/CIMEventBroadcastReceiver.java b/cim-client-sdk/cim-android-sdk/src/com/farsunset/cim/sdk/android/CIMEventBroadcastReceiver.java index 427dbcd..111a267 100644 --- a/cim-client-sdk/cim-android-sdk/src/com/farsunset/cim/sdk/android/CIMEventBroadcastReceiver.java +++ b/cim-client-sdk/cim-android-sdk/src/com/farsunset/cim/sdk/android/CIMEventBroadcastReceiver.java @@ -111,7 +111,7 @@ public abstract class CIMEventBroadcastReceiver extends BroadcastReceiver { * 重新连接,如果断开的话 */ if (intent.getAction().equals(CIMConstant.IntentAction.ACTION_CONNECTION_RECOVERY)) { - CIMPushManager.connect(context, 0); + connect(0); } } @@ -132,7 +132,7 @@ public abstract class CIMEventBroadcastReceiver extends BroadcastReceiver { CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE, false); if (CIMPushManager.isNetworkConnected(context)) { - CIMPushManager.connect(context, 0); + connect(0); } onConnectionClosed(); @@ -141,9 +141,10 @@ public abstract class CIMEventBroadcastReceiver extends BroadcastReceiver { private void onConnectionFailed(long reinterval) { if (CIMPushManager.isNetworkConnected(context)) { + onConnectionFailed(); - - CIMPushManager.connect(context, reinterval); + + connect(reinterval); } } @@ -157,11 +158,18 @@ public abstract class CIMEventBroadcastReceiver extends BroadcastReceiver { private void onDevicesNetworkChanged() { if (CIMPushManager.isNetworkConnected(context)) { - CIMPushManager.connect(context, 0); + connect(0); } onNetworkChanged(); } + + private void connect(long delay) { + Intent serviceIntent = new Intent(context, CIMPushService.class); + serviceIntent.putExtra(CIMPushService.KEY_DELAYED_TIME, delay); + serviceIntent.setAction(CIMPushManager.ACTION_CREATE_CIM_CONNECTION); + CIMPushManager.startService(context,serviceIntent); + } private void onInnerMessageReceived(com.farsunset.cim.sdk.android.model.Message message, Intent intent) { if (isForceOfflineMessage(message.getAction())) { diff --git a/cim-client-sdk/cim-android-sdk/src/com/farsunset/cim/sdk/android/CIMPushManager.java b/cim-client-sdk/cim-android-sdk/src/com/farsunset/cim/sdk/android/CIMPushManager.java index 3296a1d..74d8167 100644 --- a/cim-client-sdk/cim-android-sdk/src/com/farsunset/cim/sdk/android/CIMPushManager.java +++ b/cim-client-sdk/cim-android-sdk/src/com/farsunset/cim/sdk/android/CIMPushManager.java @@ -41,19 +41,19 @@ import com.farsunset.cim.sdk.android.model.SentBody; */ public class CIMPushManager { - static String ACTION_ACTIVATE_PUSH_SERVICE = "ACTION_ACTIVATE_PUSH_SERVICE"; + protected static String ACTION_ACTIVATE_PUSH_SERVICE = "ACTION_ACTIVATE_PUSH_SERVICE"; - static String ACTION_CREATE_CIM_CONNECTION = "ACTION_CREATE_CIM_CONNECTION"; + protected static String ACTION_CREATE_CIM_CONNECTION = "ACTION_CREATE_CIM_CONNECTION"; - static String ACTION_SEND_REQUEST_BODY = "ACTION_SEND_REQUEST_BODY"; + protected static String ACTION_SEND_REQUEST_BODY = "ACTION_SEND_REQUEST_BODY"; - static String ACTION_CLOSE_CIM_CONNECTION = "ACTION_CLOSE_CIM_CONNECTION"; + protected static String ACTION_CLOSE_CIM_CONNECTION = "ACTION_CLOSE_CIM_CONNECTION"; - static String ACTION_SET_LOGGER_EANABLE = "ACTION_SET_LOGGER_EANABLE"; + protected static String ACTION_SET_LOGGER_EANABLE = "ACTION_SET_LOGGER_EANABLE"; - static String KEY_SEND_BODY = "KEY_SEND_BODY"; + protected static String KEY_SEND_BODY = "KEY_SEND_BODY"; - static String KEY_CIM_CONNECTION_STATUS = "KEY_CIM_CONNECTION_STATUS"; + protected static String KEY_CIM_CONNECTION_STATUS = "KEY_CIM_CONNECTION_STATUS"; /** * 初始化,连接服务端,在程序启动页或者 在Application里调用 @@ -64,57 +64,34 @@ public class CIMPushManager { */ public static void connect(Context context, String host, int port) { - connect(context, host, port, false, 0); - - } - - private static void connect(Context context, String host, int port, boolean autoBind, long delayedTime) { - if(TextUtils.isEmpty(host) || port == 0) { CIMLogger.getLogger().invalidHostPort(host, port); return; } - CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED, false); - CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_MANUAL_STOP, false); CIMCacheManager.putString(context, CIMCacheManager.KEY_CIM_SERVIER_HOST, host); CIMCacheManager.putInt(context, CIMCacheManager.KEY_CIM_SERVIER_PORT, port); - - if (!autoBind) { - CIMCacheManager.remove(context, CIMCacheManager.KEY_ACCOUNT); - } + + CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED, false); + CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_MANUAL_STOP, false); + + CIMCacheManager.remove(context, CIMCacheManager.KEY_ACCOUNT); + Intent serviceIntent = new Intent(context, CIMPushService.class); - serviceIntent.putExtra(CIMCacheManager.KEY_CIM_SERVIER_HOST, host); - serviceIntent.putExtra(CIMCacheManager.KEY_CIM_SERVIER_PORT, port); - serviceIntent.putExtra(CIMPushService.KEY_DELAYED_TIME, delayedTime); serviceIntent.setAction(ACTION_CREATE_CIM_CONNECTION); - startServiceCompat(context,serviceIntent); + startService(context,serviceIntent); + } public static void setLoggerEnable(Context context,boolean enable) { Intent serviceIntent = new Intent(context, CIMPushService.class); serviceIntent.putExtra(CIMPushService.KEY_LOGGER_ENABLE, enable); serviceIntent.setAction(ACTION_SET_LOGGER_EANABLE); - startServiceCompat(context,serviceIntent); + startService(context,serviceIntent); } - protected static void connect(Context context, long delayedTime) { - - boolean isManualStop = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_MANUAL_STOP); - boolean isManualDestory = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED); - - if (isManualStop || isManualDestory) { - return; - } - - String host = CIMCacheManager.getString(context, CIMCacheManager.KEY_CIM_SERVIER_HOST); - int port = CIMCacheManager.getInt(context, CIMCacheManager.KEY_CIM_SERVIER_PORT); - - connect(context, host, port, true, delayedTime); - - } /** * 设置一个账号登录到服务端 @@ -124,8 +101,7 @@ public class CIMPushManager { */ public static void bindAccount(Context context, String account) { - boolean isManualDestory = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED); - if (isManualDestory || account == null || account.trim().length() == 0) { + if (isDestoryed(context) || account == null || account.trim().length() == 0) { return; } @@ -159,8 +135,7 @@ public class CIMPushManager { protected static boolean autoBindAccount(Context context) { String account = CIMCacheManager.getString(context, CIMCacheManager.KEY_ACCOUNT); - boolean isManualDestory = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED); - if (account == null || account.trim().length() == 0 || isManualDestory) { + if (account == null || account.trim().length() == 0 || isDestoryed(context)) { return false; } @@ -177,17 +152,14 @@ public class CIMPushManager { */ public static void sendRequest(Context context, SentBody body) { - boolean isManualStop = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_MANUAL_STOP); - boolean isManualDestory = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED); - - if (isManualStop || isManualDestory) { + if (isDestoryed(context) || isStoped(context)) { return; } Intent serviceIntent = new Intent(context, CIMPushService.class); serviceIntent.putExtra(KEY_SEND_BODY, body); serviceIntent.setAction(ACTION_SEND_REQUEST_BODY); - startServiceCompat(context,serviceIntent); + startService(context,serviceIntent); } @@ -198,8 +170,7 @@ public class CIMPushManager { */ public static void stop(Context context) { - boolean isManualDestory = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED); - if (isManualDestory) { + if (isDestoryed(context)) { return; } @@ -207,7 +178,7 @@ public class CIMPushManager { Intent serviceIntent = new Intent(context, CIMPushService.class); serviceIntent.setAction(ACTION_CLOSE_CIM_CONNECTION); - startServiceCompat(context,serviceIntent); + startService(context,serviceIntent); } @@ -232,14 +203,21 @@ public class CIMPushManager { */ public static void resume(Context context) { - boolean isManualDestory = CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED); - if (isManualDestory) { + if (isDestoryed(context)) { return; } autoBindAccount(context); } + public static boolean isDestoryed(Context context) { + return CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED); + } + + public static boolean isStoped(Context context) { + return CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_MANUAL_STOP); + } + public static boolean isConnected(Context context) { return CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE); } @@ -253,6 +231,17 @@ public class CIMPushManager { return ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo(); } + + public static void startService(Context context,Intent intent) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + context.startForegroundService(intent); + } else { + context.startService(intent); + } + } + + + private static String getVersionName(Context context) { String versionName = null; try { @@ -263,14 +252,6 @@ public class CIMPushManager { return versionName; } - private static void startServiceCompat(Context context,Intent intent) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - context.startForegroundService(intent); - } else { - context.startService(intent); - } - } - } diff --git a/cim-client-sdk/cim-android-sdk/src/com/farsunset/cim/sdk/android/CIMPushService.java b/cim-client-sdk/cim-android-sdk/src/com/farsunset/cim/sdk/android/CIMPushService.java index 6267279..7ed402c 100644 --- a/cim-client-sdk/cim-android-sdk/src/com/farsunset/cim/sdk/android/CIMPushService.java +++ b/cim-client-sdk/cim-android-sdk/src/com/farsunset/cim/sdk/android/CIMPushService.java @@ -34,7 +34,6 @@ import android.net.Network; import android.os.Build; import android.os.Handler; import android.os.IBinder; -import android.os.Message; import com.farsunset.cim.sdk.android.coder.CIMLogger; import com.farsunset.cim.sdk.android.constant.CIMConstant; @@ -50,6 +49,8 @@ public class CIMPushService extends Service { public final static String KEY_DELAYED_TIME = "KEY_DELAYED_TIME"; public final static String KEY_LOGGER_ENABLE = "KEY_LOGGER_ENABLE"; + private final static int NOTIFICATION_ID = Integer.MAX_VALUE; + private CIMConnectorManager manager; private KeepAliveBroadcastReceiver keepAliveReceiver; private ConnectivityManager connectivityManager; @@ -90,15 +91,19 @@ public class CIMPushService extends Service { }; - Handler connectionHandler = new Handler() { + Handler connectHandler = new Handler() { @Override public void handleMessage(android.os.Message message) { - String host = message.getData().getString(CIMCacheManager.KEY_CIM_SERVIER_HOST); - int port = message.getData().getInt(CIMCacheManager.KEY_CIM_SERVIER_PORT, 0); - handleConnection(host, port); + connect(); } }; + Handler notificationHandler = new Handler() { + @Override + public void handleMessage(android.os.Message message) { + stopForeground(true); + } + }; @Override public int onStartCommand(Intent intent, int flags, int startId) { @@ -107,9 +112,13 @@ public class CIMPushService extends Service { NotificationChannel channel = new NotificationChannel(getClass().getSimpleName(),getClass().getSimpleName(), NotificationManager.IMPORTANCE_LOW); channel.enableLights(false); channel.enableVibration(false); + channel.setSound(null, null); notificationManager.createNotificationChannel(channel); - Notification notification = new Notification.Builder(this, channel.getId()).build(); - startForeground(this.hashCode(),notification); + Notification notification = new Notification.Builder(this, channel.getId()) + .setContentTitle("Push service") + .setContentText("Push service is running") + .build(); + startForeground(NOTIFICATION_ID,notification); } intent = (intent == null ? new Intent(CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE) : intent); @@ -117,7 +126,7 @@ public class CIMPushService extends Service { String action = intent.getAction(); if (CIMPushManager.ACTION_CREATE_CIM_CONNECTION.equals(action)) { - handleDelayConnection(intent); + connect(intent.getLongExtra(KEY_DELAYED_TIME, 0)); } if (CIMPushManager.ACTION_SEND_REQUEST_BODY.equals(action)) { @@ -138,42 +147,36 @@ public class CIMPushService extends Service { } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - stopForeground(true); + notificationHandler.sendEmptyMessageDelayed(0, 1000); } return super.onStartCommand(intent, flags, startId); } - private void handleDelayConnection(Intent intent) { + private void connect(long delayMillis) { - long delayMillis = intent.getLongExtra(KEY_DELAYED_TIME, 0); - - if (delayMillis <= 0) { - String host = intent.getStringExtra(CIMCacheManager.KEY_CIM_SERVIER_HOST); - int port = intent.getIntExtra(CIMCacheManager.KEY_CIM_SERVIER_PORT, 0); - handleConnection(host, port); + if(delayMillis <= 0) { + connect(); return; } - - Message msg = connectionHandler.obtainMessage(); - msg.what = 0; - msg.setData(intent.getExtras()); - connectionHandler.removeMessages(0); - connectionHandler.sendMessageDelayed(msg, delayMillis); + connectHandler.sendEmptyMessageDelayed(0, delayMillis); } - private void handleConnection(String host,int port) { + private void connect() { - boolean isManualStop = CIMCacheManager.getBoolean(getApplicationContext(), CIMCacheManager.KEY_MANUAL_STOP); - boolean isDestroyed = CIMCacheManager.getBoolean(getApplicationContext(), CIMCacheManager.KEY_CIM_DESTROYED); - if(isManualStop || isDestroyed) { + if(CIMPushManager.isDestoryed(this) || CIMPushManager.isStoped(this)) { return; } - manager.connect(host, port); - } + + String host = CIMCacheManager.getString(this, CIMCacheManager.KEY_CIM_SERVIER_HOST); + int port = CIMCacheManager.getInt(this, CIMCacheManager.KEY_CIM_SERVIER_PORT); + manager.connect(host, port); + + } + private void handleKeepAlive() { if (manager.isConnected()) { @@ -181,10 +184,8 @@ public class CIMPushService extends Service { return; } - String host = CIMCacheManager.getString(this, CIMCacheManager.KEY_CIM_SERVIER_HOST); - int port = CIMCacheManager.getInt(this, CIMCacheManager.KEY_CIM_SERVIER_PORT); - - handleConnection(host,port); + connect(); + } @Override @@ -196,9 +197,12 @@ public class CIMPushService extends Service { public void onDestroy() { super.onDestroy(); manager.destroy(); - connectionHandler.removeMessages(0); + connectHandler.removeMessages(0); + notificationHandler.removeMessages(0); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { unregisterReceiver(keepAliveReceiver); + } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { diff --git a/cim-use-examples/cim-client-android/app/libs/cim-android-sdk-3.7.0.jar b/cim-use-examples/cim-client-android/app/libs/cim-android-sdk-3.7.0.jar index 4e629a4e9807ff44a91f9d173f8224328e81e753..4b9acfe69dbc095cb3cefe349e4935519e873dbc 100644 GIT binary patch delta 14514 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 X0S+<}JUxO!P_BefP>p&Jr%?YN@eK{; delta 14793 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 CjA!})