Android集成阿里消息推送

释放双眼,带上耳机,听听看~!

1.阿里消息推送的官方文档地址

https://help.aliyun.com/document_detail/30054.html?spm=a2c4g.11174283.3.2.136c6d1669NIv4

集成的步骤:

第一步:创建app(创建app这个步骤的内容是官方文档里的)

移动服务当前创建应用,需要两步

  • (1)添加Android应用
  • (2)在产品处,点击管理后,右上角点击“创建应用”完成应用创建

1、点击页面中的“添加产品”按钮,即可创建一个新的产品

1

2、输入产品的基本信息创建App时需要输入产品的名称,上传产品图标,选择产品分类。

1

3、产品创建成功

App创建成功后,产品列表会多出一个产品,强烈建议您去配置app

1

4、创建产品对应的应用

在产品列表页面,点击已经创建的产品按钮,进入产品管理页面。

5、在产品管理页面,点击添加应用图标,创建应用(目前需要分端创建)。

1

  • (1)创建Android应用,并填写APP名称和PackageName

1

创建完成后,应用会出现在应用列表中:

1

1

第二步:下载SDK

1

第三步:集成SDK

1.添加jar包到libs文件夹下

2.在APP工程的build.gradle中配置jniLibs的目录

    sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}  

3.添加gradle依赖

implementation('com.aliyun.ams:alicloud-android-push:3.1.4', {
//和支付支付有utdid包的冲突
exclude module: 'alicloud-android-utdid'
}) 

4.在AndroidManifest.xml里配置appkey和appsecret

<!-- 阿里推送 -->
<meta-data
android:name="com.alibaba.app.appkey"
android:value="2********00" />
<meta-data
android:name="com.alibaba.app.appsecret"
android:value="3b6**************fdb" />

5.在AndroidManifest.xml里添加权限(这个不是阿里官方文档权限,是我自己项目里的,可以自己去官方文档复印哦)

<!-- 允许程序打开定位权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!-- 允许程序打开网络套接字 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 允许程序设置内置sd卡的写权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 允许程序获取网络状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 允许程序访问WiFi网络信息 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 允许程序读写手机状态和身份 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 允许程序访问CellID或WiFi热点来获取粗略的位置 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<!-- application中弹框 -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<!-- 分享权限 -->
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- 蓝牙分享所需的权限 -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!-- 照片权限 -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

6.在项目的主build.gradle不是app下的build.gradle的allprojects 下添加

allprojects {
repositories {
google()
jcenter()
//集成阿里推送添加的
maven {
url 'http://maven.aliyun.com/nexus/content/repositories/releases/'
}
//集成支付宝添加的
flatDir {
dirs 'libs'
}
maven { url 'https://dl.bintray.com/umsdk/release' } //友盟统计
maven { url 'https://jitpack.io' }
}
}

7.接收消息的Receiver配置

<receiver
android:name=".receiver.AliMessageReceiver"
android:exported="false"> <!-- 为保证receiver安全,建议设置不可导出,如需对其他应用开放可通过android:permission进行限制 -->
<intent-filter>
<action android:name="com.alibaba.push2.action.NOTIFICATION_OPENED" />
</intent-filter>
<intent-filter>
<action android:name="com.alibaba.push2.action.NOTIFICATION_REMOVED" />
</intent-filter>
<intent-filter>
<action android:name="com.alibaba.sdk.android.push.RECEIVE" />
</intent-filter>
</receiver>

8.混淆文件proguard-rules.pro的配置

#阿里移动推送
-keep class android.support.multidex.**{*;}
-keep class com.alibaba.fastjson.** {*;}
-keep class sun.misc.Unsafe { *; }
-keep class com.taobao.** {*;}
-keep class com.alibaba.** {*;}
-keep class com.alipay.** {*;}
-keep class com.ut.** {*;}
-keep class com.ta.** {*;}
-keep class anet.**{*;}
-keep class anetwork.**{*;}
-keep class org.android.spdy.**{*;}
-keep class org.android.agoo.**{*;}
-keep class android.os.**{*;}
-dontwarn com.taobao.**
-dontwarn com.alibaba.**
-dontwarn com.alipay.**
-dontwarn anet.**
-dontwarn org.android.spdy.**
-dontwarn org.android.agoo.**
-dontwarn anetwork.**
-dontwarn com.ut.**
-dontwarn com.ta.**
# 小米辅助通道
-keep class com.xiaomi.** {*;}
-dontwarn com.xiaomi.**
# 华为辅助通道
-keep class com.huawei.** {*;}
-dontwarn com.huawei.**

