diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml index d730279..e032b2f 100644 --- a/AndroidManifest-common.xml +++ b/AndroidManifest-common.xml @@ -47,6 +47,26 @@ + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + @@ -347,16 +367,16 @@ - - - - - - - - + + + + + + + + + + @@ -366,5 +386,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build.gradle b/build.gradle index 0f3da9e..471fb73 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,6 @@ buildscript { classpath GRADLE_CLASS_PATH classpath PROTOBUF_CLASS_PATH classpath "com.tencent.android.tpns:tpnsplugin:1.8.0" - } } @@ -66,8 +65,8 @@ android { defaultConfig { minSdkVersion 26 targetSdkVersion 28 - versionCode 22 - versionName "3.1" + versionCode 30 + versionName "3.9" ndk { //选择要添加的对应 cpu 类型的 .so 库。 abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' @@ -317,8 +316,10 @@ dependencies { implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0' //gson implementation 'com.google.code.gson:gson:2.9.0' + //磁盘缓存 + implementation 'com.jakewharton:disklrucache:2.0.2' //mmkv - implementation 'com.tencent:mmkv-static:1.2.12' + implementation 'com.tencent:mmkv-static:1.2.13' //腾讯移动推送 TPNS implementation 'com.tencent.tpns:tpns:1.3.2.0-release' //极光推送 diff --git a/res/drawable-hdpi/com_android_appstore.png b/res/drawable-hdpi/com_android_appstore.png index 4a2e0e9..033f1c4 100644 Binary files a/res/drawable-hdpi/com_android_appstore.png and b/res/drawable-hdpi/com_android_appstore.png differ diff --git a/res/drawable-hdpi/com_android_browser.png b/res/drawable-hdpi/com_android_browser.png index f0c9cb1..13554a9 100644 Binary files a/res/drawable-hdpi/com_android_browser.png and b/res/drawable-hdpi/com_android_browser.png differ diff --git a/res/drawable-hdpi/com_android_calculator2.png b/res/drawable-hdpi/com_android_calculator2.png index 1de3635..121fc0c 100644 Binary files a/res/drawable-hdpi/com_android_calculator2.png and b/res/drawable-hdpi/com_android_calculator2.png differ diff --git a/res/drawable-hdpi/com_android_calendar.png b/res/drawable-hdpi/com_android_calendar.png index 07d5a3a..f78cbec 100644 Binary files a/res/drawable-hdpi/com_android_calendar.png and b/res/drawable-hdpi/com_android_calendar.png differ diff --git a/res/drawable-hdpi/com_android_camera.png b/res/drawable-hdpi/com_android_camera.png index ae2d497..b1fffb1 100644 Binary files a/res/drawable-hdpi/com_android_camera.png and b/res/drawable-hdpi/com_android_camera.png differ diff --git a/res/drawable-hdpi/com_android_contacts.png b/res/drawable-hdpi/com_android_contacts.png index fd1f160..ffb7868 100644 Binary files a/res/drawable-hdpi/com_android_contacts.png and b/res/drawable-hdpi/com_android_contacts.png differ diff --git a/res/drawable-hdpi/com_android_deskclock.png b/res/drawable-hdpi/com_android_deskclock.png index 9fbacbb..60f8eba 100644 Binary files a/res/drawable-hdpi/com_android_deskclock.png and b/res/drawable-hdpi/com_android_deskclock.png differ diff --git a/res/drawable-hdpi/com_android_dialer.png b/res/drawable-hdpi/com_android_dialer.png index 335090a..bb1d965 100644 Binary files a/res/drawable-hdpi/com_android_dialer.png and b/res/drawable-hdpi/com_android_dialer.png differ diff --git a/res/drawable-hdpi/com_android_gallery3d_app.png b/res/drawable-hdpi/com_android_gallery3d_app.png index 1e7e536..d75a799 100644 Binary files a/res/drawable-hdpi/com_android_gallery3d_app.png and b/res/drawable-hdpi/com_android_gallery3d_app.png differ diff --git a/res/drawable-hdpi/com_android_mms_ui.png b/res/drawable-hdpi/com_android_mms_ui.png index 3b8ddc5..5893b1d 100644 Binary files a/res/drawable-hdpi/com_android_mms_ui.png and b/res/drawable-hdpi/com_android_mms_ui.png differ diff --git a/res/drawable-hdpi/com_android_music.png b/res/drawable-hdpi/com_android_music.png index 5108f69..792912b 100644 Binary files a/res/drawable-hdpi/com_android_music.png and b/res/drawable-hdpi/com_android_music.png differ diff --git a/res/drawable-hdpi/com_android_settings.png b/res/drawable-hdpi/com_android_settings.png index e3ef259..7e83714 100644 Binary files a/res/drawable-hdpi/com_android_settings.png and b/res/drawable-hdpi/com_android_settings.png differ diff --git a/res/drawable-hdpi/com_android_soundrecorder.png b/res/drawable-hdpi/com_android_soundrecorder.png index 34a2ddd..bedf4ab 100644 Binary files a/res/drawable-hdpi/com_android_soundrecorder.png and b/res/drawable-hdpi/com_android_soundrecorder.png differ diff --git a/res/drawable-hdpi/com_android_stk_stkmain.png b/res/drawable-hdpi/com_android_stk_stkmain.png index 3fe7e67..d1e5d39 100644 Binary files a/res/drawable-hdpi/com_android_stk_stkmain.png and b/res/drawable-hdpi/com_android_stk_stkmain.png differ diff --git a/res/drawable-hdpi/com_android_vdieo.png b/res/drawable-hdpi/com_android_vdieo.png index 313a7cf..0caae58 100644 Binary files a/res/drawable-hdpi/com_android_vdieo.png and b/res/drawable-hdpi/com_android_vdieo.png differ diff --git a/res/drawable-hdpi/com_aoleyun_info.png b/res/drawable-hdpi/com_aoleyun_info.png new file mode 100644 index 0000000..73f16c9 Binary files /dev/null and b/res/drawable-hdpi/com_aoleyun_info.png differ diff --git a/res/drawable-hdpi/com_aoleyun_sn.png b/res/drawable-hdpi/com_aoleyun_sn.png new file mode 100644 index 0000000..7ad7ca7 Binary files /dev/null and b/res/drawable-hdpi/com_aoleyun_sn.png differ diff --git a/res/drawable-hdpi/com_mediatek_filemanager.png b/res/drawable-hdpi/com_mediatek_filemanager.png index 02a37cd..0634bc6 100644 Binary files a/res/drawable-hdpi/com_mediatek_filemanager.png and b/res/drawable-hdpi/com_mediatek_filemanager.png differ diff --git a/res/drawable-hdpi/com_mediatek_fmradio.png b/res/drawable-hdpi/com_mediatek_fmradio.png index fca9011..075277c 100644 Binary files a/res/drawable-hdpi/com_mediatek_fmradio.png and b/res/drawable-hdpi/com_mediatek_fmradio.png differ diff --git a/res/mipmap-hdpi/ic_launcher_home.png b/res/mipmap-hdpi/ic_launcher_home.png index cc24a00..4d6240b 100644 Binary files a/res/mipmap-hdpi/ic_launcher_home.png and b/res/mipmap-hdpi/ic_launcher_home.png differ diff --git a/res/mipmap-mdpi/ic_launcher_home.png b/res/mipmap-mdpi/ic_launcher_home.png index cc24a00..4d6240b 100644 Binary files a/res/mipmap-mdpi/ic_launcher_home.png and b/res/mipmap-mdpi/ic_launcher_home.png differ diff --git a/res/mipmap-xhdpi/ic_launcher_home.png b/res/mipmap-xhdpi/ic_launcher_home.png index cc24a00..4d6240b 100644 Binary files a/res/mipmap-xhdpi/ic_launcher_home.png and b/res/mipmap-xhdpi/ic_launcher_home.png differ diff --git a/res/mipmap-xxhdpi/ic_launcher_home.png b/res/mipmap-xxhdpi/ic_launcher_home.png index cc24a00..4d6240b 100644 Binary files a/res/mipmap-xxhdpi/ic_launcher_home.png and b/res/mipmap-xxhdpi/ic_launcher_home.png differ diff --git a/src/com/aoleyun/os/Launcher.java b/src/com/aoleyun/os/Launcher.java index 170d838..5933329 100644 --- a/src/com/aoleyun/os/Launcher.java +++ b/src/com/aoleyun/os/Launcher.java @@ -24,6 +24,7 @@ import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.app.ActivityOptions; import android.app.WallpaperManager; +import android.app.role.RoleManager; import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetManager; import android.content.ActivityNotFoundException; @@ -49,6 +50,7 @@ import android.os.Handler; import android.os.Parcelable; import android.os.Process; import android.os.StrictMode; +import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.text.method.TextKeyListener; @@ -166,7 +168,9 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Random; +import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; import java.util.function.Predicate; import io.reactivex.Observable; @@ -421,7 +425,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, } if (!isDefaultHome()) { - setDefaultL(); +// setDefaultL(); + setRoleHolderAsUser(this, BuildConfig.APPLICATION_ID); } SharedPreferences sharedPref = getPreferences(MODE_PRIVATE); int i = sharedPref.getInt("SetWallPaper", 0); @@ -572,6 +577,39 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, } } +// private void setDefault() { +// String mRoleName ="android.app.role.HOME"; +// final Intent intent = new Intent(Intent.ACTION_MANAGE_DEFAULT_APP) +// .putExtra(Intent.EXTRA_ROLE_NAME, mRoleName); +// startActivity(intent); +// } + + public void setRoleHolderAsUser(Context context, String packageName) { + String roleName = "android.app.role.HOME"; + boolean add = true; + int flags = 0; + UserHandle user = Process.myUserHandle(); + + Log.i("settingssssssstemf", (add ? "Adding" : "Removing") + " package as role holder, role: " + + roleName + ", package: " + packageName); + + RoleManager roleManager = context.getSystemService(RoleManager.class); + Executor executor = context.getMainExecutor(); + Consumer callback = successful -> { + if (successful) { + Log.d("settingssssssstemf", "Package " + (add ? "added" : "removed") + + " as role holder, role: " + roleName + ", package: " + packageName); + } else { + Log.d("settingssssssstemf", "Failed to " + (add ? "add" : "remove") + + " package as role holder, role: " + roleName + ", package: " + + packageName); + } + }; + + roleManager.addRoleHolderAsUser(roleName, packageName, flags, user, executor, callback); + Log.i("settingssssssstemf", "addRoleHolderAsUser done"); + } + private TimeChangedReceiver mTimeChangedReceiver; //监听时间和日期变化 diff --git a/src/com/aoleyun/os/base/BaseApplication.java b/src/com/aoleyun/os/base/BaseApplication.java index 4572031..4539d8e 100644 --- a/src/com/aoleyun/os/base/BaseApplication.java +++ b/src/com/aoleyun/os/base/BaseApplication.java @@ -5,10 +5,9 @@ import android.app.Application; import android.content.Context; import android.util.Log; -import com.aoleyun.os.BuildConfig; +import com.aoleyun.os.manager.ConnectManager; import com.aoleyun.os.uiuiutils.ToastUtil; import com.aoleyun.os.uiuiutils.Utils; -import com.aoleyun.os.network.HTTPInterface; import com.aoleyun.os.network.NetworkManager; import com.aoleyun.os.network.URLPath; import com.aoleyun.os.uiuiutils.JGYUtils; @@ -46,7 +45,7 @@ public class BaseApplication extends Application { return app; } - public static Context getContext(){ + public static Context getContext() { return context; } @@ -62,30 +61,37 @@ public class BaseApplication extends Application { Aria.init(this); NetworkManager.init(this); ToastUtil.init(this); + ConnectManager.init(this); - initJPush(); + initPush(); } - private void initJPush() { + private void initPush() { // JPushInterface.setDebugMode(BuildConfig.DEBUG); // 设置开启日志,发布时请关闭日志 // JPushInterface.init(this); - XGPushConfig.enableDebug(this,true); + XGPushConfig.enableDebug(this, true); XGPushManager.registerPush(this, new XGIOperateCallback() { @Override public void onSuccess(Object data, int flag) { //token在设备卸载重装的时候有可能会变 - Log.d("TPush", "注册成功,设备token为:" + data); + Log.e("TPush", "注册成功,设备token为:" + data); } @Override public void onFail(Object data, int errCode, String msg) { - Log.d("TPush", "注册失败,错误码:" + errCode + ",错误信息:" + msg); + Log.e("TPush", "注册失败,错误码:" + errCode + ",错误信息:" + msg); } }); - initAliasObservable(); - initTagObservable(); - setJpushAlias(); - setJpushTags(); + NetworkManager.getInstance().setPushTag(true, new NetworkManager.onCompleteCallback() { + @Override + public void onComplete() { + + } + }); +// initAliasObservable(); +// initTagObservable(); +// setJpushAlias(); +// setJpushTags(); } private void initAliasObservable() { diff --git a/src/com/aoleyun/os/disklrucache/CacheHelper.java b/src/com/aoleyun/os/disklrucache/CacheHelper.java new file mode 100644 index 0000000..2800dae --- /dev/null +++ b/src/com/aoleyun/os/disklrucache/CacheHelper.java @@ -0,0 +1,461 @@ +package com.aoleyun.os.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 = 5 * 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); + mMMKV.encode(key, System.currentTimeMillis()); + + 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(); + try { + //s + edit.abort();//write REMOVE + } catch (IOException e1) { + e1.printStackTrace(); + } + } finally { + try { + if (bw != null) { + bw.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public String getAsString(String key) { + Log.e(TAG, "getAsString: " + key); + InputStream inputStream = null; + try { + //write READ + inputStream = get(key); + if (inputStream == null) { + return 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(); + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + } + 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 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(); + } + + 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(); + } + + 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()) { + cachePath = context.getExternalCacheDir().getPath(); + } else { + cachePath = context.getCacheDir().getPath(); + } + return new File(cachePath + File.separator + uniqueName); + } + +} diff --git a/src/com/aoleyun/os/disklrucache/DiskLruCacheHelper.java b/src/com/aoleyun/os/disklrucache/DiskLruCacheHelper.java new file mode 100644 index 0000000..1dbfe10 --- /dev/null +++ b/src/com/aoleyun/os/disklrucache/DiskLruCacheHelper.java @@ -0,0 +1,427 @@ +package com.aoleyun.os.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 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 DiskLruCacheHelper { + private static final String DIR_NAME = "diskCache"; + private static final int MAX_COUNT = 5 * 1024 * 1024; + private static final int DEFAULT_APP_VERSION = 1; + + private static final String TAG = "DiskLruCacheHelper"; + + private DiskLruCache mDiskLruCache; + + public DiskLruCacheHelper(Context context) throws IOException { + mDiskLruCache = generateCache(context, DIR_NAME, MAX_COUNT); + } + + public DiskLruCacheHelper(Context context, String dirName) throws IOException { + mDiskLruCache = generateCache(context, dirName, MAX_COUNT); + } + + public DiskLruCacheHelper(Context context, String dirName, int maxCount) throws IOException { + mDiskLruCache = generateCache(context, dirName, maxCount); + } + + //custom cache dir + public DiskLruCacheHelper(File dir) throws IOException { + mDiskLruCache = generateCache(null, dir, MAX_COUNT); + } + + public DiskLruCacheHelper(Context context, File dir) throws IOException { + mDiskLruCache = generateCache(context, dir, MAX_COUNT); + } + + public DiskLruCacheHelper(Context context, File dir, int maxCount) throws IOException { + mDiskLruCache = generateCache(context, dir, maxCount); + } + + private DiskLruCache generateCache(Context context, File dir, int maxCount) throws IOException { + 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 = DiskLruCache.open( + dir, + appVersion, + DEFAULT_APP_VERSION, + maxCount); + + return diskLruCache; + } + + private DiskLruCache generateCache(Context context, String dirName, int maxCount) throws IOException { + DiskLruCache diskLruCache = DiskLruCache.open( + getDiskCacheDir(context, dirName), + Utils.getAppVersion(context), + DEFAULT_APP_VERSION, + maxCount); + return diskLruCache; + } + // ======================================= + // ============== String 数据 读写 ============= + // ======================================= + + public void put(String key, String 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(); + try { + //s + edit.abort();//write REMOVE + } catch (IOException e1) { + e1.printStackTrace(); + } + } finally { + try { + if (bw != null) + bw.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public String getAsString(String key) { + InputStream inputStream = null; + try { + //write READ + inputStream = get(key); + if (inputStream == null) return 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(); + if (inputStream != null) + try { + inputStream.close(); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + 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 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(); + } + + 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(); + } + + 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()) { + cachePath = context.getExternalCacheDir().getPath(); + } else { + cachePath = context.getCacheDir().getPath(); + } + return new File(cachePath + File.separator + uniqueName); + } + +} diff --git a/src/com/aoleyun/os/disklrucache/Utils.java b/src/com/aoleyun/os/disklrucache/Utils.java new file mode 100644 index 0000000..114d864 --- /dev/null +++ b/src/com/aoleyun/os/disklrucache/Utils.java @@ -0,0 +1,101 @@ +package com.aoleyun.os.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); + } +} \ No newline at end of file diff --git a/src/com/aoleyun/os/icons/IconCache.java b/src/com/aoleyun/os/icons/IconCache.java index d1e03b1..3ce3d9c 100644 --- a/src/com/aoleyun/os/icons/IconCache.java +++ b/src/com/aoleyun/os/icons/IconCache.java @@ -120,15 +120,16 @@ public class IconCache extends BaseIconCache { /** * Fetches high-res icon for the provided ItemInfo and updates the caller when done. + * * @return a request ID that can be used to cancel the request. */ public IconLoadRequest updateIconInBackground(final ItemInfoUpdateReceiver caller, - final ItemInfoWithIcon info) { + final ItemInfoWithIcon info) { Preconditions.assertUIThread(); if (mPendingIconRequestCount <= 0) { LauncherModel.setWorkerPriority(Process.THREAD_PRIORITY_FOREGROUND); } - mPendingIconRequestCount ++; + mPendingIconRequestCount++; IconLoadRequest request = new IconLoadRequest(mWorkerHandler, this::onIconRequestEnd) { @Override @@ -149,7 +150,7 @@ public class IconCache extends BaseIconCache { } private void onIconRequestEnd() { - mPendingIconRequestCount --; + mPendingIconRequestCount--; if (mPendingIconRequestCount <= 0) { LauncherModel.setWorkerPriority(Process.THREAD_PRIORITY_BACKGROUND); } @@ -171,7 +172,7 @@ public class IconCache extends BaseIconCache { * Fill in {@param info} with the icon and label for {@param activityInfo} */ public synchronized void getTitleAndIcon(ItemInfoWithIcon info, - LauncherActivityInfo activityInfo, boolean useLowResIcon) { + LauncherActivityInfo activityInfo, boolean useLowResIcon) { // If we already have activity info, no need to use package icon getTitleAndIcon(info, () -> activityInfo, false, useLowResIcon); } @@ -229,10 +230,13 @@ public class IconCache extends BaseIconCache { info.contentDescription = entry.contentDescription; info.applyFrom((entry.icon == null) ? getDefaultIcon(info.user) : entry); } + private List appClassNameList = new ArrayList() { { - this.add("com.android.appstore");//应用市场 - this.add("com.android.browser.BrowserActivity");//浏览器 + this.add("com.aoleyun.appstore.activity.SplashActivity");//应用市场 + this.add("com.aoleyun.browser.BrowserActivity");//浏览器 + this.add("com.aoleyun.sn.activity.SplashActivity");// + this.add("com.aoleyun.info.activity.main.MainActivity");// this.add("com.android.calculator2.Calculator");//计算器 this.add("com.android.calendar.AllInOneActivity");//日历 this.add("com.android.camera.CameraLauncher");//相机 @@ -260,6 +264,8 @@ public class IconCache extends BaseIconCache { private List appIconList = new ArrayList() {{ this.add("com_android_appstore"); this.add("com_android_browser"); + this.add("com_aoleyun_sn"); + this.add("com_aoleyun_info"); this.add("com_android_calculator2"); this.add("com_android_calendar"); this.add("com_android_camera"); @@ -294,7 +300,7 @@ public class IconCache extends BaseIconCache { if (null != info) { String name = info.getComponentName().getClassName(); -// Log.e("fht", "getDeskClockIcon:"+name); + Log.e("getFullResIcon", "getDeskClockIcon: " + name); if (appClassNameList.indexOf(info.getComponentName().getClassName()) == -1) { icon = BitmapUtils.getRoundedBitmap(mIconProvider.getIcon(info, mIconDpi, flattenDrawable), mContext); } else { diff --git a/src/com/aoleyun/os/manager/ConnectManager.java b/src/com/aoleyun/os/manager/ConnectManager.java new file mode 100644 index 0000000..2a33897 --- /dev/null +++ b/src/com/aoleyun/os/manager/ConnectManager.java @@ -0,0 +1,134 @@ +package com.aoleyun.os.manager; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.util.Log; + +import com.aoleyun.os.uiuiutils.TimeUtils; +import com.tencent.mmkv.MMKV; + +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); + } + + +} diff --git a/src/com/aoleyun/os/manager/ConnectMode.java b/src/com/aoleyun/os/manager/ConnectMode.java new file mode 100644 index 0000000..731e298 --- /dev/null +++ b/src/com/aoleyun/os/manager/ConnectMode.java @@ -0,0 +1,12 @@ +package com.aoleyun.os.manager; + +public enum ConnectMode { + DEFAULT, + ONE_MINUTE, + FIFTEEN_MINUTES, + HALF_HOUR, + ONE_HOUR, + SIX_HOUR, + HALF_DAY, + ONE_DAY, +} \ No newline at end of file diff --git a/src/com/aoleyun/os/model/LoaderTask.java b/src/com/aoleyun/os/model/LoaderTask.java index f545aac..3cc2d39 100644 --- a/src/com/aoleyun/os/model/LoaderTask.java +++ b/src/com/aoleyun/os/model/LoaderTask.java @@ -73,6 +73,7 @@ import com.aoleyun.os.logging.FileLog; import com.aoleyun.os.provider.ImportDataTask; import com.aoleyun.os.shortcuts.DeepShortcutManager; import com.aoleyun.os.shortcuts.ShortcutKey; +import com.aoleyun.os.uiuiutils.JGYUtils; import com.aoleyun.os.util.ComponentKey; import com.aoleyun.os.util.LooperIdleLock; import com.aoleyun.os.util.MultiHashMap; @@ -303,34 +304,45 @@ public class LoaderTask implements Runnable { //add for load all app on workspace private void verifyApplications() { final Context context = mApp.getContext(); + ContentResolver crv = context.getContentResolver(); ArrayList> installQueue = new ArrayList<>(); final List profiles = mUserManager.getUserProfiles(); - String whiteList = Settings.System.getString(context.getContentResolver(), "only_jgy_shortcut_list"); + String whiteList = Settings.System.getString(crv, "only_jgy_shortcut_list"); Log.e("verifyApplications", "whiteList: " + whiteList); + int qch_unlock_ipad = Settings.System.getInt(crv, "qch_unlock_ipad", 0); + Log.e("verifyApplications", "qch_unlock_ipad: " + qch_unlock_ipad); + int desktop_clear = Settings.Global.getInt(crv, "desktop_clear", 0); + if (qch_unlock_ipad == 1 && desktop_clear != 1) { + Settings.Global.putInt(crv, "desktop_clear", 1); + JGYUtils.getInstance().cleanAoleLauncher3Cache(); + } for (UserHandle user : profiles) { final List apps = mLauncherApps.getActivityList(null, user); ArrayList added = new ArrayList(); synchronized (this) { + for (LauncherActivityInfo app : apps) { Log.e("verifyApplications", "AllAPP: " + app.getApplicationInfo().packageName); if (BuildConfig.APPLICATION_ID.equals(app.getApplicationInfo().packageName)) continue; /*系统应用*/ - if ((app.getApplicationFlags() & ApplicationInfo.FLAG_SYSTEM) == 1) { - if (!showApp.contains(app.getApplicationInfo().packageName)) { - Log.e("verifyApplications", "skip1: " + app.getApplicationInfo().packageName); - continue; - } - } else { - if (TextUtils.isEmpty(whiteList)) { + if (qch_unlock_ipad == 0) { + if ((app.getApplicationFlags() & ApplicationInfo.FLAG_SYSTEM) == 1) { if (!showApp.contains(app.getApplicationInfo().packageName)) { - Log.e("verifyApplications", "skip2: " + app.getApplicationInfo().packageName); + Log.e("verifyApplications", "skip1: " + app.getApplicationInfo().packageName); continue; } - } else if (!whiteList.contains(app.getApplicationInfo().packageName)) { - if (!showApp.contains(app.getApplicationInfo().packageName)) { - Log.e("verifyApplications", "skip3: " + app.getApplicationInfo().packageName); - continue; + } else { + if (TextUtils.isEmpty(whiteList)) { + if (!showApp.contains(app.getApplicationInfo().packageName)) { + Log.e("verifyApplications", "skip2: " + app.getApplicationInfo().packageName); + continue; + } + } else if (!whiteList.contains(app.getApplicationInfo().packageName)) { + if (!showApp.contains(app.getApplicationInfo().packageName)) { + Log.e("verifyApplications", "skip3: " + app.getApplicationInfo().packageName); + continue; + } } } } diff --git a/src/com/aoleyun/os/network/NetworkManager.java b/src/com/aoleyun/os/network/NetworkManager.java index 62a09f9..af413db 100644 --- a/src/com/aoleyun/os/network/NetworkManager.java +++ b/src/com/aoleyun/os/network/NetworkManager.java @@ -2,9 +2,16 @@ package com.aoleyun.os.network; import android.content.Context; import android.os.Environment; +import android.text.TextUtils; +import android.util.Log; +import com.aoleyun.os.disklrucache.CacheHelper; +import com.aoleyun.os.manager.ConnectManager; +import com.aoleyun.os.manager.ConnectMode; import com.aoleyun.os.network.bean.AppPasswdBean; import com.aoleyun.os.network.bean.BaseResponse; +import com.aoleyun.os.network.bean.Batch; +import com.aoleyun.os.uiuiutils.JGYUtils; import com.aoleyun.os.uiuiutils.Utils; import com.aoleyun.os.network.api.AddAppLog; import com.aoleyun.os.network.api.AppUsageRecordApi; @@ -13,13 +20,24 @@ import com.aoleyun.os.network.api.GetAppPassword; import com.aoleyun.os.network.api.GetJpushTagsApi; import com.aoleyun.os.network.api.RunningApp; import com.aoleyun.os.network.api.SendScreenshotApi; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.tencent.android.tpush.XGIOperateCallback; +import com.tencent.android.tpush.XGPushManager; +import com.tencent.mmkv.MMKV; import java.io.File; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.concurrent.TimeUnit; import io.reactivex.Observable; +import io.reactivex.Observer; import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.annotations.NonNull; +import io.reactivex.disposables.Disposable; import io.reactivex.schedulers.Schedulers; import okhttp3.Cache; import okhttp3.OkHttpClient; @@ -32,10 +50,15 @@ import retrofit2.converter.gson.GsonConverterFactory; public class NetworkManager { private static NetworkManager sInstance; private Context mContext; + private MMKV mMMKV = MMKV.defaultMMKV(); + private CacheHelper cacheHelper; + private static Retrofit mRetrofit; private NetworkManager(Context context) { this.mContext = context; + this.cacheHelper = new CacheHelper(mContext); + if (null == mRetrofit) { mRetrofit = new Retrofit.Builder() .client(okHttpClient) @@ -109,7 +132,7 @@ public class NetworkManager { * * @return */ - public Observable getJpushTagsObservable() { + public Observable> getJpushTagsObservable() { return mRetrofit.create(GetJpushTagsApi.class) .getJpushTags(Utils.getSerial()) .subscribeOn(Schedulers.io()) @@ -117,7 +140,6 @@ public class NetworkManager { } - public AppUsageRecordApi getAppUsageRecordControl() { return mRetrofit.create(AppUsageRecordApi.class); } @@ -127,4 +149,94 @@ public class NetworkManager { } -} + public interface onCompleteCallback { + void onComplete(); + } + + public void setPushTag(boolean refresh, onCompleteCallback callback) { + ConnectMode connectMode = ConnectMode.ONE_DAY; + if (refresh) { + connectMode = ConnectMode.FIFTEEN_MINUTES; + } + if (ConnectManager.getInstance().isNeedConnect(URLPath.GET_DEVICES_TAGS, connectMode)) { + setPushTag(callback); + } else { + String jsonString = cacheHelper.getAsString(URLPath.GET_DEVICES_TAGS); + //为 "" 是已经请求成功的 + if (jsonString == null) { + setPushTag(callback); + } else { + Set tagSets = mMMKV.decodeStringSet(URLPath.GET_DEVICES_TAGS); + Log.e("setPushTags", "tagSets: " + tagSets); + clearAndAppendTags(tagSets); + callback.onComplete(); + } + } + } + + + public void setPushTag(onCompleteCallback callback) { + Set set = new HashSet(); + JGYUtils.getInstance().getAppPlatform(new JGYUtils.GetAppPlatformCallback() { + @Override + public void AppPlatform(int platform) { + if (platform == JGYUtils.MTKPlatform) { + set.add(JGYUtils.MTKTag); + } else if (platform == JGYUtils.ZhanruiPlatform) { + set.add(JGYUtils.ZhanruiTag); + } + } + }); + getJpushTagsObservable() + .subscribe(new Observer>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("setPushTag", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse response) { + Log.e("setPushTag", "onNext: " + response); + if (response.code == 200) { + String batch = response.data.getBatch(); + cacheHelper.put(URLPath.GET_DEVICES_TAGS, batch); + if (!TextUtils.isEmpty(batch)) { + set.add(batch); + } else { + Log.e("setPushTag", "onNext: " + "batch empty"); + } + } else { + cacheHelper.put(URLPath.GET_DEVICES_TAGS, ""); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("setPushTag", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("setPushTag", "onComplete: "); + mMMKV.encode(URLPath.GET_DEVICES_TAGS, set); + clearAndAppendTags(set); + callback.onComplete(); + } + }); + } + + synchronized private void clearAndAppendTags(Set tagSets) { + XGPushManager.clearAndAppendTags(mContext, "clearAndAppendTags :" + System.currentTimeMillis(), tagSets, new XGIOperateCallback() { + @Override + public void onSuccess(Object o, int i) { + Log.e("clearAndAppendTags", "onSuccess: " + o); + } + + @Override + public void onFail(Object o, int i, String s) { + Log.e("clearAndAppendTags", "onFail: " + o); + } + }); + } +} \ No newline at end of file diff --git a/src/com/aoleyun/os/network/api/GetJpushTagsApi.java b/src/com/aoleyun/os/network/api/GetJpushTagsApi.java index 93a6b78..3aa9507 100644 --- a/src/com/aoleyun/os/network/api/GetJpushTagsApi.java +++ b/src/com/aoleyun/os/network/api/GetJpushTagsApi.java @@ -3,6 +3,7 @@ package com.aoleyun.os.network.api; import com.aoleyun.os.network.bean.BaseResponse; import com.aoleyun.os.network.URLPath; +import com.aoleyun.os.network.bean.Batch; import io.reactivex.Observable; import retrofit2.http.GET; @@ -10,7 +11,7 @@ import retrofit2.http.Query; public interface GetJpushTagsApi { @GET(URLPath.GET_DEVICES_TAGS) - Observable getJpushTags( + Observable> getJpushTags( @Query("sn") String sn ); } diff --git a/src/com/aoleyun/os/network/bean/Batch.java b/src/com/aoleyun/os/network/bean/Batch.java new file mode 100644 index 0000000..9e14b55 --- /dev/null +++ b/src/com/aoleyun/os/network/bean/Batch.java @@ -0,0 +1,17 @@ +package com.aoleyun.os.network.bean; + +import java.io.Serializable; + +public class Batch implements Serializable { + private static final long serialVersionUID = 4284402995241045670L; + + String batch; + + public String getBatch() { + return batch; + } + + public void setBatch(String batch) { + this.batch = batch; + } +} diff --git a/src/com/aoleyun/os/tpush/Constants.java b/src/com/aoleyun/os/tpush/Constants.java new file mode 100644 index 0000000..05d9213 --- /dev/null +++ b/src/com/aoleyun/os/tpush/Constants.java @@ -0,0 +1,17 @@ +package com.aoleyun.os.tpush; + +/** + * Created by chacewang on 2019/7/5. + */ + +public class Constants { + public static final int TEST_LOCAL_NOTIFICATION = 1; + public static final int TEST_NOTIFICATION = 2; + public static final int TEST_SET_TAG = 3; + public static final int TEST_DEL_TAG = 4; + public static final int TEST_SET_ACCOUNT = 5; + public static final int TEST_DEL_ACCOUNT = 6; + + public static final String LOCAL_NOTIFICATION_TITLE = "localtest"; + public static final String TEST_TAG_NAME = "DiagnosisTag"; +} diff --git a/src/com/aoleyun/os/tpush/MessageReceiver.java b/src/com/aoleyun/os/tpush/MessageReceiver.java new file mode 100644 index 0000000..91c2137 --- /dev/null +++ b/src/com/aoleyun/os/tpush/MessageReceiver.java @@ -0,0 +1,320 @@ +package com.aoleyun.os.tpush; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.text.TextUtils; +import android.util.Log; +import android.widget.Toast; + +import com.aoleyun.os.network.HTTPInterface; +import com.aoleyun.os.tpush.common.NotificationService; +import com.aoleyun.os.tpush.po.XGNotification; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.tencent.android.tpush.NotificationAction; +import com.tencent.android.tpush.XGPushBaseReceiver; +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 java.text.SimpleDateFormat; +import java.util.Calendar; + +public class MessageReceiver extends XGPushBaseReceiver { + public static final String UPDATE_LISTVIEW_ACTION = "com.qq.xgdemo.activity.UPDATE_LISTVIEW"; + public static final String TEST_ACTION = "com.qq.xgdemo.activity.TEST_ACTION"; + public static final String LogTag = "xg.test"; + + private static final String TAG = MessageReceiver.class.getSimpleName(); + + /*删除应用*/ + private final String UPDATEPASSWD = "39"; + + + private Context mContext; + private ContentResolver mResolver; + private PackageManager mPackageManager; + + /** + * 消息透传处理 + * + * @param context + * @param message 解析自定义的 JSON + */ + @Override + public void onTextMessage(Context context, XGPushTextMessage message) { + this.mContext = context; + this.mResolver = context.getContentResolver(); + this.mPackageManager = context.getPackageManager(); + String text = "收到消息:" + message.toString(); + // 获取自定义key-value + String customContent = message.getCustomContent(); + if (customContent != null && customContent.length() != 0) { + JsonObject obj = JsonParser.parseString(customContent).getAsJsonObject(); + // key1为前台配置的key + if (!TextUtils.isEmpty(obj.get("key").getAsString())) { + String value = obj.get("key").getAsString(); + Log.d(LogTag, "get custom value:" + value); + } + // ... + } + // APP自主处理消息的过程... + Log.e(LogTag, text); + show(context, text); + processCustomMessage(context, message); + } + + /** + * 通知展示 + * + * @param context + * @param notifiShowedRlt 包含通知的内容 + */ + @Override + public void onNotificationShowedResult(Context context, XGPushShowedResult notifiShowedRlt) { + if (context == null || notifiShowedRlt == null) { + return; + } + XGNotification notific = new XGNotification(); + notific.setMsg_id(notifiShowedRlt.getMsgId()); + notific.setTitle(notifiShowedRlt.getTitle()); + notific.setContent(notifiShowedRlt.getContent()); + // notificationActionType==1为Activity,2为url,3为intent + notific.setNotificationActionType(notifiShowedRlt + .getNotificationActionType()); + // Activity,url,intent都可以通过getActivity()获得 + notific.setActivity(notifiShowedRlt.getActivity()); + notific.setUpdate_time(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") + .format(Calendar.getInstance().getTime())); + NotificationService.getInstance(context).save(notific); + + Intent testIntent = new Intent(TEST_ACTION); + if (notifiShowedRlt.getTitle().equals(Constants.LOCAL_NOTIFICATION_TITLE)) { + testIntent.putExtra("step", Constants.TEST_LOCAL_NOTIFICATION); + } else { + testIntent.putExtra("step", Constants.TEST_NOTIFICATION); + } + context.sendBroadcast(testIntent); + + Intent viewIntent = new Intent(UPDATE_LISTVIEW_ACTION); + context.sendBroadcast(viewIntent); + show(context, "您有1条新消息, " + "通知被展示 , " + notifiShowedRlt.toString()); + Log.d(LogTag, "您有1条新消息, " + "通知被展示 , " + notifiShowedRlt.toString() + ", PushChannel:" + notifiShowedRlt.getPushChannel()); + } + + /** + * 注册回调 + * + * @param context + * @param errorCode 0 为成功,其它为错误码 + */ + @Override + public void onRegisterResult(Context context, int errorCode, XGPushRegisterResult message) { + if (context == null || message == null) { + return; + } + String text = ""; + if (errorCode == XGPushBaseReceiver.SUCCESS) { + // 在这里拿token + String token = message.getToken(); + text = "注册成功1. token:" + token; + } else { + text = message + "注册失败,错误码:" + errorCode; + } + Log.d(LogTag, text); + show(context, text); + } + + /** + * 反注册回调 + * + * @param context + * @param errorCode 0 为成功,其它为错误码 + */ + @Override + public void onUnregisterResult(Context context, int errorCode) { + if (context == null) { + return; + } + String text = ""; + if (errorCode == XGPushBaseReceiver.SUCCESS) { + text = "反注册成功"; + } else { + text = "反注册失败" + errorCode; + } + Log.d(LogTag, text); + show(context, text); + + } + + /** + * 设置标签回调 + * + * @param context + * @param errorCode 0 为成功,其它为错误码 + * @param tagName 设置的 TAG + */ + @Override + public void onSetTagResult(Context context, int errorCode, String tagName) { + if (context == null) { + return; + } + String text = ""; + if (errorCode == XGPushBaseReceiver.SUCCESS) { + text = "\"" + tagName + "\"设置成功"; + } else { + text = "\"" + tagName + "\"设置失败,错误码:" + errorCode; + } + Log.d(LogTag, text); + show(context, text); + + Intent testIntent = new Intent(TEST_ACTION); + testIntent.putExtra("step", Constants.TEST_SET_TAG); + context.sendBroadcast(testIntent); + } + + /** + * 删除标签的回调 + * + * @param context + * @param errorCode 0 为成功,其它为错误码 + * @param tagName 设置的 TAG + */ + @Override + public void onDeleteTagResult(Context context, int errorCode, String tagName) { + if (context == null) { + return; + } + String text = ""; + if (errorCode == XGPushBaseReceiver.SUCCESS) { + text = "\"" + tagName + "\"删除成功"; + } else { + text = "\"" + tagName + "\"删除失败,错误码:" + errorCode; + } + Log.d(LogTag, text); + show(context, text); + + Intent testIntent = new Intent(TEST_ACTION); + testIntent.putExtra("step", Constants.TEST_DEL_TAG); + context.sendBroadcast(testIntent); + } + + /** + * 设置账号回调 + * + * @param context + * @param errorCode 0 为成功,其它为错误码 + * @param account 设置的账号 + */ + @Override + public void onSetAccountResult(Context context, int errorCode, String account) { + Intent testIntent = new Intent(TEST_ACTION); + testIntent.putExtra("step", Constants.TEST_SET_ACCOUNT); + context.sendBroadcast(testIntent); + } + + + /** + * 删除账号回调 + * + * @param context + * @param errorCode 0 为成功,其它为错误码 + * @param account 设置的账号 + */ + @Override + public void onDeleteAccountResult(Context context, int errorCode, String account) { + Intent testIntent = new Intent(TEST_ACTION); + testIntent.putExtra("step", Constants.TEST_DEL_ACCOUNT); + context.sendBroadcast(testIntent); + } + + @Override + public void onSetAttributeResult(Context context, int i, String s) { + + } + + @Override + public void onDeleteAttributeResult(Context context, int i, String s) { + + } + + @Override + public void onQueryTagsResult(Context context, int errorCode, String data, String operateName) { + Log.i(LogTag, "action - onQueryTagsResult, errorCode:" + errorCode + ", operateName:" + operateName + ", data: " + data); + } + + /** + * 通知点击回调 actionType=1为该消息被清除,actionType=0为该消息被点击 + * + * @param context + * @param message 包含被点击通知的内容 + */ + @Override + public void onNotificationClickedResult(Context context, XGPushClickedResult message) { + if (context == null || message == null) { + return; + } + String text = ""; + if (message.getActionType() == NotificationAction.clicked.getType()) { + // 通知在通知栏被点击啦。。。。。 + // APP自己处理点击的相关动作 + // 这个动作可以在activity的onResume也能监听,请看第3点相关内容 + text = "通知被打开 :" + message; + } else if (message.getActionType() == NotificationAction.delete.getType()) { + // 通知被清除啦。。。。 + // APP自己处理通知被清除后的相关动作 + text = "通知被清除 :" + message; + } + Toast.makeText(context, "广播接收到通知被点击:" + message.toString(), + Toast.LENGTH_SHORT).show(); + // 获取自定义key-value + String customContent = message.getCustomContent(); + if (customContent != null && customContent.length() != 0) { + JsonObject obj = JsonParser.parseString(customContent).getAsJsonObject(); + // key1为前台配置的key + if (!TextUtils.isEmpty(obj.get("key").getAsString())) { + String value = obj.get("key").getAsString(); + Log.d(LogTag, "get custom value:" + value); + } + // ... + } + // APP自主处理的过程。。。 + Log.d(LogTag, text); + show(context, text); + } + + private void show(Context context, String text) { +// Toast.makeText(context, text, Toast.LENGTH_SHORT).show(); + } + + private int changeNum(int paramInt) { + return paramInt == 0 ? 1 : 0; + } + + private void processCustomMessage(Context context, XGPushTextMessage message) { + if (context == null || message == null) { + return; + } + + String title = message.getTitle(); + String content = message.getContent(); + JsonObject extrasJson = JsonParser.parseString(content).getAsJsonObject(); + + String extras = ""; + if (extrasJson.get("extras") != null) { + extras = extrasJson.get("extras").toString(); + } + + switch (title) { + case UPDATEPASSWD: + HTTPInterface.getAppPasswd(); + break; + default: + } + } + + +} diff --git a/src/com/aoleyun/os/tpush/common/DBOpenHelper.java b/src/com/aoleyun/os/tpush/common/DBOpenHelper.java new file mode 100644 index 0000000..8621c98 --- /dev/null +++ b/src/com/aoleyun/os/tpush/common/DBOpenHelper.java @@ -0,0 +1,23 @@ +package com.aoleyun.os.tpush.common; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; + +public class DBOpenHelper extends SQLiteOpenHelper { + + public DBOpenHelper(Context context) { + super(context, "XGExample.db", null, 1); + } + + @Override + public void onCreate(SQLiteDatabase db) { + db.execSQL("CREATE TABLE notification (id integer primary key autoincrement,msg_id varchar(64),title varchar(128),activity varchar(256),notificationActionType varchar(512),content text,update_time varchar(16))"); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + + } + +} diff --git a/src/com/aoleyun/os/tpush/common/NotificationService.java b/src/com/aoleyun/os/tpush/common/NotificationService.java new file mode 100644 index 0000000..0fb4d7f --- /dev/null +++ b/src/com/aoleyun/os/tpush/common/NotificationService.java @@ -0,0 +1,135 @@ +package com.aoleyun.os.tpush.common; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; + + +import com.aoleyun.os.tpush.po.XGNotification; + +import java.util.ArrayList; +import java.util.List; + +public class NotificationService { + private DBOpenHelper dbOpenHelper; + private static NotificationService instance = null; + + public NotificationService(Context context) { + this.dbOpenHelper = new DBOpenHelper(context); + } + + public synchronized static NotificationService getInstance(Context ctx) { + if (null == instance) { + instance = new NotificationService(ctx); + } + return instance; + } + + public void save(XGNotification notification) { + SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); + ContentValues values = new ContentValues(); + values.put("msg_id", notification.getMsg_id()); + values.put("title", notification.getTitle()); + values.put("content", notification.getContent()); + values.put("activity", notification.getActivity()); + values.put("notificationActionType", notification.getNotificationActionType()); + values.put("update_time", notification.getUpdate_time()); + db.insert("notification", null, values); + } + + public void delete(Integer id) { + SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); + db.delete("notification", "id=?", new String[] { id.toString() }); + } + + public void deleteAll() { + SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); + db.delete("notification", "", null); + } + + public void update(XGNotification notification) { + SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); + ContentValues values = new ContentValues(); + values.put("msg_id", notification.getMsg_id()); + values.put("title", notification.getTitle()); + values.put("content", notification.getContent()); + values.put("activity", notification.getActivity()); + values.put("notificationActionType", notification.getNotificationActionType()); + values.put("update_time", notification.getUpdate_time()); + db.update("notification", values, "id=?", new String[] { notification + .getId().toString() }); + } + + public XGNotification find(Integer id) { + SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); + Cursor cursor = db + .query("notification", + new String[] { "id,msg_id,title,content,activity,notificationActionType,update_time" }, + "id=?", new String[] { id.toString() }, null, null, + null, "1"); + try { + if (cursor.moveToFirst()) { + return new XGNotification(cursor.getInt(cursor + .getColumnIndex("id")), cursor.getLong(cursor + .getColumnIndex("msg_id")), cursor.getString(cursor + .getColumnIndex("title")), cursor.getString(cursor + .getColumnIndex("content")), cursor.getString(cursor + .getColumnIndex("activity")), cursor.getInt(cursor + .getColumnIndex("notificationActionType")), cursor.getString(cursor + .getColumnIndex("update_time"))); + } + return null; + } finally { + cursor.close(); + } + } + + public List getScrollData(int currentPage, int lineSize, + String msg_id) { + String firstResult = String.valueOf((currentPage - 1) * lineSize); + SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); + Cursor cursor = null; + try { + if (msg_id == null || "".equals(msg_id)) { + cursor = db + .query("notification", + new String[] { "id,msg_id,title,content,activity,notificationActionType,update_time" }, + null, null, null, null, "update_time DESC", + firstResult + "," + lineSize); + } else { + cursor = db + .query("notification", + new String[] { "id,msg_id,title,content,activity,notificationActionType,update_time" }, + "msg_id like ?", new String[] { msg_id + "%" }, + null, null, "update_time DESC", firstResult + + "," + lineSize); + } + List notifications = new ArrayList(); + while (cursor.moveToNext()) { + notifications.add(new XGNotification(cursor.getInt(cursor + .getColumnIndex("id")), cursor.getLong(cursor + .getColumnIndex("msg_id")), cursor.getString(cursor + .getColumnIndex("title")), cursor.getString(cursor + .getColumnIndex("content")), cursor.getString(cursor + .getColumnIndex("activity")), cursor.getInt(cursor + .getColumnIndex("notificationActionType")), cursor.getString(cursor + .getColumnIndex("update_time")))); + } + return notifications; + } finally { + cursor.close(); + } + } + + public int getCount() { + SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); + Cursor cursor = db.rawQuery("select count(*) from notification", null); + try { + cursor.moveToFirst(); + return cursor.getInt(0); + } finally { + cursor.close(); + } + } +} diff --git a/src/com/aoleyun/os/tpush/po/XGNotification.java b/src/com/aoleyun/os/tpush/po/XGNotification.java new file mode 100644 index 0000000..e3844e8 --- /dev/null +++ b/src/com/aoleyun/os/tpush/po/XGNotification.java @@ -0,0 +1,83 @@ +package com.aoleyun.os.tpush.po; + +public class XGNotification { + private Integer id; + private Long msg_id; + private String title; + private String content; + private String activity; + private int notificationActionType; + private String update_time; + + public XGNotification() { + + } + + public XGNotification(Integer id, Long msg_id, String title, + String content, String activity, int notificationActionType, String update_time) { + super(); + this.id = id; + this.msg_id = msg_id; + this.title = title; + this.content = content; + this.activity = activity; + this.notificationActionType = notificationActionType; + this.update_time = update_time; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Long getMsg_id() { + return msg_id; + } + + public void setMsg_id(Long msg_id) { + this.msg_id = msg_id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getUpdate_time() { + return update_time; + } + + public void setUpdate_time(String update_time) { + this.update_time = update_time; + } + + public String getActivity() { + return activity; + } + + public void setActivity(String activity) { + this.activity = activity; + } + + public int getNotificationActionType() { + return notificationActionType; + } + + public void setNotificationActionType(int notificationActionType) { + this.notificationActionType = notificationActionType; + } +} diff --git a/src/com/aoleyun/os/uiuiutils/CacheUtils.java b/src/com/aoleyun/os/uiuiutils/CacheUtils.java new file mode 100644 index 0000000..0cc6b6f --- /dev/null +++ b/src/com/aoleyun/os/uiuiutils/CacheUtils.java @@ -0,0 +1,139 @@ +package com.aoleyun.os.uiuiutils; + + +import android.content.Context; +import android.content.pm.IPackageDataObserver; +import android.content.pm.IPackageManager; +import android.content.pm.IPackageStatsObserver; +import android.content.pm.PackageManager; +import android.content.pm.PackageStats; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.util.Log; + +import java.lang.reflect.Method; + +public class CacheUtils { + + private static final String TAG = CacheUtils.class.getSimpleName(); + private final long MAX_WAIT_TIME = 60 * 1000; + private final long WAIT_TIME_INCR = 10 * 1000; + + /** + * 获取应用数据大小 cache + data + * + * @param context + * @param packageName + * @return + * @throws Exception + */ + + public long getApplicationCache(Context context, String packageName) throws Exception { + try { + PackageStatsObserver observer = new PackageStatsObserver(); + // wait on observer + synchronized (observer) { + Method method = PackageManager.class.getMethod("getPackageSizeInfo", new Class[] { String.class, IPackageStatsObserver.class }); + method.invoke(context.getPackageManager(), packageName, observer); +// getPm().getPackageSizeInfo(packageName, UserHandle.myUserId(), observer); + long waitTime = 0; + while ((!observer.isDone()) || (waitTime > MAX_WAIT_TIME)) { + observer.wait(WAIT_TIME_INCR); + waitTime += WAIT_TIME_INCR; + } + if (!observer.isDone()) { + throw new Exception("Timed out waiting for PackageStatsObserver.onGetStatsCompleted"); + } + } + Log.d(TAG, "toString " + observer.stats.toString()); + return observer.stats.dataSize + observer.stats.cacheSize; + } catch (RemoteException e) { + Log.w(TAG, "Failed to get handle for PackageManger Exception: " + e); + return -1; + } catch (InterruptedException e) { + Log.w(TAG, "InterruptedException :" + e); + return -1; + } + } + + /** + * 清除应用数据 + * + * @param context + * @param packageName + * @return + * @throws Exception + */ + public boolean cleanApplicationUserData(Context context, String packageName) throws Exception { + Log.e(TAG, "cleanApplicationUserData: " + packageName); + try { + PackageDataObserver observer = new PackageDataObserver(); + // wait on observer + synchronized (observer) { + Method method = PackageManager.class.getMethod("clearApplicationUserData", new Class[] { String.class, IPackageDataObserver.class }); + method.invoke(context.getPackageManager(), packageName, observer); +// getPm().deleteApplicationCacheFiles(appid, observer); + long waitTime = 0; + while (!observer.isDone() || (waitTime > MAX_WAIT_TIME)) { + observer.wait(WAIT_TIME_INCR); + waitTime += WAIT_TIME_INCR; + } + if (!observer.isDone()) { + throw new Exception("timed out waiting for PackageDataObserver.onRemoveCompleted"); + } + } + Log.d(TAG, "cleanApplicationCache " + observer.retValue); + return observer.retValue; + } catch (RemoteException e) { + Log.w(TAG, "Failed to get handle for PackageManger Exception: " + e); + return false; + } catch (InterruptedException e) { + Log.w(TAG, "InterruptedException :" + e); + return false; + } + } + + private IPackageManager getPm() { + return IPackageManager.Stub.asInterface(ServiceManager.getService("package")); + } + + class PackageDataObserver extends IPackageDataObserver.Stub { + public boolean retValue = false; + private boolean doneFlag = false; + + public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException { + synchronized (this) { + retValue = succeeded; + doneFlag = true; + notifyAll(); + } + } + + public boolean isDone() { + return doneFlag; + } + } + + class PackageStatsObserver extends IPackageStatsObserver.Stub { + public boolean retValue = false; + public PackageStats stats; + private boolean doneFlag = false; + + public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) throws RemoteException { + synchronized (this) { + retValue = succeeded; + stats = pStats; + doneFlag = true; + notifyAll(); + } + } + + public boolean isDone() { + return doneFlag; + } + } + + + +} + diff --git a/src/com/aoleyun/os/uiuiutils/GsonUtils.java b/src/com/aoleyun/os/uiuiutils/GsonUtils.java new file mode 100644 index 0000000..2df74d6 --- /dev/null +++ b/src/com/aoleyun/os/uiuiutils/GsonUtils.java @@ -0,0 +1,29 @@ +package com.aoleyun.os.uiuiutils; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; + + +public class GsonUtils { + public static JsonObject getJsonObject(String jsonString) { + JsonObject jsonObject = JsonParser.parseString(jsonString).getAsJsonObject(); + return jsonObject; + } + + // TODO: 2022/3/31 暂时没有实现 + public static E getJsonFromType(String jsonString) { + Gson gson = new Gson(); + Type Type = new TypeToken() { + }.getType(); + E e = gson.fromJson(jsonString, Type); + return e; + } + + public static String toJsonString(Object o) { + return new Gson().toJson(o); + } +} diff --git a/src/com/aoleyun/os/uiuiutils/JGYUtils.java b/src/com/aoleyun/os/uiuiutils/JGYUtils.java index 29bb8e7..2f87789 100644 --- a/src/com/aoleyun/os/uiuiutils/JGYUtils.java +++ b/src/com/aoleyun/os/uiuiutils/JGYUtils.java @@ -207,5 +207,23 @@ public class JGYUtils { bootIntent.setComponent(new ComponentName(PACKAGE_APPSTORE, CLASS_APPSTORE)); mContext.sendBroadcast(bootIntent); } + + public void cleanLauncher3Cache() { + try { + new CacheUtils().cleanApplicationUserData(mContext, "com.android.launcher3"); + } catch (Exception e) { + Log.e(TAG, "onReceive: " + e.getMessage()); + e.printStackTrace(); + } + } + + public void cleanAoleLauncher3Cache() { + try { + new CacheUtils().cleanApplicationUserData(mContext, "com.aoleyun.os"); + } catch (Exception e) { + Log.e(TAG, "onReceive: " + e.getMessage()); + e.printStackTrace(); + } + } } diff --git a/src/com/aoleyun/os/uiuiutils/TimeUtils.java b/src/com/aoleyun/os/uiuiutils/TimeUtils.java index 8a8c143..1d8506e 100644 --- a/src/com/aoleyun/os/uiuiutils/TimeUtils.java +++ b/src/com/aoleyun/os/uiuiutils/TimeUtils.java @@ -2,11 +2,17 @@ package com.aoleyun.os.uiuiutils; import android.annotation.SuppressLint; import android.content.Context; +import android.os.Build; import android.util.Log; +import androidx.annotation.RequiresApi; + import java.io.Serializable; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.Date; public class TimeUtils { @@ -106,5 +112,20 @@ public class TimeUtils { return false; } + @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); + } + + public static String transferLongToDate(Long millSec) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = new Date(millSec); + return sdf.format(date); + } }