diff --git a/README.md b/README.md
index e30db83..1bde0d1 100644
--- a/README.md
+++ b/README.md
@@ -3,11 +3,35 @@
使用xposed让被完全停止的应用响应fcm,让fcm送达率达到100%,不错过任何通知
- 允许fcm唤醒选中的应用来发送通知
-- 修复在国内网络下出现重连服务出现负数问题(仅203615037有效)
-- 固定心跳间隔为117s(仅203615037有效)
+- 修复在国内网络下出现重连服务出现负数问题(可选)(需要查看自己手机上gms的版本编辑配置文件)
+- 固定心跳间隔为117s(可选)(需要查看自己手机上gms的版本编辑配置文件)
## 注意
在国内版miui上,除了在本应用中勾选目标应用之外,还要给予目标应用自启动权限中的允许系统唤醒权限(eu版和国际版则不需要给自启动权限)
-## todo
-没想到版本更新后混淆名称会变,支持多版本的事等之后有空再说吧
\ No newline at end of file
+## 由于gms更新较快,代码遭到混淆,hook点几乎每个版本都会变动,所以需要手动修改配置文件
+- 1. 确保xposed模块已经运行,如果存在/data/data/com.google.andorid.gms/shared_prefs/fcmfix_config.xml则证明模块已经成功运行,这是配置文件,之后都是编辑这个文件的内容。
+- 2. 下载MT管理器等可以进行反编译的工具
+- 3. 对/data/app/com.google.android.gms-/base.apk进行反编译(在MT管理器对apk文件选择查看,点击classes.dex使用Dex编辑器++打开,全选 -> 确认)
+- 4. 搜索 "Previous alarms will stay active" ,路径: / ,搜索类型: 代码,按道理应该只有一个搜索结果,将搜到类名(一般是4个字母)填入配置文件的timer_class项中
+- 5. 回到MT管理器点击刚才搜索到的类,看文件最上面第九行左右开始属性声明,`.field private final d:Landroid/content/Intent;`将这个私有属性类型是Intent的属性`d(按自己实际情况填)`填入配置文件的timer_intent_property
+- 6. 寻找一个没有返回值,只有一个长整形参数的public方法,一般是第90行左右的`.method public final a(J)V`,认准这个`final`和`(J)`和`V`找这个方法,把方法名`a`填入配置文件的timer_settimeout_method
+- 7. 继续查看刚在找到的这个timer_settimeout_method,这个方法往下几行的`iget-wide v0, p0, L[xxxx];->[f]:J`,这个xxxx是最开始的类名,这个f就是我们要找的属性名,将这个找到的属性名`f`填入配置文件的timer_next_time_property
+- 8. 修改完上面的配置项,现在配置文件大概是这样的
+```xml
+
+
+
+```
+- 9. 最后将配置文件的enable修改true,保存,重启手机
+
+- 10. 一般来说gms更新改变的只有类名也就是timer_class
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 82876a8..496e72b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -7,8 +7,8 @@ android {
applicationId "com.kooritea.fcmfix"
minSdkVersion 27
targetSdkVersion 29
- versionCode 2
- versionName "0.0.2"
+ versionCode 3
+ versionName "0.0.3"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b392790..49128f0 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -25,6 +25,13 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/kooritea/fcmfix/MainActivity.java b/app/src/main/java/com/kooritea/fcmfix/MainActivity.java
index e00c0ff..6b6b849 100644
--- a/app/src/main/java/com/kooritea/fcmfix/MainActivity.java
+++ b/app/src/main/java/com/kooritea/fcmfix/MainActivity.java
@@ -4,6 +4,7 @@
import android.annotation.SuppressLint;
import android.app.Activity;
+import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SharedPreferences;
@@ -11,10 +12,12 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
+import android.database.ContentObserver;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -26,14 +29,18 @@
import android.widget.ListView;
import android.widget.TextView;
+import com.kooritea.fcmfix.util.ContentProviderHelper;
+
import java.io.File;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
+import java.util.Observer;
import java.util.Set;
public class MainActivity extends AppCompatActivity {
@@ -161,39 +168,16 @@ public void onItemClick(AdapterView> arg0, View arg1, int position, long arg3)
appListAdapter.notifyDataSetChanged();
}
});
- this.initHeartbeatInterval();
- }
-
- private void initHeartbeatInterval(){
- if(this.sharedPreferences.getString("heartbeatInterval","").equals("")){
- this.sharedPreferencesEditor.putString("heartbeatInterval","117000");
- this.sharedPreferencesEditor.commit();
- this.setWorldReadable();
- }
}
private void addAppInAllowList(String packageName){
this.allowList.add(packageName);
this.sharedPreferencesEditor.putStringSet("allowList",this.allowList);
this.sharedPreferencesEditor.commit();
- this.setWorldReadable();
}
private void deleteAppInAllowList(String packageName){
this.allowList.remove(packageName);
this.sharedPreferencesEditor.putStringSet("allowList",this.allowList);
this.sharedPreferencesEditor.commit();
- this.setWorldReadable();
- }
-
- private void setWorldReadable() {
- File dataDir = new File(getApplicationInfo().dataDir);
- File prefsDir = new File(dataDir, "shared_prefs");
- File prefsFile = new File(prefsDir, "config.xml");
- if (prefsFile.exists()) {
- for (File file : new File[]{dataDir, prefsDir, prefsFile}) {
- file.setReadable(true, false);
- file.setExecutable(true, false);
- }
- }
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/kooritea/fcmfix/XposedMain.java b/app/src/main/java/com/kooritea/fcmfix/XposedMain.java
index c569605..7e15205 100644
--- a/app/src/main/java/com/kooritea/fcmfix/XposedMain.java
+++ b/app/src/main/java/com/kooritea/fcmfix/XposedMain.java
@@ -1,8 +1,17 @@
package com.kooritea.fcmfix;
+import android.app.AndroidAppHelper;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+
import com.kooritea.fcmfix.xposed.BroadcastFix;
import com.kooritea.fcmfix.xposed.ReconnectManagerFix;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
@@ -17,6 +26,8 @@ public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam loadPackageP
if(loadPackageParam.packageName.equals("com.google.android.gms")){
XposedBridge.log("[fcmfix] start hook com.google.android.gms");
new ReconnectManagerFix(loadPackageParam);
+
}
+
}
}
diff --git a/app/src/main/java/com/kooritea/fcmfix/XposedProvider.java b/app/src/main/java/com/kooritea/fcmfix/XposedProvider.java
new file mode 100644
index 0000000..8c62311
--- /dev/null
+++ b/app/src/main/java/com/kooritea/fcmfix/XposedProvider.java
@@ -0,0 +1,85 @@
+package com.kooritea.fcmfix;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.net.Uri;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+public class XposedProvider extends ContentProvider {
+
+ private static UriMatcher uriMatcher;
+
+ static
+ {
+ uriMatcher=new UriMatcher(UriMatcher.NO_MATCH);
+ uriMatcher.addURI("com.kooritea.fcmfix.provider","config",0);
+ }
+
+ @Override
+ public boolean onCreate() {
+ return false;
+ }
+
+ @Nullable
+ @Override
+ public String getType(@NonNull Uri uri) {
+ switch (uriMatcher.match(uri))
+ {
+ default:
+ break;
+ }
+ return null;
+ }
+
+
+ @Nullable
+ @Override
+ public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
+ //这里填写查询逻辑
+ SharedPreferences sharedPreferences = getContext().getSharedPreferences("config", Context.MODE_PRIVATE);
+ String[] COLUMN_NAME = { "key", "value" };
+ MatrixCursor data = new MatrixCursor(COLUMN_NAME);
+ switch (selection){
+ case "heartbeatInterval":
+ data.addRow(new Object[]{"heartbeatInterval",sharedPreferences.getLong("heartbeatInterval",117000L)});
+ break;
+ case "allowList":
+ for(String item : sharedPreferences.getStringSet("allowList",new HashSet())){
+ data.addRow(new Object[]{"allowList",item});
+ }
+ break;
+ }
+ return data;
+ }
+
+ @Nullable
+ @Override
+ public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
+ //这里填写插入逻辑
+ return null;
+ }
+
+ @Override
+ public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
+ //这里填写更新逻辑
+ return 0;
+ }
+
+ @Override
+ public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
+ //这里填写删除逻辑
+ return 0;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/kooritea/fcmfix/util/ContentProviderHelper.java b/app/src/main/java/com/kooritea/fcmfix/util/ContentProviderHelper.java
new file mode 100644
index 0000000..6796841
--- /dev/null
+++ b/app/src/main/java/com/kooritea/fcmfix/util/ContentProviderHelper.java
@@ -0,0 +1,82 @@
+package com.kooritea.fcmfix.util;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.net.Uri;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+public class ContentProviderHelper {
+
+ public ContentResolver contentResolver;
+ private Uri uri;
+ private ArrayList contentObservers = new ArrayList<>();
+ public Boolean useDefaultValue = false;
+
+ public ContentProviderHelper(Context context, String uri){
+ contentResolver = context.getContentResolver();
+ this.uri = Uri.parse(uri);
+ }
+ public ContentProviderHelper(){
+ useDefaultValue = true;
+ }
+
+ public Long getLong(String selection,Long defaultValue){
+ if(useDefaultValue){
+ return defaultValue;
+ }
+ Cursor cursor = contentResolver.query(uri, null, selection, null,null);
+ if(cursor == null){
+ return defaultValue;
+ }
+ cursor.getCount();
+ while(cursor.moveToNext()) {
+ if(selection.equals(cursor.getString(cursor.getColumnIndex("key")))){
+ cursor.close();
+ return cursor.getLong(cursor.getColumnIndex("value"));
+ }
+ }
+ cursor.close();
+ return defaultValue;
+ }
+ public String getString(String selection,String defaultValue){
+ if(useDefaultValue){
+ return defaultValue;
+ }
+ Cursor cursor =contentResolver.query(uri, null, selection, null,null);
+ if(cursor == null){
+ return defaultValue;
+ }
+ cursor.getCount();
+ while(cursor.moveToNext()) {
+ if(selection.equals(cursor.getString(cursor.getColumnIndex("key")))){
+ cursor.close();
+ return cursor.getString(cursor.getColumnIndex("value"));
+ }
+ }
+ cursor.close();
+ return defaultValue;
+ }
+ public Set getStringSet(String selection){
+ if(useDefaultValue){
+ return new HashSet();
+ }
+ Cursor cursor = contentResolver.query(uri, null, selection, null,null);
+ if(cursor == null){
+ return new HashSet();
+ }
+ cursor.getCount();
+ Set result = new HashSet();
+ while(cursor.moveToNext()) {
+ if(selection.equals(cursor.getString(cursor.getColumnIndex("key")))){
+ result.add(cursor.getString(cursor.getColumnIndex("value")));
+ }
+ }
+ cursor.close();
+ return result;
+ }
+}
diff --git a/app/src/main/java/com/kooritea/fcmfix/xposed/BroadcastFix.java b/app/src/main/java/com/kooritea/fcmfix/xposed/BroadcastFix.java
index 3dcfd58..7e59af6 100644
--- a/app/src/main/java/com/kooritea/fcmfix/xposed/BroadcastFix.java
+++ b/app/src/main/java/com/kooritea/fcmfix/xposed/BroadcastFix.java
@@ -1,8 +1,11 @@
package com.kooritea.fcmfix.xposed;
+import android.app.AndroidAppHelper;
import android.content.ContextWrapper;
import android.content.Intent;
+import com.kooritea.fcmfix.util.ContentProviderHelper;
+
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
@@ -15,8 +18,12 @@
public class BroadcastFix extends XposedModule {
+ protected ContentProviderHelper contentProviderHelper;
+
public BroadcastFix(XC_LoadPackage.LoadPackageParam loadPackageParam) {
super(loadPackageParam);
+ contentProviderHelper = new ContentProviderHelper(AndroidAppHelper.currentApplication().getApplicationContext(),"content://com.kooritea.fcmfix.provider/config");
+ this.startHook();
}
protected void startHook(){
@@ -58,7 +65,7 @@ protected void beforeHookedMethod(MethodHookParam methodHookParam) throws Throwa
private boolean targetIsAllow(String packageName){
if (!packageName.equals("com.tencent.mm")) {
- Set allowList = this.getXSharedPreferences().getStringSet("allowList", new HashSet());
+ Set allowList = this.contentProviderHelper.getStringSet("allowList");
for (String item : allowList) {
if (item.equals(packageName)) {
return true;
diff --git a/app/src/main/java/com/kooritea/fcmfix/xposed/ReconnectManagerFix.java b/app/src/main/java/com/kooritea/fcmfix/xposed/ReconnectManagerFix.java
index c8f0dca..e1a1b8a 100644
--- a/app/src/main/java/com/kooritea/fcmfix/xposed/ReconnectManagerFix.java
+++ b/app/src/main/java/com/kooritea/fcmfix/xposed/ReconnectManagerFix.java
@@ -1,78 +1,206 @@
package com.kooritea.fcmfix.xposed;
import android.app.AndroidAppHelper;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.TaskStackBuilder;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Build;
import android.os.SystemClock;
+import android.os.UserManager;
+import androidx.core.app.NotificationCompat;
+import androidx.core.app.NotificationManagerCompat;
+
+import com.kooritea.fcmfix.R;
+import com.kooritea.fcmfix.util.ContentProviderHelper;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import de.robv.android.xposed.XC_MethodHook;
+import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
-public class ReconnectManagerFix extends XposedModule{
+import static android.content.Context.NOTIFICATION_SERVICE;
+
+public class ReconnectManagerFix extends XposedModule {
private Class> GcmChimeraService;
+
public ReconnectManagerFix(XC_LoadPackage.LoadPackageParam loadPackageParam) {
super(loadPackageParam);
+ this.startHookGcmServiceStart();
}
- protected void startHook(){
- this.GcmChimeraService = XposedHelpers.findClass("com.google.android.gms.gcm.GcmChimeraService",loadPackageParam.classLoader);
- XposedHelpers.findAndHookMethod(XposedHelpers.findClass("abcn",loadPackageParam.classLoader),"a", long.class, new XC_MethodHook() {
+ private void startHookGcmServiceStart() {
+ this.GcmChimeraService = XposedHelpers.findClass("com.google.android.gms.gcm.GcmChimeraService", loadPackageParam.classLoader);
+ XposedHelpers.findAndHookMethod(XposedHelpers.findClass("com.google.android.gms.gcm.GcmChimeraService", loadPackageParam.classLoader), "onCreate", new XC_MethodHook() {
+ @Override
+ protected void afterHookedMethod(final MethodHookParam param) throws Throwable {
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction("com.kooritea.fcmfix.log");
+ AndroidAppHelper.currentApplication().getApplicationContext().registerReceiver(logBroadcastReceive, intentFilter);
+ if (AndroidAppHelper.currentApplication().getApplicationContext().getSystemService(UserManager.class).isUserUnlocked()) {
+ try {
+ startHook();
+ printLog("ReconnectManagerFixStartHook 完成");
+ } catch (Exception e) {
+ printLog("ReconnectManagerFixStartHook 初始化失败: " + e.getMessage());
+ }
+ } else {
+ IntentFilter userUnlockIntentFilter = new IntentFilter();
+ userUnlockIntentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
+ AndroidAppHelper.currentApplication().getApplicationContext().registerReceiver(unlockBroadcastReceive, userUnlockIntentFilter);
+ }
+ }
+ });
+ XposedHelpers.findAndHookMethod(XposedHelpers.findClass("com.google.android.gms.gcm.GcmChimeraService", loadPackageParam.classLoader), "onDestroy", new XC_MethodHook() {
+ @Override
+ protected void beforeHookedMethod(final MethodHookParam param) throws Throwable {
+ AndroidAppHelper.currentApplication().getApplicationContext().unregisterReceiver(logBroadcastReceive);
+ }
+ });
+
+ }
+
+ private void startHook() throws Exception {
+ Context context = AndroidAppHelper.currentApplication().getApplicationContext();
+ final SharedPreferences sharedPreferences = context.getSharedPreferences("fcmfix_config", Context.MODE_PRIVATE);
+ String versionName = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
+ if (!sharedPreferences.getBoolean("isInit", false)) {
+ this.printLog("fcmfix_config init");
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putBoolean("isInit", true);
+ editor.putBoolean("enable", false);
+ editor.putLong("heartbeatInterval", 117000L);
+ editor.putString("timer_class", "");
+ editor.putString("timer_settimeout_method", "");
+ editor.putString("timer_next_time_property", "");
+ editor.putString("timer_intent_property", "");
+ editor.putString("gms_version", versionName);
+ editor.commit();
+ this.sendUpdateNotification("[xposed-fcmfix]请初始化fcmfix配置");
+ return;
+ }
+ if (!sharedPreferences.getBoolean("enable", false)) {
+ this.printLog("ReconnectManagerFix配置已关闭");
+ return;
+ }
+ if (!sharedPreferences.getString("gms_version", "").equals(versionName)) {
+ this.printLog("gms已更新,请重新编辑fcmfix_config.xml");
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putBoolean("enable", false);
+ editor.putString("gms_version", versionName);
+ editor.commit();
+ this.sendUpdateNotification("[xposed-fcmfix]gms已更新");
+ return;
+ }
+ this.printLog("ReconnectManagerFix读取配置已成功,timer_class: " + sharedPreferences.getString("timer_class", ""));
+ XposedHelpers.findAndHookMethod(XposedHelpers.findClass(sharedPreferences.getString("timer_class", ""), loadPackageParam.classLoader), sharedPreferences.getString("timer_settimeout_method", ""), long.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(final MethodHookParam param) throws Throwable {
// 修改心跳间隔
- Intent intent = (Intent) XposedHelpers.getObjectField(param.thisObject,"d");
- if("com.google.android.gms.gcm.HEARTBEAT_ALARM".equals(intent.getAction())){
- param.args[0] = 117000L;
+ Intent intent = (Intent) XposedHelpers.getObjectField(param.thisObject, sharedPreferences.getString("timer_intent_property", ""));
+ if ("com.google.android.gms.gcm.HEARTBEAT_ALARM".equals(intent.getAction())) {
+ param.args[0] = sharedPreferences.getLong("heartbeatInterval", 117000L);
}
}
+
@Override
protected void afterHookedMethod(final MethodHookParam param) throws Throwable {
// 防止计时器出现负数计时,分别是心跳计时和重连计时
- Intent intent = (Intent) XposedHelpers.getObjectField(param.thisObject,"d");
- if("com.google.android.intent.action.GCM_RECONNECT".equals(intent.getAction()) || "com.google.android.gms.gcm.HEARTBEAT_ALARM".equals(intent.getAction())){
+ Intent intent = (Intent) XposedHelpers.getObjectField(param.thisObject, sharedPreferences.getString("timer_intent_property", ""));
+ if ("com.google.android.intent.action.GCM_RECONNECT".equals(intent.getAction()) || "com.google.android.gms.gcm.HEARTBEAT_ALARM".equals(intent.getAction())) {
new Timer("ReconnectManagerFix").schedule(new TimerTask() {
@Override
public void run() {
- long nextConnectionTime = XposedHelpers.getLongField(param.thisObject,"f");
- if(nextConnectionTime !=0 && nextConnectionTime - SystemClock.elapsedRealtime() < 0){
+ long nextConnectionTime = XposedHelpers.getLongField(param.thisObject, sharedPreferences.getString("timer_next_time_property", ""));
+ if (nextConnectionTime != 0 && nextConnectionTime - SystemClock.elapsedRealtime() < 0) {
AndroidAppHelper.currentApplication().getApplicationContext().sendBroadcast(new Intent("com.google.android.intent.action.GCM_RECONNECT"));
printLog("Send broadcast GCM_RECONNECT");
}
}
- }, (long)param.args[0]+5000);
+ }, (long) param.args[0] + 5000);
}
}
});
- XposedHelpers.findAndHookMethod(XposedHelpers.findClass("com.google.android.gms.gcm.GcmChimeraService",loadPackageParam.classLoader),"onCreate", new XC_MethodHook() {
- @Override
- protected void afterHookedMethod(final MethodHookParam param) throws Throwable {
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction("com.kooritea.fcmfix.log");
- AndroidAppHelper.currentApplication().getApplicationContext().registerReceiver(logBroadcastReceive,intentFilter);
- }
- });
- XposedHelpers.findAndHookMethod(XposedHelpers.findClass("com.google.android.gms.gcm.GcmChimeraService",loadPackageParam.classLoader),"onDestroy", new XC_MethodHook() {
- @Override
- protected void beforeHookedMethod(final MethodHookParam param) throws Throwable {
- AndroidAppHelper.currentApplication().getApplicationContext().unregisterReceiver(logBroadcastReceive);
+ }
+
+ private void sendUpdateNotification(String text) {
+ Context context = AndroidAppHelper.currentApplication().getApplicationContext();
+ NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
+ this.createFcmfixChannel(notificationManager);
+ NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "fcmfix");
+ builder.setSmallIcon(R.mipmap.ic_launcher);
+ builder.setContentTitle(text);
+ // builder.setContentText("点击编辑fcmfix.xml");
+ builder.setAutoCancel(true);
+ notificationManager.notify((int) System.currentTimeMillis(), builder.build());
+ }
+
+ private void createFcmfixChannel(NotificationManager notificationManager) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ List channelList = notificationManager.getNotificationChannels();
+ for (NotificationChannel item : channelList) {
+ if (item.getId() == "fcmfix") {
+ item.setName("fcmfix");
+ item.setImportance(NotificationManager.IMPORTANCE_HIGH);
+ item.setDescription("fcmfix");
+ return;
+ }
}
- });
+ NotificationChannel channel = new NotificationChannel("fcmfix", "fcmfix", NotificationManager.IMPORTANCE_HIGH);
+ channel.setDescription("[xposed] fcmfix更新通知");
+ notificationManager.createNotificationChannel(channel);
+ }
}
private BroadcastReceiver logBroadcastReceive = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
- if("com.kooritea.fcmfix.log".equals(action)) {
- XposedHelpers.callStaticMethod(GcmChimeraService,"a",new Class>[]{String.class,Object[].class},"[fcmfix] "+ intent.getStringExtra("text"),null);
+ if ("com.kooritea.fcmfix.log".equals(action)) {
+ XposedHelpers.callStaticMethod(GcmChimeraService, "a", new Class>[]{String.class, Object[].class}, "[fcmfix] " + intent.getStringExtra("text"), null);
+ }
+ }
+ };
+
+ private BroadcastReceiver unlockBroadcastReceive = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (Intent.ACTION_USER_UNLOCKED.equals(action)) {
+ printLog("UserUnlock Broadcast");
+ try {
+ startHook();
+ printLog("ReconnectManagerFixStartHook 完成");
+ AndroidAppHelper.currentApplication().getApplicationContext().unregisterReceiver(unlockBroadcastReceive);
+ } catch (Exception e) {
+ printLog("ReconnectManagerFixStartHook 初始化失败: " + e.getMessage());
+ }
}
}
};
diff --git a/app/src/main/java/com/kooritea/fcmfix/xposed/XposedModule.java b/app/src/main/java/com/kooritea/fcmfix/xposed/XposedModule.java
index acc06f7..70870fb 100644
--- a/app/src/main/java/com/kooritea/fcmfix/xposed/XposedModule.java
+++ b/app/src/main/java/com/kooritea/fcmfix/xposed/XposedModule.java
@@ -2,11 +2,10 @@
import android.app.AndroidAppHelper;
import android.content.Intent;
+import android.util.Log;
-import java.lang.reflect.Method;
+import com.kooritea.fcmfix.util.ContentProviderHelper;
-import de.robv.android.xposed.XSharedPreferences;
-import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
public class XposedModule {
@@ -15,15 +14,6 @@ public class XposedModule {
protected XposedModule(final XC_LoadPackage.LoadPackageParam loadPackageParam){
this.loadPackageParam = loadPackageParam;
- this.startHook();
- }
-
- protected void startHook(){};
-
- protected XSharedPreferences getXSharedPreferences(){
- XSharedPreferences xSharedPreferences = new XSharedPreferences("com.kooritea.fcmfix","config");
- xSharedPreferences.makeWorldReadable();
- return xSharedPreferences;
}
protected void printLog(String text){