9.Application中的配置

/**
* 初始化云推送通道
* @param applicationContext
*/
private void initCloudChannel(Context applicationContext) {
PushServiceFactory.init(applicationContext);
final CloudPushService pushService = PushServiceFactory.getCloudPushService();
pushService.register(applicationContext, new CommonCallback() {
@Override
public void onSuccess(final String response) {
Log.d(TAG, "init cloudchannel success");
}
@Override
public void onFailed(String errorCode, String errorMessage) {
Log.d(TAG, "init cloudchannel failed -- errorcode:" + errorCode + " -- errorMessage:" + errorMessage);
}
});
this.createNotificationChannel();
MiPushRegister.register(applicationContext, Constants.XIAOMI_APP_ID, Constants.XIAOMI_APP_KEY); // 初始化小米辅助推送
HuaWeiRegister.register(applicationContext); // 接入华为辅助推送
OppoRegister.register(applicationContext, Constants.OPPO_APPKEY, Constants.OPPO_APPSECRET); // appKey/appSecret在OPPO通道开发者平台获取
}
private void createNotificationChannel() {
//针对于安卓8.0以上的手机,开启通道
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// 通知渠道的id
String id = "app";
// 用户可以看到的通知渠道的名字.
CharSequence name = "notification channel";
// 用户可以看到的通知渠道的描述
String description = "notification description";
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = new NotificationChannel(id, name, importance);
// 配置通知渠道的属性
mChannel.setDescription(description);
// 设置通知出现时的闪灯(如果 android 设备支持的话)
mChannel.enableLights(true);
mChannel.setLightColor(Color.RED);
// 设置通知出现时的震动(如果 android 设备支持的话)
mChannel.enableVibration(true);
mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
//最后在notificationmanager中创建该通知渠道
mNotificationManager.createNotificationChannel(mChannel);
}
}

10.接收消息Reciver代码的编写

