version:3.2
fix:修复全局更新,更换腾讯推送 update:接口缓存
This commit is contained in:
@@ -45,8 +45,8 @@ android {
|
||||
productFlavors {
|
||||
beta {
|
||||
flavorDimensions "default"
|
||||
versionCode 22
|
||||
versionName "3.1"
|
||||
versionCode 23
|
||||
versionName "3.2"
|
||||
}
|
||||
|
||||
official {
|
||||
@@ -175,6 +175,8 @@ dependencies {
|
||||
//glide
|
||||
implementation 'com.github.bumptech.glide:glide:4.13.2'
|
||||
annotationProcessor 'com.github.bumptech.glide:compiler:4.13.2'
|
||||
//磁盘缓存
|
||||
implementation 'com.jakewharton:disklrucache:2.0.2'
|
||||
//aria
|
||||
implementation 'com.arialyy.aria:core:3.8.15'
|
||||
annotationProcessor 'com.arialyy.aria:compiler:3.8.15'
|
||||
@@ -190,12 +192,19 @@ dependencies {
|
||||
//RxJava
|
||||
implementation 'io.reactivex.rxjava3:rxjava:3.0.0'
|
||||
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
|
||||
|
||||
//生命周期管理
|
||||
implementation 'com.trello.rxlifecycle4:rxlifecycle:4.0.2'
|
||||
implementation 'com.trello.rxlifecycle4:rxlifecycle-android:4.0.2'
|
||||
implementation 'com.trello.rxlifecycle4:rxlifecycle-components:4.0.2'
|
||||
implementation 'com.trello.rxlifecycle4:rxlifecycle-components-preference:4.0.2'
|
||||
implementation 'com.trello.rxlifecycle4:rxlifecycle-android-lifecycle:4.0.2'
|
||||
//google
|
||||
implementation 'com.google.code.gson:gson:2.9.0'
|
||||
implementation 'com.google.zxing:core:3.5.0'
|
||||
//fastjson
|
||||
implementation 'com.alibaba:fastjson:1.2.83'
|
||||
//MMKV
|
||||
implementation 'com.tencent:mmkv-static:1.2.13'
|
||||
//腾讯移动推送 TPNS
|
||||
implementation 'com.tencent.tpns:tpns:1.3.2.0-release'
|
||||
// //极光推送
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
<service android:name="com.uiui.appstore.service.StepService" />
|
||||
<service android:name="com.uiui.appstore.service.MyDownloadService" />
|
||||
<service
|
||||
android:name="com.uiui.appstore.service.InitJpushServer"
|
||||
android:name="com.uiui.appstore.service.main.MainService"
|
||||
android:enabled="true"
|
||||
android:exported="true" />
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ import com.uiui.appstore.fragment.FeaturedFragment;
|
||||
import com.uiui.appstore.fragment.ManageFragment;
|
||||
import com.uiui.appstore.network.NetInterfaceManager;
|
||||
import com.uiui.appstore.service.GuardService;
|
||||
import com.uiui.appstore.service.InitJpushServer;
|
||||
import com.uiui.appstore.service.main.MainService;
|
||||
import com.uiui.appstore.service.MyDownloadService;
|
||||
import com.uiui.appstore.service.StepService;
|
||||
import com.uiui.appstore.utils.SPUtils;
|
||||
@@ -66,7 +66,7 @@ public class MainActivity extends BaseActivity {
|
||||
private void starService() {
|
||||
startService(new Intent(this, GuardService.class));
|
||||
startService(new Intent(this, StepService.class));
|
||||
startService(new Intent(this, InitJpushServer.class));
|
||||
startService(new Intent(this, MainService.class));
|
||||
startService(new Intent(this, MyDownloadService.class));
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,9 @@ import com.scwang.smartrefresh.layout.header.ClassicsHeader;
|
||||
import com.tencent.android.tpush.XGIOperateCallback;
|
||||
import com.tencent.android.tpush.XGPushConfig;
|
||||
import com.tencent.android.tpush.XGPushManager;
|
||||
import com.tencent.mmkv.MMKV;
|
||||
import com.uiui.appstore.R;
|
||||
import com.uiui.appstore.manager.ConnectManager;
|
||||
import com.uiui.appstore.network.NetInterfaceManager;
|
||||
import com.uiui.appstore.receiver.AppManagerReceiver;
|
||||
import com.uiui.appstore.utils.JGYUtils;
|
||||
@@ -75,9 +77,13 @@ public class BaseApplication extends Application {
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
app = this;
|
||||
String rootDir = MMKV.initialize(this);
|
||||
Log.i(TAG, "mmkv root: " + rootDir);
|
||||
|
||||
tPushInit();
|
||||
ToastUtil.init(this);
|
||||
JGYUtils.init(this);
|
||||
ConnectManager.init(this);
|
||||
Aria.init(this);
|
||||
Aria.get(this).getDownloadConfig().setMaxTaskNum(1);
|
||||
Aria.get(this).getDownloadConfig().setConvertSpeed(true);
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.uiui.appstore.base;
|
||||
|
||||
public interface BasePresenter<V extends BaseView> {
|
||||
void attachView(V view);
|
||||
|
||||
void detachView();
|
||||
}
|
||||
4
app/src/main/java/com/uiui/appstore/base/BaseView.java
Normal file
4
app/src/main/java/com/uiui/appstore/base/BaseView.java
Normal file
@@ -0,0 +1,4 @@
|
||||
package com.uiui.appstore.base;
|
||||
|
||||
public interface BaseView {
|
||||
}
|
||||
28
app/src/main/java/com/uiui/appstore/bean/BatchID.java
Normal file
28
app/src/main/java/com/uiui/appstore/bean/BatchID.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package com.uiui.appstore.bean;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class BatchID implements Serializable {
|
||||
private static final long serialVersionUID = -2320968190625923242L;
|
||||
|
||||
String batch_id;
|
||||
|
||||
public String getBatch_id() {
|
||||
return batch_id;
|
||||
}
|
||||
|
||||
public void setBatch_id(String batch_id) {
|
||||
this.batch_id = batch_id;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return JsonParser.parseString(new Gson().toJson(this)).getAsJsonObject().toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,473 @@
|
||||
package com.uiui.appstore.disklrucache;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
|
||||
import com.jakewharton.disklrucache.DiskLruCache;
|
||||
import com.tencent.mmkv.MMKV;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 磁盘缓存帮助类
|
||||
*/
|
||||
public class CacheHelper {
|
||||
private static final String TAG = "DiskLruCacheHelper";
|
||||
|
||||
private MMKV mMMKV = MMKV.defaultMMKV();
|
||||
|
||||
private static final String DIR_NAME = "diskCache";
|
||||
private static final int MAX_COUNT = 1024 * 1024 * 1024;
|
||||
private static final int DEFAULT_APP_VERSION = 1;
|
||||
|
||||
private DiskLruCache mDiskLruCache;
|
||||
|
||||
public CacheHelper(Context context) {
|
||||
mDiskLruCache = generateCache(context, DIR_NAME, MAX_COUNT);
|
||||
}
|
||||
|
||||
public CacheHelper(Context context, String dirName) {
|
||||
mDiskLruCache = generateCache(context, dirName, MAX_COUNT);
|
||||
}
|
||||
|
||||
public CacheHelper(Context context, String dirName, int maxCount) {
|
||||
mDiskLruCache = generateCache(context, dirName, maxCount);
|
||||
}
|
||||
|
||||
//custom cache dir
|
||||
public CacheHelper(File dir) {
|
||||
mDiskLruCache = generateCache(null, dir, MAX_COUNT);
|
||||
}
|
||||
|
||||
public CacheHelper(Context context, File dir) {
|
||||
mDiskLruCache = generateCache(context, dir, MAX_COUNT);
|
||||
}
|
||||
|
||||
public CacheHelper(Context context, File dir, int maxCount) {
|
||||
mDiskLruCache = generateCache(context, dir, maxCount);
|
||||
}
|
||||
|
||||
private DiskLruCache generateCache(Context context, File dir, int maxCount) {
|
||||
if (!dir.exists() || !dir.isDirectory()) {
|
||||
throw new IllegalArgumentException(
|
||||
dir + " is not a directory or does not exists. ");
|
||||
}
|
||||
|
||||
int appVersion = context == null ? DEFAULT_APP_VERSION : Utils.getAppVersion(context);
|
||||
|
||||
DiskLruCache diskLruCache = null;
|
||||
try {
|
||||
diskLruCache = DiskLruCache.open(
|
||||
dir,
|
||||
appVersion,
|
||||
DEFAULT_APP_VERSION,
|
||||
maxCount);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return diskLruCache;
|
||||
}
|
||||
|
||||
private DiskLruCache generateCache(Context context, String dirName, int maxCount) {
|
||||
DiskLruCache diskLruCache = null;
|
||||
try {
|
||||
diskLruCache = DiskLruCache.open(
|
||||
getDiskCacheDir(context, dirName),
|
||||
Utils.getAppVersion(context),
|
||||
DEFAULT_APP_VERSION,
|
||||
maxCount);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return diskLruCache;
|
||||
}
|
||||
|
||||
// =======================================
|
||||
// ============== String 数据 读写 =============
|
||||
// =======================================
|
||||
|
||||
public void put(String key, String value) {
|
||||
Log.e(TAG, "put: key = " + key + " value = " + value);
|
||||
mMMKV.encode(key, System.currentTimeMillis());
|
||||
mMMKV.encode(key + "_mmkv", value);
|
||||
|
||||
DiskLruCache.Editor edit = null;
|
||||
BufferedWriter bw = null;
|
||||
try {
|
||||
edit = editor(key);
|
||||
if (edit == null) {
|
||||
return;
|
||||
}
|
||||
OutputStream os = edit.newOutputStream(0);
|
||||
bw = new BufferedWriter(new OutputStreamWriter(os));
|
||||
bw.write(value);
|
||||
edit.commit();//write CLEAN
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "put: " + e.getMessage());
|
||||
try {
|
||||
//s
|
||||
edit.abort();//write REMOVE
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
Log.e(TAG, "put: " + e1.getMessage());
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
if (bw != null) {
|
||||
bw.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "put: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getAsString(String key) {
|
||||
Log.e(TAG, "getAsString: " + key);
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
//write READ
|
||||
inputStream = get(key);
|
||||
if (inputStream == null) {
|
||||
return mMMKV.decodeString(key + "_mmkv", null);
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int len = 0;
|
||||
byte[] buf = new byte[128];
|
||||
while ((len = inputStream.read(buf)) != -1) {
|
||||
sb.append(new String(buf, 0, len));
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "getAsString: " + e.getMessage());
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
Log.e(TAG, "getAsString: " + e1.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void put(String key, JSONObject jsonObject) {
|
||||
put(key, jsonObject.toString());
|
||||
}
|
||||
|
||||
public JSONObject getAsJson(String key) {
|
||||
String val = getAsString(key);
|
||||
try {
|
||||
if (val != null) {
|
||||
return new JSONObject(val);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// =======================================
|
||||
// ============ JSONArray 数据 读写 =============
|
||||
// =======================================
|
||||
|
||||
public void put(String key, JSONArray jsonArray) {
|
||||
put(key, jsonArray.toString());
|
||||
}
|
||||
|
||||
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) {
|
||||
OutputStream out = null;
|
||||
DiskLruCache.Editor editor = null;
|
||||
try {
|
||||
editor = editor(key);
|
||||
if (editor == null) {
|
||||
return;
|
||||
}
|
||||
out = editor.newOutputStream(0);
|
||||
out.write(value);
|
||||
out.flush();
|
||||
editor.commit();//write CLEAN
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
try {
|
||||
editor.abort();//write REMOVE
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
} finally {
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public byte[] getAsBytes(String key) {
|
||||
byte[] res = null;
|
||||
InputStream is = get(key);
|
||||
if (is == null) {
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try {
|
||||
byte[] buf = new byte[256];
|
||||
int len = 0;
|
||||
while ((len = is.read(buf)) != -1) {
|
||||
baos.write(buf, 0, len);
|
||||
}
|
||||
res = baos.toByteArray();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// =======================================
|
||||
// ============== 序列化 数据 读写 =============
|
||||
// =======================================
|
||||
public void put(String key, Serializable value) {
|
||||
DiskLruCache.Editor editor = editor(key);
|
||||
ObjectOutputStream oos = null;
|
||||
if (editor == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
OutputStream os = editor.newOutputStream(0);
|
||||
oos = new ObjectOutputStream(os);
|
||||
oos.writeObject(value);
|
||||
oos.flush();
|
||||
editor.commit();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
try {
|
||||
editor.abort();
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
if (oos != null) {
|
||||
oos.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T getAsSerializable(String key) {
|
||||
T t = null;
|
||||
InputStream is = get(key);
|
||||
ObjectInputStream ois = null;
|
||||
if (is == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
ois = new ObjectInputStream(is);
|
||||
t = (T) ois.readObject();
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (ois != null) {
|
||||
ois.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
// =======================================
|
||||
// ============== bitmap 数据 读写 =============
|
||||
// =======================================
|
||||
public void put(String key, Bitmap bitmap) {
|
||||
put(key, Utils.bitmap2Bytes(bitmap));
|
||||
}
|
||||
|
||||
public Bitmap getAsBitmap(String key) {
|
||||
byte[] bytes = getAsBytes(key);
|
||||
if (bytes == null) {
|
||||
return null;
|
||||
}
|
||||
return Utils.bytes2Bitmap(bytes);
|
||||
}
|
||||
|
||||
// =======================================
|
||||
// ============= drawable 数据 读写 =============
|
||||
// =======================================
|
||||
public void put(String key, Drawable value) {
|
||||
put(key, Utils.drawable2Bitmap(value));
|
||||
}
|
||||
|
||||
public Drawable getAsDrawable(String key) {
|
||||
byte[] bytes = getAsBytes(key);
|
||||
if (bytes == null) {
|
||||
return null;
|
||||
}
|
||||
return Utils.bitmap2Drawable(Utils.bytes2Bitmap(bytes));
|
||||
}
|
||||
|
||||
// =======================================
|
||||
// ============= other methods =============
|
||||
// =======================================
|
||||
public boolean remove(String key) {
|
||||
try {
|
||||
key = Utils.hashKeyForDisk(key);
|
||||
return mDiskLruCache.remove(key);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
mDiskLruCache.close();
|
||||
}
|
||||
|
||||
public void delete() throws IOException {
|
||||
mDiskLruCache.delete();
|
||||
mMMKV.clearAll();
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
mDiskLruCache.flush();
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return mDiskLruCache.isClosed();
|
||||
}
|
||||
|
||||
public long size() {
|
||||
return mDiskLruCache.size();
|
||||
}
|
||||
|
||||
public void setMaxSize(long maxSize) {
|
||||
mDiskLruCache.setMaxSize(maxSize);
|
||||
}
|
||||
|
||||
public File getDirectory() {
|
||||
return mDiskLruCache.getDirectory();
|
||||
}
|
||||
|
||||
public long getMaxSize() {
|
||||
return mDiskLruCache.getMaxSize();
|
||||
}
|
||||
|
||||
|
||||
// =======================================
|
||||
// ===遇到文件比较大的,可以直接通过流读写 =====
|
||||
// =======================================
|
||||
//basic editor
|
||||
public DiskLruCache.Editor editor(String key) {
|
||||
try {
|
||||
key = Utils.hashKeyForDisk(key);
|
||||
//wirte DIRTY
|
||||
DiskLruCache.Editor edit = mDiskLruCache.edit(key);
|
||||
//edit maybe null :the entry is editing
|
||||
if (edit == null) {
|
||||
Log.w(TAG, "the entry spcified key:" + key + " is editing by other . ");
|
||||
}
|
||||
return edit;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "editor: " + e.getMessage());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
//basic get
|
||||
public InputStream get(String key) {
|
||||
try {
|
||||
DiskLruCache.Snapshot snapshot = mDiskLruCache.get(Utils.hashKeyForDisk(key));
|
||||
if (snapshot == null) //not find entry , or entry.readable = false
|
||||
{
|
||||
Log.e(TAG, "not find entry , or entry.readable = false");
|
||||
return null;
|
||||
}
|
||||
//write READ
|
||||
return snapshot.getInputStream(0);
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// =======================================
|
||||
// ============== 序列化 数据 读写 =============
|
||||
// =======================================
|
||||
|
||||
private File getDiskCacheDir(Context context, String uniqueName) {
|
||||
String cachePath;
|
||||
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
|
||||
|| !Environment.isExternalStorageRemovable()) {
|
||||
if (context.getExternalCacheDir() != null) {
|
||||
cachePath = context.getExternalCacheDir().getPath();
|
||||
} else if (context.getExternalFilesDir("cache") != null) {
|
||||
cachePath = context.getExternalFilesDir("cache").getPath();
|
||||
} else {
|
||||
cachePath = context.getCacheDir().getPath();
|
||||
}
|
||||
} else {
|
||||
cachePath = context.getCacheDir().getPath();
|
||||
}
|
||||
return new File(cachePath + File.separator + uniqueName);
|
||||
}
|
||||
|
||||
}
|
||||
101
app/src/main/java/com/uiui/appstore/disklrucache/Utils.java
Normal file
101
app/src/main/java/com/uiui/appstore/disklrucache/Utils.java
Normal file
@@ -0,0 +1,101 @@
|
||||
package com.uiui.appstore.disklrucache;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class Utils {
|
||||
public static int getAppVersion(Context context) {
|
||||
try {
|
||||
PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
|
||||
return info.versionCode;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
public static String hashKeyForDisk(String key) {
|
||||
String cacheKey;
|
||||
try {
|
||||
final MessageDigest mDigest = MessageDigest.getInstance("MD5");
|
||||
mDigest.update(key.getBytes());
|
||||
cacheKey = bytesToHexString(mDigest.digest());
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
cacheKey = String.valueOf(key.hashCode());
|
||||
}
|
||||
return cacheKey;
|
||||
}
|
||||
|
||||
public static String bytesToHexString(byte[] bytes) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
String hex = Integer.toHexString(0xFF & bytes[i]);
|
||||
if (hex.length() == 1) {
|
||||
sb.append('0');
|
||||
}
|
||||
sb.append(hex);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static byte[] bitmap2Bytes(Bitmap bm) {
|
||||
if (bm == null) {
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
public static Bitmap bytes2Bitmap(byte[] bytes) {
|
||||
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Drawable → Bitmap
|
||||
*/
|
||||
public 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")
|
||||
public static Drawable bitmap2Drawable(Bitmap bm) {
|
||||
if (bm == null) {
|
||||
return null;
|
||||
}
|
||||
BitmapDrawable bd = new BitmapDrawable(bm);
|
||||
bd.setTargetDensity(bm.getDensity());
|
||||
return new BitmapDrawable(bm);
|
||||
}
|
||||
}
|
||||
144
app/src/main/java/com/uiui/appstore/gson/GsonUtils.java
Normal file
144
app/src/main/java/com/uiui/appstore/gson/GsonUtils.java
Normal file
@@ -0,0 +1,144 @@
|
||||
package com.uiui.appstore.gson;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
public class GsonUtils {
|
||||
//https://blog.csdn.net/zte1055889498/article/details/122400299
|
||||
|
||||
public static JsonObject getJsonObject(String jsonString) {
|
||||
JsonObject jsonObject = JsonParser.parseString(jsonString).getAsJsonObject();
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
private static final Gson gson;
|
||||
|
||||
static {
|
||||
GsonBuilder builder = new GsonBuilder();
|
||||
builder.registerTypeAdapterFactory(new NullStringToEmptyAdapterFactory());
|
||||
builder.registerTypeAdapter(Integer.class, new IntegerDefault0Adapter());
|
||||
builder.registerTypeAdapter(int.class, new IntegerDefault0Adapter());
|
||||
builder.disableHtmlEscaping();
|
||||
builder.enableComplexMapKeySerialization();
|
||||
// builder.excludeFieldsWithoutExposeAnnotation();
|
||||
builder.setDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
gson = builder.create();
|
||||
}
|
||||
|
||||
public static Type makeJavaType(Type rawType, Type... typeArguments) {
|
||||
return TypeToken.getParameterized(rawType, typeArguments).getType();
|
||||
}
|
||||
|
||||
public static String toString(Object value) {
|
||||
if (Objects.isNull(value)) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof String) {
|
||||
return (String) value;
|
||||
}
|
||||
return toJSONString(value);
|
||||
}
|
||||
|
||||
public static String toJSONString(Object value) {
|
||||
return gson.toJson(value);
|
||||
}
|
||||
|
||||
public static String toPrettyString(Object value) {
|
||||
return gson.newBuilder().setPrettyPrinting().create().toJson(value);
|
||||
}
|
||||
|
||||
public static JsonElement fromJavaObject(Object value) {
|
||||
JsonElement result = null;
|
||||
if (Objects.nonNull(value) && (value instanceof String)) {
|
||||
result = parseObject((String) value);
|
||||
} else {
|
||||
result = gson.toJsonTree(value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static JsonElement parseObject(String content) {
|
||||
return JsonParser.parseString(content);
|
||||
}
|
||||
|
||||
public static JsonElement getJsonElement(JsonObject node, String name) {
|
||||
return node.get(name);
|
||||
}
|
||||
|
||||
public static JsonElement getJsonElement(JsonArray node, int index) {
|
||||
return node.get(index);
|
||||
}
|
||||
|
||||
public static <T> T toJavaObject(JsonElement node, Class<T> clazz) {
|
||||
return gson.fromJson(node, clazz);
|
||||
}
|
||||
|
||||
public static <T> T toJavaObject(JsonElement node, Type type) {
|
||||
return gson.fromJson(node, type);
|
||||
}
|
||||
|
||||
public static <T> T toJavaObject(JsonElement node, TypeToken<?> typeToken) {
|
||||
return toJavaObject(node, typeToken.getType());
|
||||
}
|
||||
|
||||
public static <E> List<E> toJavaList(JsonElement node, Class<E> clazz) {
|
||||
return toJavaObject(node, makeJavaType(List.class, clazz));
|
||||
}
|
||||
|
||||
public static List<Object> toJavaList(JsonElement node) {
|
||||
return toJavaObject(node, new TypeToken<List<Object>>() {
|
||||
}.getType());
|
||||
}
|
||||
|
||||
public static <V> Map<String, V> toJavaMap(JsonElement node, Class<V> clazz) {
|
||||
return toJavaObject(node, makeJavaType(Map.class, String.class, clazz));
|
||||
}
|
||||
|
||||
public static Map<String, Object> toJavaMap(JsonElement node) {
|
||||
return toJavaObject(node, new TypeToken<Map<String, Object>>() {
|
||||
}.getType());
|
||||
}
|
||||
|
||||
public static <T> T toJavaObject(String content, Class<T> clazz) {
|
||||
JsonObject jsonObject = getJsonObject(content);
|
||||
String jsonString = jsonObject.toString();
|
||||
return gson.fromJson(jsonString, clazz);
|
||||
}
|
||||
|
||||
public static <T> T toJavaObject(String content, Type type) {
|
||||
return gson.fromJson(content, type);
|
||||
}
|
||||
|
||||
public static <T> T toJavaObject(String content, TypeToken<?> typeToken) {
|
||||
return toJavaObject(content, typeToken.getType());
|
||||
}
|
||||
|
||||
public static <E> List<E> toJavaList(String content, Class<E> clazz) {
|
||||
return toJavaObject(content, makeJavaType(List.class, clazz));
|
||||
}
|
||||
|
||||
public static List<Object> toJavaList(String content) {
|
||||
return toJavaObject(content, new TypeToken<List<Object>>() {
|
||||
}.getType());
|
||||
}
|
||||
|
||||
public static <V> Map<String, V> toJavaMap(String content, Class<V> clazz) {
|
||||
return toJavaObject(content, makeJavaType(Map.class, String.class, clazz));
|
||||
}
|
||||
|
||||
public static Map<String, Object> toJavaMap(String content) {
|
||||
return toJavaObject(content, new TypeToken<Map<String, Object>>() {
|
||||
}.getType());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.uiui.appstore.gson;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class IntegerDefault0Adapter implements JsonSerializer<Integer>, JsonDeserializer<Integer> {
|
||||
@Override
|
||||
public Integer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
try {
|
||||
if (json.getAsString().equals("")) {
|
||||
return 0;
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
try {
|
||||
return json.getAsInt();
|
||||
} catch (NumberFormatException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(Integer src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
return new JsonPrimitive(src);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.uiui.appstore.gson;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class NullStringToEmptyAdapterFactory<T> implements TypeAdapterFactory {
|
||||
@Override
|
||||
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
|
||||
|
||||
Class<T> rawType = (Class<T>) type.getRawType();
|
||||
if (rawType != String.class) {
|
||||
return null;
|
||||
}
|
||||
return (TypeAdapter<T>) new StringAdapter();
|
||||
}
|
||||
|
||||
public static class StringAdapter extends TypeAdapter<String> {
|
||||
@Override
|
||||
public String read(JsonReader reader) throws IOException {
|
||||
if (reader.peek() == JsonToken.NULL) {
|
||||
reader.nextNull();
|
||||
return "";
|
||||
}
|
||||
return reader.nextString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(JsonWriter writer, String value) throws IOException {
|
||||
if (value == null) {
|
||||
writer.nullValue();
|
||||
return;
|
||||
}
|
||||
writer.value(value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
134
app/src/main/java/com/uiui/appstore/manager/ConnectManager.java
Normal file
134
app/src/main/java/com/uiui/appstore/manager/ConnectManager.java
Normal file
@@ -0,0 +1,134 @@
|
||||
package com.uiui.appstore.manager;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import com.tencent.mmkv.MMKV;
|
||||
import com.uiui.appstore.utils.TimeUtils;
|
||||
|
||||
public class ConnectManager {
|
||||
private static final String TAG = ConnectManager.class.getSimpleName();
|
||||
|
||||
|
||||
public static final long ONE_MINUTES_TIME = 60 * 1000;
|
||||
public static final long FIFTEEN_MINUTES_TIME = ONE_MINUTES_TIME * 15;
|
||||
public static final long HALF_HOUR_TIME = FIFTEEN_MINUTES_TIME * 2;
|
||||
public static final long ONE_HOUR_TIME = HALF_HOUR_TIME * 2;
|
||||
public static final long SIX_HOUR_TIME = ONE_HOUR_TIME * 6;
|
||||
public static final long HALF_DAY_TIME = SIX_HOUR_TIME * 2;
|
||||
public static final long ONE_DAY_TIME = HALF_DAY_TIME * 2;
|
||||
|
||||
/*重启后连接成功的时间*/
|
||||
public static final String REBOOT_LAST_ONNECT_TIME = "reboot_last_connect_time";
|
||||
/*WiFi连接后连接成功的时间*/
|
||||
public static final String WIFI_LAST_CONNECT_TIME = "WiFi_last_connect_time";
|
||||
/*打开设备信息连接成功的时间*/
|
||||
public static final String OPENINFO_LAST_ONNECT_TIME = "opneinfo_last_connect_time";
|
||||
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private static ConnectManager sInstance;
|
||||
private Context mContext;
|
||||
private MMKV mMMKV = MMKV.defaultMMKV();
|
||||
|
||||
private ConnectManager(Context context) {
|
||||
if (context == null) {
|
||||
throw new RuntimeException("Context is NULL");
|
||||
}
|
||||
this.mContext = context;
|
||||
|
||||
}
|
||||
|
||||
public static void init(Context context) {
|
||||
if (sInstance == null) {
|
||||
Log.e(TAG, "init: ");
|
||||
sInstance = new ConnectManager(context);
|
||||
}
|
||||
}
|
||||
|
||||
public static ConnectManager getInstance() {
|
||||
if (sInstance == null) {
|
||||
throw new IllegalStateException("You must be init ConnectManager first");
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
public long getConnectModeTime(ConnectMode connectMode) {
|
||||
long time = 0;
|
||||
switch (connectMode) {
|
||||
case DEFAULT:
|
||||
time = 0;
|
||||
break;
|
||||
case ONE_MINUTE:
|
||||
time = ONE_MINUTES_TIME;
|
||||
break;
|
||||
case FIFTEEN_MINUTES:
|
||||
time = FIFTEEN_MINUTES_TIME;
|
||||
break;
|
||||
case HALF_HOUR:
|
||||
time = HALF_HOUR_TIME;
|
||||
break;
|
||||
case ONE_HOUR:
|
||||
time = ONE_HOUR_TIME;
|
||||
break;
|
||||
case SIX_HOUR:
|
||||
time = SIX_HOUR_TIME;
|
||||
break;
|
||||
case HALF_DAY:
|
||||
time = HALF_DAY_TIME;
|
||||
break;
|
||||
case ONE_DAY:
|
||||
time = ONE_DAY_TIME;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
public boolean isNeedConnect(String key, ConnectMode connectMode) {
|
||||
long nowTime = System.currentTimeMillis();
|
||||
long lastTime = mMMKV.decodeLong(key, 0);
|
||||
long intervalTime = getConnectModeTime(connectMode);
|
||||
//防止一分钟内重复请求
|
||||
return nowTime - lastTime > intervalTime && nowTime - lastTime > ONE_MINUTES_TIME;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return 重启后是否连接
|
||||
*/
|
||||
public boolean isRebootFistConnect() {
|
||||
long rebootTime = mMMKV.decodeLong(REBOOT_LAST_ONNECT_TIME, 0);
|
||||
//只在开机后15内连接,其他情况为service重启
|
||||
long time = System.currentTimeMillis() - rebootTime;
|
||||
return time < 15 * 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 今天WiFi连接是否有连接
|
||||
*/
|
||||
public boolean isWiFiFistConnect() {
|
||||
long time = mMMKV.decodeLong(WIFI_LAST_CONNECT_TIME, 0);
|
||||
return !TimeUtils.isTodayTime(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 今天打开设备信息后是否连接
|
||||
*/
|
||||
public boolean isOpenInfoFistConnect() {
|
||||
long time = mMMKV.decodeLong(OPENINFO_LAST_ONNECT_TIME, 0);
|
||||
return !TimeUtils.isTodayTime(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WiFiAlias
|
||||
* @return 今天切换WiFi后是否连接
|
||||
*/
|
||||
public boolean isWiFiCutoverFistConnect(String WiFiAlias) {
|
||||
long time = mMMKV.decodeLong(WiFiAlias, 0);
|
||||
return !TimeUtils.isTodayTime(time);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
12
app/src/main/java/com/uiui/appstore/manager/ConnectMode.java
Normal file
12
app/src/main/java/com/uiui/appstore/manager/ConnectMode.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package com.uiui.appstore.manager;
|
||||
|
||||
public enum ConnectMode {
|
||||
DEFAULT,
|
||||
ONE_MINUTE,
|
||||
FIFTEEN_MINUTES,
|
||||
HALF_HOUR,
|
||||
ONE_HOUR,
|
||||
SIX_HOUR,
|
||||
HALF_DAY,
|
||||
ONE_DAY,
|
||||
}
|
||||
@@ -1,53 +1,102 @@
|
||||
package com.uiui.appstore.network;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.tencent.android.tpush.XGIOperateCallback;
|
||||
import com.tencent.android.tpush.XGPushManager;
|
||||
import com.tencent.mmkv.MMKV;
|
||||
import com.trello.rxlifecycle4.RxLifecycle;
|
||||
import com.trello.rxlifecycle4.android.ActivityEvent;
|
||||
import com.uiui.appstore.bean.AppInfo;
|
||||
import com.uiui.appstore.bean.Banner;
|
||||
import com.uiui.appstore.bean.BaseResponse;
|
||||
import com.uiui.appstore.bean.BatchID;
|
||||
import com.uiui.appstore.disklrucache.CacheHelper;
|
||||
import com.uiui.appstore.gson.GsonUtils;
|
||||
import com.uiui.appstore.manager.ConnectManager;
|
||||
import com.uiui.appstore.manager.ConnectMode;
|
||||
import com.uiui.appstore.network.api.AdminApp;
|
||||
import com.uiui.appstore.network.api.BannerImage;
|
||||
import com.uiui.appstore.network.api.DownloadApp;
|
||||
import com.uiui.appstore.network.api.GetBanner;
|
||||
import com.uiui.appstore.network.api.GetBatchApi;
|
||||
import com.uiui.appstore.network.api.NewestAppUpdate;
|
||||
import com.uiui.appstore.network.api.QueryAllApp;
|
||||
import com.uiui.appstore.network.api.QueryPackageApp;
|
||||
import com.uiui.appstore.network.api.SNInfo;
|
||||
import com.uiui.appstore.network.api.SearchApp;
|
||||
import com.uiui.appstore.network.api.QueryPackageApp;
|
||||
import com.uiui.appstore.network.interceptor.RepeatRequestInterceptor;
|
||||
import com.uiui.appstore.utils.JGYUtils;
|
||||
import com.uiui.appstore.utils.Utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.reactivex.rxjava3.core.Observable;
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.rxjava3.annotations.NonNull;
|
||||
import io.reactivex.rxjava3.core.Observable;
|
||||
import io.reactivex.rxjava3.core.Observer;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
import io.reactivex.rxjava3.subjects.BehaviorSubject;
|
||||
import okhttp3.Cache;
|
||||
import okhttp3.OkHttpClient;
|
||||
import retrofit2.CallAdapter;
|
||||
import retrofit2.Converter;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
|
||||
public class NetInterfaceManager {
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private static NetInterfaceManager sInstance;
|
||||
private Context mContext;
|
||||
private static Retrofit mRetrofit;
|
||||
private Retrofit mRetrofit;
|
||||
private MMKV mMMKV = MMKV.defaultMMKV();
|
||||
private OkHttpClient okHttpClient;
|
||||
private CacheHelper cacheHelper;
|
||||
|
||||
public static final String ROOT_URL = UrlAddress.ROOT_URL;
|
||||
//超时时间
|
||||
private static final int timeOut = 5;
|
||||
// 缓存文件最大限制大小20M
|
||||
private static final long cacheSize = 1024 * 1024 * 64;
|
||||
public static final String CUSTOM_REPEAT_REQ_PROTOCOL = "MY_CUSTOM_REPEAT_REQ_PROTOCOL";
|
||||
public static final String HTTP_KEY = "YTM3YTAxNTJmMmZmNzkyM2E2YzIwZjlhZTc0NzNmMGI=";
|
||||
|
||||
private NetInterfaceManager(Context context) {
|
||||
if (context == null) {
|
||||
throw new RuntimeException("Context is NULL");
|
||||
}
|
||||
this.mContext = context;
|
||||
this.cacheHelper = new CacheHelper(mContext);
|
||||
|
||||
if (null == mRetrofit) {
|
||||
if (okHttpClient == null) {
|
||||
//如果无法生存缓存文件目录,检测权限使用已经加上,检测手机是否把文件读写权限禁止了
|
||||
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||
builder.connectTimeout(timeOut, TimeUnit.SECONDS); // 设置连接超时时间
|
||||
builder.writeTimeout(timeOut, TimeUnit.SECONDS);// 设置写入超时时间
|
||||
builder.readTimeout(timeOut, TimeUnit.SECONDS);// 设置读取数据超时时间
|
||||
builder.retryOnConnectionFailure(true);// 设置进行连接失败重试
|
||||
builder.addInterceptor(new RepeatRequestInterceptor());
|
||||
|
||||
// 设置缓存文件路径
|
||||
String cacheDirectory = getCacheDir() + "/OkHttpCache";
|
||||
Cache cache = new Cache(new File(cacheDirectory), cacheSize);
|
||||
builder.cache(cache);// 设置缓存
|
||||
okHttpClient = builder.build();
|
||||
}
|
||||
|
||||
mRetrofit = new Retrofit.Builder()
|
||||
.client(OK_HTTP_CLIENT)
|
||||
.baseUrl(ROOT_URL)
|
||||
.addConverterFactory(gsonConverterFactory)
|
||||
.addCallAdapterFactory(rxJavaCallAdapterFactory)
|
||||
.client(okHttpClient)
|
||||
.baseUrl(UrlAddress.ROOT_URL)
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -56,7 +105,23 @@ public class NetInterfaceManager {
|
||||
if (sInstance == null) {
|
||||
sInstance = new NetInterfaceManager(context);
|
||||
}
|
||||
}
|
||||
|
||||
private String getCacheDir() {
|
||||
String cachePath;
|
||||
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
|
||||
|| !Environment.isExternalStorageRemovable()) {
|
||||
if (mContext.getExternalCacheDir() != null) {
|
||||
cachePath = mContext.getExternalCacheDir().getPath();
|
||||
} else if (mContext.getExternalFilesDir("cache") != null) {
|
||||
cachePath = mContext.getExternalFilesDir("cache").getPath();
|
||||
} else {
|
||||
cachePath = mContext.getCacheDir().getPath();
|
||||
}
|
||||
} else {
|
||||
cachePath = mContext.getCacheDir().getPath();
|
||||
}
|
||||
return cachePath;
|
||||
}
|
||||
|
||||
public static NetInterfaceManager getInstance() {
|
||||
@@ -66,25 +131,6 @@ public class NetInterfaceManager {
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
private static final long cacheSize = 1024 * 1024 * 32;// 缓存文件最大限制大小20M
|
||||
private static String cacheDirectory = Environment.getExternalStorageDirectory() + "/okttpcaches"; // 设置缓存文件路径
|
||||
private static Cache cache = new Cache(new File(cacheDirectory), cacheSize); //
|
||||
private static final OkHttpClient OK_HTTP_CLIENT;
|
||||
private static final int timeOut = 5;
|
||||
|
||||
static {
|
||||
//如果无法生存缓存文件目录,检测权限使用已经加上,检测手机是否把文件读写权限禁止了
|
||||
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||
builder.connectTimeout(timeOut, TimeUnit.SECONDS); // 设置连接超时时间
|
||||
builder.writeTimeout(timeOut, TimeUnit.SECONDS);// 设置写入超时时间
|
||||
builder.readTimeout(timeOut, TimeUnit.SECONDS);// 设置读取数据超时时间
|
||||
builder.retryOnConnectionFailure(true);// 设置进行连接失败重试
|
||||
builder.cache(cache);// 设置缓存
|
||||
OK_HTTP_CLIENT = builder.build();
|
||||
}
|
||||
|
||||
private static CallAdapter.Factory rxJavaCallAdapterFactory = RxJava3CallAdapterFactory.create();
|
||||
private static Converter.Factory gsonConverterFactory = GsonConverterFactory.create();
|
||||
|
||||
public Observable<BaseResponse<Banner>> getBannerObservable() {
|
||||
return mRetrofit.create(GetBanner.class)
|
||||
@@ -125,12 +171,114 @@ public class NetInterfaceManager {
|
||||
return mRetrofit.create(QueryPackageApp.class);
|
||||
}
|
||||
|
||||
public Observable<BaseResponse<List<AppInfo>>> getAdminAppObservable() {
|
||||
public Observable<BaseResponse<List<AppInfo>>> getAdminAppObservable() {
|
||||
return mRetrofit.create(AdminApp.class).getAdminApp()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread());
|
||||
|
||||
}
|
||||
|
||||
public Observable<BaseResponse<BatchID>> getBatchApiControl() {
|
||||
return mRetrofit.create(GetBatchApi.class)
|
||||
.getBatch(Utils.getSerial())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread());
|
||||
}
|
||||
|
||||
public interface onCompleteCallback {
|
||||
void onComplete();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置推送标签
|
||||
*
|
||||
* @param lifecycle
|
||||
* @param callback
|
||||
*/
|
||||
public void setPushTags(boolean refresh, BehaviorSubject<ActivityEvent> lifecycle, onCompleteCallback callback) {
|
||||
ConnectMode connectMode = ConnectMode.SIX_HOUR;
|
||||
if (refresh) {
|
||||
connectMode = ConnectMode.ONE_HOUR;
|
||||
}
|
||||
if (ConnectManager.getInstance().isNeedConnect(UrlAddress.GET_BATCH, connectMode)) {
|
||||
setPushTags(lifecycle, callback);
|
||||
} else {
|
||||
String jsonString = cacheHelper.getAsString(UrlAddress.GET_BATCH);
|
||||
//为 "" 是已经请求成功的
|
||||
if (jsonString == null) {
|
||||
setPushTags(lifecycle, callback);
|
||||
} else {
|
||||
Set tagSets = mMMKV.decodeStringSet(UrlAddress.GET_BATCH);
|
||||
Log.e("setPushTags", "tagSets: " + tagSets);
|
||||
clearAndAppendTags(tagSets);
|
||||
callback.onComplete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setPushTags(BehaviorSubject<ActivityEvent> lifecycle, onCompleteCallback callback) {
|
||||
Set set = new HashSet();
|
||||
JGYUtils.getInstance().getAppPlatform(platform -> {
|
||||
if (platform == JGYUtils.MTKPlatform) {
|
||||
set.add(JGYUtils.MTKTag);
|
||||
} else if (platform == JGYUtils.ZhanruiPlatform) {
|
||||
set.add(JGYUtils.ZhanruiTag);
|
||||
}
|
||||
});
|
||||
getBatchApiControl()
|
||||
.compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY))
|
||||
.subscribe(new Observer<BaseResponse<BatchID>>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
Log.e("setPushTags", "onSubscribe: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull BaseResponse<BatchID> response) {
|
||||
Log.e("setPushTags", "onNext: " + response);
|
||||
if (response.code == 200) {
|
||||
BatchID batchID = response.data;
|
||||
String batch = batchID.getBatch_id();
|
||||
Log.e("setPushTags", "onNext: " + batch);
|
||||
if (!TextUtils.isEmpty(batch)) {
|
||||
set.add(batch);
|
||||
} else {
|
||||
Log.e("setPushTags", "onNext: " + "batch empty");
|
||||
}
|
||||
cacheHelper.put(UrlAddress.GET_BATCH, GsonUtils.toJSONString(response.data));
|
||||
} else {
|
||||
cacheHelper.put(UrlAddress.GET_BATCH, "");
|
||||
}
|
||||
mMMKV.encode(UrlAddress.GET_BATCH, set);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
Log.e("setPushTags", "onError: " + e.getMessage());
|
||||
onComplete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Log.e("setPushTags", "onComplete: ");
|
||||
Log.e("setPushTags", "tagSets: " + set);
|
||||
clearAndAppendTags(set);
|
||||
callback.onComplete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void clearAndAppendTags(Set tagSets) {
|
||||
XGPushManager.clearAndAppendTags(mContext, "clearAndAppendTags :" + System.currentTimeMillis(), tagSets, new XGIOperateCallback() {
|
||||
@Override
|
||||
public void onSuccess(Object o, int i) {
|
||||
Log.e("setPushTags", "onSuccess: " + o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(Object o, int i, String s) {
|
||||
Log.e("setPushTags", "onFail: " + o);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.uiui.appstore.network.api;
|
||||
|
||||
import com.uiui.appstore.bean.BaseResponse;
|
||||
import com.uiui.appstore.bean.BatchID;
|
||||
import com.uiui.appstore.network.UrlAddress;
|
||||
|
||||
import io.reactivex.rxjava3.core.Observable;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.Query;
|
||||
|
||||
public interface GetBatchApi {
|
||||
@GET(UrlAddress.GET_BATCH)
|
||||
Observable<BaseResponse<BatchID>> getBatch(
|
||||
@Query("sn") String sn
|
||||
);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package com.uiui.appstore.network.interceptor;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
import com.uiui.appstore.BuildConfig;
|
||||
import com.uiui.appstore.utils.MD5Util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.Protocol;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.ResponseBody;
|
||||
import okio.Buffer;
|
||||
|
||||
/**
|
||||
* v1.0 2022-07-15 16:16:52
|
||||
*/
|
||||
public class RepeatRequestInterceptor implements Interceptor {
|
||||
private static final String TAG = RepeatRequestInterceptor.class.getSimpleName();
|
||||
|
||||
private final ConcurrentHashMap<String, Long> requestIdsMap = new ConcurrentHashMap<>();
|
||||
public static final String REPEAT_REQUEST_PROTOCOL = "OKHTTP_REPEAT_REQUEST_PROTOCOL";
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Response intercept(@NotNull Chain chain) throws IOException {
|
||||
Request request = chain.request();
|
||||
Response response = chain.proceed(request);
|
||||
ResponseBody responseBody = response.body();
|
||||
|
||||
//会消费请求,导致请求多次
|
||||
String content = responseBody.string();
|
||||
// Response copy = response.newBuilder().body(responseBody).build();
|
||||
ResponseBody copy = ResponseBody.create(responseBody.contentType(), content);
|
||||
if (BuildConfig.DEBUG) {
|
||||
// Log.e(TAG, "请求体返回:| Response: " + request.url().encodedPath() + "\t body: " + content);
|
||||
}
|
||||
//相同的请求
|
||||
String requestKey = MD5Util.getUpperMD5Str(request.method() + request.url().toString() + requestBodyToString(request.body()));
|
||||
long time = System.currentTimeMillis();//请求时间
|
||||
try {
|
||||
if (requestIdsMap.size() > 0 && requestIdsMap.containsKey(requestKey)) {
|
||||
log("重复请求:", requestKey, request);
|
||||
//下面这行写了不会抛出onerror
|
||||
// chain.call().cancel();
|
||||
return new Response.Builder()
|
||||
.protocol(Protocol.get(REPEAT_REQUEST_PROTOCOL))
|
||||
.request(request) //multi thread
|
||||
.build();
|
||||
}
|
||||
requestIdsMap.put(requestKey, time);
|
||||
log("注册请求:", requestKey, request);
|
||||
// RepeatRequestInterceptor.Builder builder = request.newBuilder();
|
||||
// builder.addHeader("header", jsonObject.toString());
|
||||
return response.newBuilder().body(copy).build();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "intercept: " + e.getMessage());
|
||||
throw e;
|
||||
} finally {
|
||||
if (requestIdsMap.containsKey(requestKey) && requestIdsMap.containsValue(time)) {//请求任务完成删除map中的数据
|
||||
requestIdsMap.remove(requestKey);
|
||||
log("移除请求:", requestKey, request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void log(String action, String requestKey, Request request) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
Log.e("REPEAT-REQUEST", action + requestKey + " Method @" + request.method() + " --- " + " URL = " + request.url().encodedPath() + "\t" + bodyToString(request));
|
||||
} else {
|
||||
Log.e("REPEAT-REQUEST", action + requestKey + " Method @" + request.method());
|
||||
}
|
||||
}
|
||||
|
||||
private static String bodyToString(final Request request) {
|
||||
try {
|
||||
final Request copy = request.newBuilder().build();
|
||||
final Buffer buffer = new Buffer();
|
||||
copy.body().writeTo(buffer);
|
||||
if (buffer.size() > 4096) {
|
||||
return "-too long";
|
||||
}
|
||||
return buffer.readUtf8();
|
||||
} catch (Exception e) {
|
||||
return "-";
|
||||
}
|
||||
}
|
||||
|
||||
private static String requestBodyToString(RequestBody body) {
|
||||
try {
|
||||
final Buffer buffer = new Buffer();
|
||||
body.writeTo(buffer);
|
||||
if (buffer.size() > 4096) {
|
||||
return "-too long";
|
||||
}
|
||||
return buffer.readUtf8();
|
||||
} catch (Exception e) {
|
||||
return "-";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import com.uiui.appstore.service.GuardService;
|
||||
import com.uiui.appstore.service.InitJpushServer;
|
||||
import com.uiui.appstore.service.main.MainService;
|
||||
import com.uiui.appstore.service.StepService;
|
||||
import com.uiui.appstore.utils.JGYUtils;
|
||||
import com.uiui.appstore.utils.LogUtils;
|
||||
@@ -23,7 +23,7 @@ public class BootReceiver extends BroadcastReceiver {
|
||||
break;
|
||||
case Intent.ACTION_BOOT_COMPLETED:
|
||||
case BOOT_COMPLETED:
|
||||
context.startService(new Intent(context, InitJpushServer.class));
|
||||
context.startService(new Intent(context, MainService.class));
|
||||
context.startService(new Intent(context, StepService.class));
|
||||
context.startService(new Intent(context, GuardService.class));
|
||||
LogUtils.e("StoreBootReceiver", "booting BootReceiver");
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
package com.uiui.appstore.service;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
import com.uiui.appstore.KeepAliveConnection;
|
||||
import com.uiui.appstore.network.HTTPInterface;
|
||||
import com.uiui.appstore.utils.SPUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.reactivex.rxjava3.core.Observable;
|
||||
import io.reactivex.rxjava3.core.ObservableEmitter;
|
||||
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
|
||||
import io.reactivex.rxjava3.core.Observer;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
|
||||
public class InitJpushServer extends Service {
|
||||
public InitJpushServer() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
// TODO: Return the communication channel to the service.
|
||||
// throw new UnsupportedOperationException("Not yet implemented");
|
||||
return new KeepAliveConnection.Stub() {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
start.onstar(System.currentTimeMillis());
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
Observable.create(subscribe)
|
||||
.throttleFirst(3, TimeUnit.HOURS)
|
||||
.subscribe(timeObserver);
|
||||
File file = new File(DOWNLOAD_PATH);
|
||||
if (file.isFile() || !file.exists()) {
|
||||
file.delete();
|
||||
file.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
private interface Start {
|
||||
void onstar(long time);
|
||||
}
|
||||
|
||||
private Start start;
|
||||
|
||||
private final ObservableOnSubscribe<Long> subscribe = new ObservableOnSubscribe<Long>() {
|
||||
@Override
|
||||
public void subscribe(ObservableEmitter emitter) throws Exception {
|
||||
start = new Start() {
|
||||
@Override
|
||||
public void onstar(long time) {
|
||||
emitter.onNext(time);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
private Observer<Long> timeObserver = new Observer<Long>() {
|
||||
@Override
|
||||
public void onSubscribe(Disposable d) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(Long aLong) {
|
||||
Log.e("TimeObserver", "onNext: " + aLong);
|
||||
int isLogined = (int) SPUtils.get(InitJpushServer.this, "isLogined", 2);
|
||||
if (isLogined == 2) return;
|
||||
HTTPInterface.checkUpdate(InitJpushServer.this);
|
||||
HTTPInterface.checkUpdate(InitJpushServer.this, "com.uiui.sn");
|
||||
// HTTPInterface.checkUpdate(InitJpushServer.this, "com.uiui.os");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
private final String DOWNLOAD_PATH = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + File.separator + "jgy";
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.uiui.appstore.service.main;
|
||||
|
||||
import com.uiui.appstore.base.BasePresenter;
|
||||
import com.uiui.appstore.base.BaseView;
|
||||
|
||||
public class MainSContact {
|
||||
public interface MainView extends BaseView {
|
||||
void setSnTag();
|
||||
}
|
||||
|
||||
interface Presenter extends BasePresenter<MainView> {
|
||||
//获取设备信息
|
||||
void getSnTag();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.uiui.appstore.service.main;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.trello.rxlifecycle4.android.ActivityEvent;
|
||||
import com.uiui.appstore.network.NetInterfaceManager;
|
||||
|
||||
import io.reactivex.rxjava3.subjects.BehaviorSubject;
|
||||
|
||||
public class MainSPresenter implements MainSContact.Presenter {
|
||||
private String TAG = MainSPresenter.class.getSimpleName();
|
||||
|
||||
private MainSContact.MainView mView;
|
||||
private Context mContext;
|
||||
|
||||
public MainSPresenter(Context context) {
|
||||
this.mContext = context;
|
||||
}
|
||||
|
||||
private BehaviorSubject<ActivityEvent> lifecycle;
|
||||
|
||||
public void setLifecycle(BehaviorSubject<ActivityEvent> lifecycle) {
|
||||
this.lifecycle = lifecycle;
|
||||
}
|
||||
|
||||
public BehaviorSubject<ActivityEvent> getLifecycle() {
|
||||
return lifecycle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachView(MainSContact.MainView view) {
|
||||
this.mView = view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detachView() {
|
||||
this.mView = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSnTag() {
|
||||
NetInterfaceManager.getInstance().setPushTags(true, getLifecycle(), new NetInterfaceManager.onCompleteCallback() {
|
||||
@Override
|
||||
public void onComplete() {
|
||||
mView.setSnTag();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
package com.uiui.appstore.service.main;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.Environment;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
import com.blankj.utilcode.util.NetworkUtils;
|
||||
import com.trello.rxlifecycle4.LifecycleProvider;
|
||||
import com.trello.rxlifecycle4.LifecycleTransformer;
|
||||
import com.trello.rxlifecycle4.RxLifecycle;
|
||||
import com.trello.rxlifecycle4.android.ActivityEvent;
|
||||
import com.trello.rxlifecycle4.android.RxLifecycleAndroid;
|
||||
import com.uiui.appstore.KeepAliveConnection;
|
||||
import com.uiui.appstore.network.HTTPInterface;
|
||||
import com.uiui.appstore.utils.SPUtils;
|
||||
import com.uiui.appstore.utils.ToastUtil;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.reactivex.rxjava3.core.Observable;
|
||||
import io.reactivex.rxjava3.core.ObservableEmitter;
|
||||
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
|
||||
import io.reactivex.rxjava3.core.Observer;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
import io.reactivex.rxjava3.subjects.BehaviorSubject;
|
||||
|
||||
public class MainService extends Service implements MainSContact.MainView, NetworkUtils.OnNetworkStatusChangedListener, LifecycleProvider<ActivityEvent> {
|
||||
private String TAG = MainService.class.getSimpleName();
|
||||
|
||||
private final String DOWNLOAD_PATH = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + File.separator + "jgy";
|
||||
|
||||
public MainSPresenter mPresenter;
|
||||
|
||||
private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();
|
||||
|
||||
|
||||
@Override
|
||||
public void onDisconnected() {
|
||||
Log.e(TAG, "网络未连接");
|
||||
ToastUtil.show("网络未连接");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnected(NetworkUtils.NetworkType networkType) {
|
||||
Log.e(TAG, "网络已连接");
|
||||
ToastUtil.show("网络已连接");
|
||||
mPresenter.getSnTag();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Observable<ActivityEvent> lifecycle() {
|
||||
return lifecycleSubject.hide();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> LifecycleTransformer<T> bindUntilEvent(@NotNull ActivityEvent event) {
|
||||
return RxLifecycle.bindUntilEvent(lifecycleSubject, event);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> LifecycleTransformer<T> bindToLifecycle() {
|
||||
return RxLifecycleAndroid.bindActivity(lifecycleSubject);
|
||||
}
|
||||
|
||||
public MainService() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
// TODO: Return the communication channel to the service.
|
||||
// throw new UnsupportedOperationException("Not yet implemented");
|
||||
return new KeepAliveConnection.Stub() {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
start.onstar(System.currentTimeMillis());
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
lifecycleSubject.onNext(ActivityEvent.CREATE);
|
||||
mPresenter = new MainSPresenter(this);
|
||||
mPresenter.setLifecycle(lifecycleSubject);
|
||||
mPresenter.attachView(this);
|
||||
NetworkUtils.registerNetworkStatusChangedListener(this);
|
||||
|
||||
Observable.create(subscribe)
|
||||
.throttleFirst(3, TimeUnit.HOURS)
|
||||
.subscribe(timeObserver);
|
||||
File file = new File(DOWNLOAD_PATH);
|
||||
if (file.isFile() || !file.exists()) {
|
||||
file.delete();
|
||||
file.mkdirs();
|
||||
}
|
||||
mPresenter.getSnTag();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
lifecycleSubject.onNext(ActivityEvent.DESTROY);
|
||||
NetworkUtils.unregisterNetworkStatusChangedListener(this);
|
||||
mPresenter.detachView();
|
||||
}
|
||||
|
||||
private interface Start {
|
||||
void onstar(long time);
|
||||
}
|
||||
|
||||
private Start start;
|
||||
|
||||
private final ObservableOnSubscribe<Long> subscribe = new ObservableOnSubscribe<Long>() {
|
||||
@Override
|
||||
public void subscribe(ObservableEmitter emitter) throws Exception {
|
||||
start = new Start() {
|
||||
@Override
|
||||
public void onstar(long time) {
|
||||
emitter.onNext(time);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
private Observer<Long> timeObserver = new Observer<Long>() {
|
||||
@Override
|
||||
public void onSubscribe(Disposable d) {
|
||||
Log.e("TimeObserver", "Disposable: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(Long aLong) {
|
||||
Log.e("TimeObserver", "onNext: " + aLong);
|
||||
int isLogined = (int) SPUtils.get(MainService.this, "isLogined", 2);
|
||||
if (isLogined == 2) return;
|
||||
HTTPInterface.checkUpdate(MainService.this);
|
||||
HTTPInterface.checkUpdate(MainService.this, "com.uiui.sn");
|
||||
// HTTPInterface.checkUpdate(InitJpushServer.this, "com.uiui.os");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
Log.e("TimeObserver", "onError: " + e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Log.e("TimeObserver", "onComplete: ");
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void setSnTag() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,15 @@ import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.tencent.android.tpush.NotificationAction;
|
||||
@@ -16,11 +21,16 @@ import com.tencent.android.tpush.XGPushClickedResult;
|
||||
import com.tencent.android.tpush.XGPushRegisterResult;
|
||||
import com.tencent.android.tpush.XGPushShowedResult;
|
||||
import com.tencent.android.tpush.XGPushTextMessage;
|
||||
import com.uiui.appstore.gson.GsonUtils;
|
||||
import com.uiui.appstore.tpush.common.NotificationService;
|
||||
import com.uiui.appstore.tpush.po.XGNotification;
|
||||
import com.uiui.appstore.utils.FileUtils;
|
||||
import com.uiui.appstore.utils.ToastUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class MessageReceiver extends XGPushBaseReceiver {
|
||||
@@ -306,10 +316,33 @@ public class MessageReceiver extends XGPushBaseReceiver {
|
||||
|
||||
switch (title) {
|
||||
case ACTION_FORCE_INSTALLAPK:
|
||||
forceInstallApk(context, extras);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void forceInstallApk(Context context, String jsonString) {
|
||||
if (TextUtils.isEmpty(jsonString)) {
|
||||
return;
|
||||
}
|
||||
JSONObject jsonObject = (JSONObject) JSON.parse(jsonString);
|
||||
final String packages = jsonObject.getString("package");
|
||||
ToastUtil.debugShow("收到应用安装消息:包名" + packages);
|
||||
String url = jsonObject.getString("url");
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
return;
|
||||
}
|
||||
if (Aria.download(this).taskExists(url)) {
|
||||
List<DownloadEntity> entity = Aria.download(this).getDownloadEntity(url);
|
||||
for (DownloadEntity downloadEntity : entity) {
|
||||
Aria.download(this).load(downloadEntity.getId()).cancel(true);
|
||||
}
|
||||
}
|
||||
File file = new File(Environment.getExternalStoragePublicDirectory("Download") + "/Sninfo/apk");
|
||||
file.mkdirs();
|
||||
FileUtils.ariaDownload(context, url, jsonObject);
|
||||
Aria.download(this).resumeAllTask();
|
||||
}
|
||||
}
|
||||
|
||||
112
app/src/main/java/com/uiui/appstore/utils/MD5Util.java
Normal file
112
app/src/main/java/com/uiui/appstore/utils/MD5Util.java
Normal file
@@ -0,0 +1,112 @@
|
||||
package com.uiui.appstore.utils;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class MD5Util {
|
||||
|
||||
public static String packetMD5(String str) {
|
||||
MessageDigest messageDigest = null;
|
||||
try {
|
||||
messageDigest = MessageDigest.getInstance("MD5");
|
||||
|
||||
messageDigest.reset();
|
||||
|
||||
messageDigest.update(str.getBytes("UTF-8"));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
System.out.println("NoSuchAlgorithmException caught!");
|
||||
System.exit(-1);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
byte[] byteArray = messageDigest.digest();
|
||||
|
||||
StringBuffer md5StrBuff = new StringBuffer();
|
||||
|
||||
for (int i = 0; i < byteArray.length; i++) {
|
||||
if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
|
||||
md5StrBuff.append("0").append(
|
||||
Integer.toHexString(0xFF & byteArray[i]));
|
||||
else
|
||||
md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
|
||||
}
|
||||
|
||||
return md5StrBuff.toString();
|
||||
}
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
public static String getUpperMD5Str(String str) {
|
||||
MessageDigest messageDigest = null;
|
||||
|
||||
try {
|
||||
messageDigest = MessageDigest.getInstance("MD5");
|
||||
|
||||
messageDigest.reset();
|
||||
|
||||
messageDigest.update(str.getBytes("UTF-8"));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
System.out.println("NoSuchAlgorithmException caught!");
|
||||
System.exit(-1);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
byte[] byteArray = messageDigest.digest();
|
||||
|
||||
StringBuffer md5StrBuff = new StringBuffer();
|
||||
|
||||
for (int i = 0; i < byteArray.length; i++) {
|
||||
if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
|
||||
md5StrBuff.append("0").append(
|
||||
Integer.toHexString(0xFF & byteArray[i]));
|
||||
else
|
||||
md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
|
||||
}
|
||||
|
||||
return md5StrBuff.toString().toUpperCase();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取16位的MD5 值得
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
@SuppressLint("DefaultLocale")
|
||||
public static String getUpperMD5Str16(String str) {
|
||||
MessageDigest messageDigest = null;
|
||||
|
||||
try {
|
||||
messageDigest = MessageDigest.getInstance("MD5");
|
||||
|
||||
messageDigest.reset();
|
||||
|
||||
messageDigest.update(str.getBytes("UTF-8"));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
System.out.println("NoSuchAlgorithmException caught!");
|
||||
System.exit(-1);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
byte[] byteArray = messageDigest.digest();
|
||||
|
||||
StringBuffer md5StrBuff = new StringBuffer();
|
||||
|
||||
for (int i = 0; i < byteArray.length; i++) {
|
||||
if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
|
||||
md5StrBuff.append("0").append(
|
||||
Integer.toHexString(0xFF & byteArray[i]));
|
||||
else
|
||||
md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
|
||||
}
|
||||
|
||||
return md5StrBuff.toString().toUpperCase().substring(8, 24);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,13 @@
|
||||
package com.uiui.appstore.utils;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
|
||||
public class TimeUtils {
|
||||
@@ -9,4 +16,14 @@ public class TimeUtils {
|
||||
Date date = new Date(millSec);
|
||||
return sdf.format(date);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
public static boolean isTodayTime(long timeStamp) {
|
||||
String time = transferLongToDate(timeStamp);
|
||||
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
LocalDateTime localTime = LocalDateTime.parse(time, dtf);
|
||||
LocalDateTime startTime = LocalDate.now().atTime(0, 0, 0);
|
||||
LocalDateTime endTime = LocalDate.now().atTime(23, 59, 59);
|
||||
return localTime.isAfter(startTime) && localTime.isBefore(endTime);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user