public class AliMessageReceiver extends MessageReceiver {
// 消息接收部分的LOG_TAG
public static final String REC_TAG = "receiver";
/**
* desc 收到通知的回调方法(未点击弹窗)
*/
@Override
public void onNotification(Context context, String title, String summary, Map<String, String> extraMap) {
// TODO 处理推送通知
Log.e("收到通知", "Receive notification, title: " + title + ", summary: " + summary + ", extraMap: " + extraMap);
String msgId = extraMap.get("_ALIYUN_NOTIFICATION_ID_");
Bundle bundle = new Bundle();
if (msgId == null) {
return;
}
ACache mCache = ACache.get(context);
String result = mCache.getAsString(Constants.JPUSH_MODEL); //缓存里找是否有数据
if (result == null || "".equals(result)) {
Map<String, Object> resultMap = new HashMap<String, Object>();
mCache.put(Constants.JPUSH_MODEL, resultMap.toString());
return;
}
com.alibaba.fastjson.JSONObject extras = JSON.parseObject(result);
if (!extras.containsKey(msgId)) {//已经存过了就不存了
Map<String, Object> bundleMap = new HashMap<String, Object>();
bundleMap.put("push_user", bundle.getString("push_user"));
bundleMap.put("content", bundle.getString("content"));
extras.put(msgId, bundleMap);
mCache.put(Constants.JPUSH_MODEL, extras.toString());
}
bundle.putString("push_user", extraMap.get("push_user"));
bundle.putString("content", extraMap.get("content"));
if (extraMap != null && !extraMap.isEmpty()) {
try {
String type = extraMap.get(Constants.JPUSH_TYPE) + "";  //收到消息的类型
switch (type) {
case "login_out"://强制下线通知
ProjectApplication.AccessToken = "";
//Constants.MOBOLE_PHONE = "";
// Constants.NICK_NAME = "";
// Constants.HEAD_PHOTO = "";
//sysAccountPre.edit().clear(); //清除缓存
//清除用户数据
//  SharedPreferencesUtils.cleanDataInfo(context,Constants.CONFIG);
//给界面发送一个通知 弹出消息
final Intent msgIntent = new Intent(BaseActivity.MESSAGE_RECEIVED_ACTION);
msgIntent.putExtras(bundle);
context.sendBroadcast(msgIntent);
break;
}
} catch (Exception e) {
}
}
}
/**
* desc 收到消息的回调方法
*/
@Override
public void onMessage(Context context, CPushMessage cPushMessage) {
Log.e("MyMessageReceiver", "onMessage, messageId: " + cPushMessage.getMessageId() + ", title: " + cPushMessage.getTitle() + ", content:" + cPushMessage.getContent());
}
/**
* desc 从通知栏打开通知的扩展处理
*/
@Override
public void onNotificationOpened(Context context, String title, String summary, String extraMap) {
Log.e("点击通知", "onNotificationOpened, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap);
com.alibaba.fastjson.JSONObject extras = JSON.parseObject(extraMap);
String msgId = extras.get("_ALIYUN_NOTIFICATION_ID_") + "";
ACache mCache = ACache.get(context);
String result = mCache.getAsString(Constants.JPUSH_MODEL); //缓存里找是否有数据
com.alibaba.fastjson.JSONObject bundleResult = JSON.parseObject(result);
Map<String, Object> bundleMap = (Map<String, Object>) bundleResult.get(msgId);
Bundle bundle = new Bundle();
bundle.putString("push_user", extras.get("push_user") + "");
bundle.putString("content", extras.get("content") + "");
if (extras != null && !extras.isEmpty()) {
String type = extras.get(Constants.JPUSH_TYPE) + "";
//点击下线通话通知和其它的通知,跳转到不同的界面,可细分。
switch (type) {
case "login_out"://强制下线通知
ProjectApplication.AccessToken = "";
//  Constants.MOBOLE_PHONE = "";
//   Constants.NICK_NAME = "";
//   Constants.HEAD_PHOTO = "";
//  sysAccountPre.edit().clear(); //清除缓存
//销毁所有活动
ActivityCollector.finishAll();
//清除用户数据
//   SharedPreferencesUtils.cleanDataInfo(context, Constants.CONFIG);
Intent msgIntent = new Intent(context, MainActivity.class);
//在广播中启动活动,需要添加如下代码
msgIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
msgIntent.putExtras(bundle);
context.startActivity(msgIntent);
break;
default:
if (null != ProjectApplication.AccessToken  && !"".equals(ProjectApplication.AccessToken)) {
Intent myOrderActivityIntent = new Intent(context, OrderActivity.class);
//在广播中启动活动,需要添加如下代码
myOrderActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
myOrderActivityIntent.putExtras(bundle);
context.startActivity(myOrderActivityIntent);
}
break;
}
}
}
/**
* desc 无动作通知点击回调。当在后台或阿里云控制台指定的通知动作为无逻辑跳转时,通知点击回调为onNotificationClickedWithNoAction而不是onNotificationOpened
*/
@Override
protected void onNotificationClickedWithNoAction(Context context, String title, String summary, String extraMap) {
Log.e("MyMessageReceiver", "onNotificationClickedWithNoAction, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap);
}
/**
* desc 应用处于前台时通知到达回调。注意:该方法仅对自定义样式通知有效,
* 相关详情请参考https://help.aliyun.com/document_detail/30066.html?spm=5176.product30047.6.620.wjcC87#h3-3-4-basiccustompushnotification-api
*/
@Override
protected void onNotificationReceivedInApp(Context context, String title, String summary, Map<String, String> extraMap, int openType, String openActivity, String openUrl) {
Log.e("MyMessageReceiver", "onNotificationReceivedInApp, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap + ", openType:" + openType + ", openActivity:" + openActivity + ", openUrl:" + openUrl);
}
/**
* desc 通知删除回调(用户划掉通知栏的弹窗)
*/
@Override
protected void onNotificationRemoved(Context context, String messageId) {
Log.e("MyMessageReceiver", "onNotificationRemoved");
}
}
  //public static String JPUSH_TYPE = "push_user";  constants里的常量
 //public static String JPUSH_MODEL = "jpush_model";

11.消息缓存的工具类Acache

public class ACache {
public static final int TIME_HOUR = 60 * 60;
public static final int TIME_DAY = TIME_HOUR * 24;
private static final int MAX_SIZE = 1000 * 1000 * 50; // 50 mb
private static final int MAX_COUNT = Integer.MAX_VALUE; // 不限制存放数据的数量
private static Map<String, ACache> mInstanceMap = new HashMap<String, ACache>();
private ACacheManager mCache;
public static ACache get(Context ctx) {
return get(ctx, "ACache");
}
public static ACache get(Context ctx, String cacheName) {
File f = new File(ctx.getCacheDir(), cacheName);
return get(f, MAX_SIZE, MAX_COUNT);
}
public static ACache get(File cacheDir) {
return get(cacheDir, MAX_SIZE, MAX_COUNT);
}
public static ACache get(Context ctx, long max_zise, int max_count) {
File f = new File(ctx.getCacheDir(), "ACache");
return get(f, max_zise, max_count);
}
public static ACache get(File cacheDir, long max_zise, int max_count) {
ACache manager = mInstanceMap.get(cacheDir.getAbsoluteFile() + myPid());
if (manager == null) {
manager = new ACache(cacheDir, max_zise, max_count);
mInstanceMap.put(cacheDir.getAbsolutePath() + myPid(), manager);
}
return manager;
}
private static String myPid() {
return "_" + android.os.Process.myPid();
}
private ACache(File cacheDir, long max_size, int max_count) {
if (!cacheDir.exists() && !cacheDir.mkdirs()) {
throw new RuntimeException("can't make dirs in "
+ cacheDir.getAbsolutePath());
}
mCache = new ACacheManager(cacheDir, max_size, max_count);
}
// =======================================
// ============ String数据 读写 ==============
// =======================================
/**
* 保存 String数据 到 缓存中
*
* @param key   保存的key
* @param value 保存的String数据
*/
public void put(String key, String value) {
File file = mCache.newFile(key);
BufferedWriter out = null;
try {
out = new BufferedWriter(new FileWriter(file), 1024);
out.write(value);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
mCache.put(file);
}
}
/**
* 保存 String数据 到 缓存中
*
* @param key      保存的key
* @param value    保存的String数据
* @param saveTime 保存的时间,单位:秒
*/
public void put(String key, String value, int saveTime) {
put(key, Utils.newStringWithDateInfo(saveTime, value));
}
/**
* 读取 String数据
*
* @param key
* @return String 数据
*/
public String getAsString(String key) {
File file = mCache.get(key);
if (!file.exists())
return null;
boolean removeFile = false;
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader(file));
String readString = "";
String currentLine;
while ((currentLine = in.readLine()) != null) {
readString += currentLine;
}
if (!Utils.isDue(readString)) {
return Utils.clearDateInfo(readString);
} else {
removeFile = true;
return null;
}
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (removeFile)
remove(key);
}
}
// =======================================
// ============= JSONObject 数据 读写 ==============
// =======================================
/**
* 保存 JSONObject数据 到 缓存中
*
* @param key   保存的key
* @param value 保存的JSON数据
*/
public void put(String key, JSONObject value) {
put(key, value.toString());
}
/**
* 保存 JSONObject数据 到 缓存中
*
* @param key      保存的key
* @param value    保存的JSONObject数据
* @param saveTime 保存的时间,单位:秒
*/
public void put(String key, JSONObject value, int saveTime) {
put(key, value.toString(), saveTime);
}
/**
* 读取JSONObject数据
*
* @param key
* @return JSONObject数据
*/
public JSONObject getAsJSONObject(String key) {
String JSONString = getAsString(key);
try {
JSONObject obj = new JSONObject(JSONString);
return obj;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
// =======================================
// ============ JSONArray 数据 读写 =============
// =======================================
/**
* 保存 JSONArray数据 到 缓存中
*
* @param key   保存的key
* @param value 保存的JSONArray数据
*/
public void put(String key, JSONArray value) {
put(key, value.toString());
}
/**
* 保存 JSONArray数据 到 缓存中
*
* @param key      保存的key
* @param value    保存的JSONArray数据
* @param saveTime 保存的时间,单位:秒
*/
public void put(String key, JSONArray value, int saveTime) {
put(key, value.toString(), saveTime);
}
/**
* 读取JSONArray数据
*
* @param key
* @return JSONArray数据
*/
public JSONArray getAsJSONArray(String key) {
String JSONString = getAsString(key);
try {
JSONArray obj = new JSONArray(JSONString);
return obj;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
// =======================================
// ============== byte 数据 读写 =============
// =======================================
/**
* 保存 byte数据 到 缓存中
*
* @param key   保存的key
* @param value 保存的数据
*/
public void put(String key, byte[] value) {
File file = mCache.newFile(key);
FileOutputStream out = null;
try {
out = new FileOutputStream(file);
out.write(value);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
mCache.put(file);
}
}
/**
* 保存 byte数据 到 缓存中
*
* @param key      保存的key
* @param value    保存的数据
* @param saveTime 保存的时间,单位:秒
*/
public void put(String key, byte[] value, int saveTime) {
put(key, Utils.newByteArrayWithDateInfo(saveTime, value));
}
/**
* 获取 byte 数据
*
* @param key
* @return byte 数据
*/
public byte[] getAsBinary(String key) {
RandomAccessFile RAFile = null;
boolean removeFile = false;
try {
File file = mCache.get(key);
if (!file.exists())
return null;
RAFile = new RandomAccessFile(file, "r");
byte[] byteArray = new byte[(int) RAFile.length()];
RAFile.read(byteArray);
if (!Utils.isDue(byteArray)) {
return Utils.clearDateInfo(byteArray);
} else {
removeFile = true;
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (RAFile != null) {
try {
RAFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (removeFile)
remove(key);
}
}
// =======================================
// ============= 序列化 数据 读写 ===============
// =======================================
/**
* 保存 Serializable数据 到 缓存中
*
* @param key   保存的key
* @param value 保存的value
*/
public void put(String key, Serializable value) {
put(key, value, -1);
}
/**
* 保存 Serializable数据到 缓存中
*
* @param key      保存的key
* @param value    保存的value
* @param saveTime 保存的时间,单位:秒
*/
public void put(String key, Serializable value, int saveTime) {
ByteArrayOutputStream baos = null;
ObjectOutputStream oos = null;
try {
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(value);
byte[] data = baos.toByteArray();
if (saveTime != -1) {
put(key, data, saveTime);
} else {
put(key, data);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
oos.close();
} catch (IOException e) {
}
}
}
/**
* 读取 Serializable数据
*
* @param key
* @return Serializable 数据
*/
public Object getAsObject(String key) {
byte[] data = getAsBinary(key);
if (data != null) {
ByteArrayInputStream bais = null;
ObjectInputStream ois = null;
try {
bais = new ByteArrayInputStream(data);
ois = new ObjectInputStream(bais);
Object reObject = ois.readObject();
return reObject;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
if (bais != null)
bais.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (ois != null)
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
// =======================================
// ============== bitmap 数据 读写 =============
// =======================================
/**
* 保存 bitmap 到 缓存中
*
* @param key   保存的key
* @param value 保存的bitmap数据
*/
public void put(String key, Bitmap value) {
put(key, Utils.Bitmap2Bytes(value));
}
/**
* 保存 bitmap 到 缓存中
*
* @param key      保存的key
* @param value    保存的 bitmap 数据
* @param saveTime 保存的时间,单位:秒
*/
public void put(String key, Bitmap value, int saveTime) {
put(key, Utils.Bitmap2Bytes(value), saveTime);
}
/**
* 读取 bitmap 数据
*
* @param key
* @return bitmap 数据
*/
public Bitmap getAsBitmap(String key) {
if (getAsBinary(key) == null) {
return null;
}
return Utils.Bytes2Bimap(getAsBinary(key));
}
// =======================================
// ============= drawable 数据 读写 =============
// =======================================
/**
* 保存 drawable 到 缓存中
*
* @param key   保存的key
* @param value 保存的drawable数据
*/
public void put(String key, Drawable value) {
put(key, Utils.drawable2Bitmap(value));
}
/**
* 保存 drawable 到 缓存中
*
* @param key      保存的key
* @param value    保存的 drawable 数据
* @param saveTime 保存的时间,单位:秒
*/
public void put(String key, Drawable value, int saveTime) {
put(key, Utils.drawable2Bitmap(value), saveTime);
}
/**
* 读取 Drawable 数据
*
* @param key
* @return Drawable 数据
*/
public Drawable getAsDrawable(String key) {
if (getAsBinary(key) == null) {
return null;
}
return Utils.bitmap2Drawable(Utils.Bytes2Bimap(getAsBinary(key)));
}
/**
* 获取缓存文件
*
* @param key
* @return value 缓存的文件
*/
public File file(String key) {
File f = mCache.newFile(key);
if (f.exists())
return f;
return null;
}
/**
* 移除某个key
*
* @param key
* @return 是否移除成功
*/
public boolean remove(String key) {
return mCache.remove(key);
}
/**
* 清除所有数据
*/
public void clear() {
mCache.clear();
}
/**
* @title 缓存管理器
*/
public class ACacheManager {
private final AtomicLong cacheSize;
private final AtomicInteger cacheCount;
private final long sizeLimit;
private final int countLimit;
private final Map<File, Long> lastUsageDates = Collections
.synchronizedMap(new HashMap<File, Long>());
protected File cacheDir;
private ACacheManager(File cacheDir, long sizeLimit, int countLimit) {
this.cacheDir = cacheDir;
this.sizeLimit = sizeLimit;
this.countLimit = countLimit;
cacheSize = new AtomicLong();
cacheCount = new AtomicInteger();
calculateCacheSizeAndCacheCount();
}
/**
* 计算 cacheSize和cacheCount
*/
private void calculateCacheSizeAndCacheCount() {
new Thread(new Runnable() {
@Override
public void run() {
int size = 0;
int count = 0;
File[] cachedFiles = cacheDir.listFiles();
if (cachedFiles != null) {
for (File cachedFile : cachedFiles) {
size += calculateSize(cachedFile);
count += 1;
lastUsageDates.put(cachedFile,
cachedFile.lastModified());
}
cacheSize.set(size);
cacheCount.set(count);
}
}
}).start();
}
private void put(File file) {
int curCacheCount = cacheCount.get();
while (curCacheCount + 1 > countLimit) {
long freedSize = removeNext();
cacheSize.addAndGet(-freedSize);
curCacheCount = cacheCount.addAndGet(-1);
}
cacheCount.addAndGet(1);
long valueSize = calculateSize(file);
long curCacheSize = cacheSize.get();
while (curCacheSize + valueSize > sizeLimit) {
long freedSize = removeNext();
curCacheSize = cacheSize.addAndGet(-freedSize);
}
cacheSize.addAndGet(valueSize);
Long currentTime = System.currentTimeMillis();
file.setLastModified(currentTime);
lastUsageDates.put(file, currentTime);
}
private File get(String key) {
File file = newFile(key);
Long currentTime = System.currentTimeMillis();
file.setLastModified(currentTime);
lastUsageDates.put(file, currentTime);
return file;
}
private File newFile(String key) {
return new File(cacheDir, key.hashCode() + "");
}
private boolean remove(String key) {
File image = get(key);
return image.delete();
}
private void clear() {
lastUsageDates.clear();
cacheSize.set(0);
File[] files = cacheDir.listFiles();
if (files != null) {
for (File f : files) {
f.delete();
}
}
}
/**
* 移除旧的文件
*
* @return
*/
private long removeNext() {
if (lastUsageDates.isEmpty()) {
return 0;
}
Long oldestUsage = null;
File mostLongUsedFile = null;
Set<Map.Entry<File, Long>> entries = lastUsageDates.entrySet();
synchronized (lastUsageDates) {
for (Map.Entry<File, Long> entry : entries) {
if (mostLongUsedFile == null) {
mostLongUsedFile = entry.getKey();
oldestUsage = entry.getValue();
} else {
Long lastValueUsage = entry.getValue();
if (lastValueUsage < oldestUsage) {
oldestUsage = lastValueUsage;
mostLongUsedFile = entry.getKey();
}
}
}
}
long fileSize = calculateSize(mostLongUsedFile);
if (mostLongUsedFile.delete()) {
lastUsageDates.remove(mostLongUsedFile);
}
return fileSize;
}
private long calculateSize(File file) {
return file.length();
}
}
/**
* @title 时间计算工具类
*/
private static class Utils {
/**
* 判断缓存的String数据是否到期
*
* @param str
* @return true:到期了 false:还没有到期
*/
private static boolean isDue(String str) {
return isDue(str.getBytes());
}
/**
* 判断缓存的byte数据是否到期
*
* @param data
* @return true:到期了 false:还没有到期
*/
private static boolean isDue(byte[] data) {
String[] strs = getDateInfoFromDate(data);
if (strs != null && strs.length == 2) {
String saveTimeStr = strs[0];
while (saveTimeStr.startsWith("0")) {
saveTimeStr = saveTimeStr
.substring(1, saveTimeStr.length());
}
long saveTime = Long.valueOf(saveTimeStr);
long deleteAfter = Long.valueOf(strs[1]);
if (System.currentTimeMillis() > saveTime + deleteAfter * 1000) {
return true;
}
}
return false;
}
private static String newStringWithDateInfo(int second, String strInfo) {
return createDateInfo(second) + strInfo;
}
private static byte[] newByteArrayWithDateInfo(int second, byte[] data2) {
byte[] data1 = createDateInfo(second).getBytes();
byte[] retdata = new byte[data1.length + data2.length];
System.arraycopy(data1, 0, retdata, 0, data1.length);
System.arraycopy(data2, 0, retdata, data1.length, data2.length);
return retdata;
}
private static String clearDateInfo(String strInfo) {
if (strInfo != null && hasDateInfo(strInfo.getBytes())) {
strInfo = strInfo.substring(strInfo.indexOf(mSeparator) + 1,
strInfo.length());
}
return strInfo;
}
private static byte[] clearDateInfo(byte[] data) {
if (hasDateInfo(data)) {
return copyOfRange(data, indexOf(data, mSeparator) + 1,
data.length);
}
return data;
}
private static boolean hasDateInfo(byte[] data) {
return data != null && data.length > 15 && data[13] == '-'
&& indexOf(data, mSeparator) > 14;
}
private static String[] getDateInfoFromDate(byte[] data) {
if (hasDateInfo(data)) {
String saveDate = new String(copyOfRange(data, 0, 13));
String deleteAfter = new String(copyOfRange(data, 14,
indexOf(data, mSeparator)));
return new String[]{saveDate, deleteAfter};
}
return null;
}
private static int indexOf(byte[] data, char c) {
for (int i = 0; i < data.length; i++) {
if (data[i] == c) {
return i;
}
}
return -1;
}
private static byte[] copyOfRange(byte[] original, int from, int to) {
int newLength = to - from;
if (newLength < 0)
throw new IllegalArgumentException(from + " > " + to);
byte[] copy = new byte[newLength];
System.arraycopy(original, from, copy, 0,
Math.min(original.length - from, newLength));
return copy;
}
private static final char mSeparator = ' ';
private static String createDateInfo(int second) {
String currentTime = System.currentTimeMillis() + "";
while (currentTime.length() < 13) {
currentTime = "0" + currentTime;
}
return currentTime + "-" + second + mSeparator;
}
/*
* Bitmap → byte[]
*/
private static byte[] Bitmap2Bytes(Bitmap bm) {
if (bm == null) {
return null;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
return baos.toByteArray();
}
/*
* byte[] → Bitmap
*/
private static Bitmap Bytes2Bimap(byte[] b) {
if (b.length == 0) {
return null;
}
return BitmapFactory.decodeByteArray(b, 0, b.length);
}
/*
* Drawable → Bitmap
*/
private static Bitmap drawable2Bitmap(Drawable drawable) {
if (drawable == null) {
return null;
}
// 取 drawable 的长宽
int w = drawable.getIntrinsicWidth();
int h = drawable.getIntrinsicHeight();
// 取 drawable 的颜色格式
Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565;
// 建立对应 bitmap
Bitmap bitmap = Bitmap.createBitmap(w, h, config);
// 建立对应 bitmap 的画布
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, w, h);
// 把 drawable 内容画到画布中
drawable.draw(canvas);
return bitmap;
}
/*
* Bitmap → Drawable
*/
@SuppressWarnings("deprecation")
private static Drawable bitmap2Drawable(Bitmap bm) {
if (bm == null) {
return null;
}
return new BitmapDrawable(bm);
}
}
}

 12.工具类activity的管理器

public class ActivityCollector {
public static List<Activity> activities = new ArrayList<Activity>();
/**
* 添加活动
* @param activity
*/
public static void addActivity(Activity activity){
if(!activities.contains(activity)){
activities.add(activity);
}
}
/**
* 移除活动
* @param activity
*/
public static void removeActivity(Activity activity){
activities.remove(activity);
}
/**
* 结束所有活动
*/
public static void finishAll(){
for(Activity activity : activities){
if(!activity.isFinishing()){
activity.finish();
}
}
}

13.在进程被杀死,收到通知,点击通知,进入app的辅助Activity(重要

public class PopupPushActivity extends AndroidPopupActivity {
static final String TAG = "PopupPushActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_popuppush);
}
/**
* 实现通知打开回调方法,获取通知相关信息
* @param title     标题
* @param summary   内容
* @param extMap    额外参数
*/
@Override
protected void onSysNoticeOpened(String title, String summary, Map<String, String> extMap) {
Log.d("点击辅助弹窗通知 :title" + title + "content" + summary ,"extMap"+extMap);
Bundle bundle = new Bundle();
bundle.putString("push_driver",extMap.get("push_driver")+"");
bundle.putString("content",extMap.get("content")+"");
if(extMap != null && !extMap.isEmpty()){
try {
String type = extMap.get(Constants.JPUSH_TYPE)+"";
switch (type){
case "login_out"://强制下线通知
Constants.ACCESS_TOKEN ="";
Constants.MOBOLE_PHONE ="";
//销毁所有活动
ActivityCollector.finishAll();
//清除用户数据
SharedPreferencesUtils.cleanDataInfo(this,Constants.CONFIG);
Intent msgIntent = new Intent(this, MainActivity.class);
//在广播中启动活动,需要添加如下代码
msgIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
msgIntent.putExtras(bundle);
PopupPushActivity.this.finish();
this.startActivity(msgIntent);
break;
default:
Intent defaultBroadcast = new Intent();
//指定动作事件,实际上就是要发送的广播的频道
defaultBroadcast.setAction(MainActivity.MAIN_RECEIVE);
//指定广播带上数据
//这个数据可以用Intent对象直接的传递,也可以通过Bundle对象打包传送
defaultBroadcast.putExtras(bundle);
this.sendBroadcast(defaultBroadcast);
Intent defaultOrder = new Intent(this, MainActivity.class);
defaultOrder.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(defaultOrder);
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void onResume() {
super.onResume();
MobclickAgent.onResume(this);
}
@Override
public void onPause() {
super.onPause();
MobclickAgent.onPause(this);
}
}

为TA充电
共{{data.count}}人
人已赞赏
Android文章

Android开发集成微信支付

2021-2-1 18:22:22

Android文章

Android开发接入阿里热修复Sophix框架

2021-2-1 19:15:25

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索