From 6d7b6e80e9374274d8a6afe2ecfd745296bd74bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=81=E5=85=89?= Date: Wed, 6 May 2026 12:36:19 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=92=A4=E9=94=80=E2=80=9C=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=20=E9=9A=90=E8=97=8F=E5=90=AF=E5=8A=A8=E5=99=A8?= =?UTF-8?q?=E5=9B=BE=E6=A0=87=20=E5=8A=9F=E8=83=BD=E2=80=9D=20&=20?= =?UTF-8?q?=E8=A1=A5=E5=85=A8=20Xposed=20API=20101=20=E7=9A=84=E7=89=B9?= =?UTF-8?q?=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 23 +++++++++++++++++++ .../com/kooritea/fcmfix/MainActivity.java | 21 ++++------------- app/src/main/res/values/strings.xml | 1 + 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d460b69..a682a390 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,7 @@ android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" + android:description="@string/description" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> @@ -25,6 +26,28 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/java/com/kooritea/fcmfix/MainActivity.java b/app/src/main/java/com/kooritea/fcmfix/MainActivity.java index 53b6e8ba..33a30b4b 100644 --- a/app/src/main/java/com/kooritea/fcmfix/MainActivity.java +++ b/app/src/main/java/com/kooritea/fcmfix/MainActivity.java @@ -14,15 +14,10 @@ import android.os.Handler; import android.util.AttributeSet; import android.util.Log; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; +import android.view.*; import android.widget.CheckBox; import android.widget.ImageView; import android.widget.TextView; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; @@ -30,23 +25,15 @@ import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; - +import com.kooritea.fcmfix.util.IceboxUtils; import io.github.libxposed.service.XposedService; import io.github.libxposed.service.XposedServiceHelper; - import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.text.Collator; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Set; - -import com.kooritea.fcmfix.util.IceboxUtils; +import java.util.*; public class MainActivity extends AppCompatActivity { private AppListAdapter appListAdapter; @@ -329,7 +316,7 @@ private void updateConfig(){ @Override public boolean onCreateOptionsMenu (Menu menu){ -// menu.add("隐藏启动器图标").setCheckable(true); + menu.add("隐藏启动器图标").setCheckable(true); menu.add("阻止应用停止时自动清除通知").setCheckable(true); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 67f1b6b4..69e608ed 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,4 @@ fcmfix + 让FCM/GCM唤醒未启动的应用进行发送通知 \ No newline at end of file From 4885c351fbc4c58f7a402551bcd18160aaf4175a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=81=E5=85=89?= Date: Thu, 7 May 2026 15:19:36 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=8D=95=E4=BE=8B=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=8F=96=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 1 + .../com/kooritea/fcmfix/MainActivity.java | 160 +++++++++++------- 2 files changed, 103 insertions(+), 58 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a682a390..0420cedb 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -20,6 +20,7 @@ android:theme="@style/AppTheme"> diff --git a/app/src/main/java/com/kooritea/fcmfix/MainActivity.java b/app/src/main/java/com/kooritea/fcmfix/MainActivity.java index 33a30b4b..79ab3135 100644 --- a/app/src/main/java/com/kooritea/fcmfix/MainActivity.java +++ b/app/src/main/java/com/kooritea/fcmfix/MainActivity.java @@ -37,6 +37,16 @@ public class MainActivity extends AppCompatActivity { private AppListAdapter appListAdapter; + private RecyclerView recyclerView; + private final Handler configRetryHandler = new Handler(); + private final Runnable configRetryRunnable = new Runnable() { + @Override + public void run() { + if (!loadConfigFromRemotePreferencesInternal()) { + configRetryHandler.postDelayed(this, 500); + } + } + }; private static XposedService xposedService; Set allowList = new HashSet<>(); JSONObject config = new JSONObject(); @@ -61,9 +71,6 @@ public void onServiceBind(@NonNull XposedService service) { xposedService = service; runOnUiThread(() -> { loadConfigFromRemotePreferences(); - if (appListAdapter != null) { - appListAdapter.notifyDataSetChanged(); - } }); } @@ -98,11 +105,11 @@ private void ensureDefaultConfigValues() { } } - private void loadConfigFromRemotePreferences() { + private boolean loadConfigFromRemotePreferencesInternal() { ensureDefaultConfigValues(); SharedPreferences pref = getRemotePreferencesOrNull(); if (pref == null) { - return; + return false; } this.allowList.clear(); this.allowList.addAll(pref.getStringSet("allowList", new HashSet<>())); @@ -114,6 +121,72 @@ private void loadConfigFromRemotePreferences() { } catch (JSONException e) { Log.e("loadRemoteConfig", e.toString()); } + return true; + } + + private void loadConfigFromRemotePreferences() { + if (loadConfigFromRemotePreferencesInternal()) { + refreshAppList(); + } + } + + private void refreshAppList() { + if (appListAdapter != null) { + appListAdapter.submitList(buildAppList()); + } + } + + private List buildAppList() { + Set allowListSet = new HashSet<>(allowList); + List _allowList = new ArrayList<>(); + List _notAllowList = new ArrayList<>(); + List _notFoundFcm = new ArrayList<>(); + PackageManager packageManager = getPackageManager(); + for (PackageInfo packageInfo : packageManager.getInstalledPackages(PackageManager.GET_RECEIVERS | PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.MATCH_UNINSTALLED_PACKAGES)) { + boolean flag = false; + AppInfo appInfo = new AppInfo(packageInfo); + if (packageInfo.receivers != null) { + for (ActivityInfo receiverInfo : packageInfo.receivers) { + if (receiverInfo.name.equals("com.google.firebase.iid.FirebaseInstanceIdReceiver") || receiverInfo.name.equals("com.google.android.gms.measurement.AppMeasurementReceiver")) { + flag = true; + appInfo.includeFcm = true; + break; + } + } + } else { + continue; + } + if (allowListSet.contains(appInfo.packageName)) { + appInfo.isAllow = true; + _allowList.add(appInfo); + } else { + if (flag) { + _notAllowList.add(appInfo); + } else { + _notFoundFcm.add(appInfo); + } + } + } + class SortName implements Comparator { + final Collator localCompare = Collator.getInstance(Locale.getDefault()); + + @Override + public int compare(AppInfo a1, AppInfo a2) { + if (localCompare.compare(a1.name, a2.name) > 0) { + return 1; + } else if (localCompare.compare(a1.name, a2.name) < 0) { + return -1; + } + return 0; + } + } + final SortName sortName = new SortName(); + _allowList.sort(sortName); + _notAllowList.sort(sortName); + _notFoundFcm.sort(sortName); + _allowList.addAll(_notAllowList); + _allowList.addAll(_notFoundFcm); + return _allowList; } private class AppInfo { @@ -132,7 +205,7 @@ public AppInfo(PackageInfo packageInfo) { private class AppListAdapter extends RecyclerView.Adapter { - private final List mAppList; + private final List mAppList = new ArrayList<>(); class ViewHolder extends RecyclerView.ViewHolder { View appView; ImageView icon; @@ -153,57 +226,8 @@ public ViewHolder(View view) { } public AppListAdapter(){ - Set allowListSet = new HashSet<>(allowList); - allowListSet.containsAll(allowList); - List _allowList = new ArrayList<>(); - List _notAllowList = new ArrayList<>(); - List _notFoundFcm = new ArrayList<>(); - PackageManager packageManager = getPackageManager(); - for(PackageInfo packageInfo : packageManager.getInstalledPackages(PackageManager.GET_RECEIVERS | PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.MATCH_UNINSTALLED_PACKAGES)) { - boolean flag = false; - AppInfo appInfo = new AppInfo(packageInfo); - if (packageInfo.receivers != null) { - for (ActivityInfo receiverInfo : packageInfo.receivers ){ - if(receiverInfo.name.equals("com.google.firebase.iid.FirebaseInstanceIdReceiver") || receiverInfo.name.equals("com.google.android.gms.measurement.AppMeasurementReceiver")){ - flag = true; - appInfo.includeFcm = true; - break; - } - } - }else{ - continue; - } - if(allowListSet.contains(appInfo.packageName)){ - appInfo.isAllow = true; - _allowList.add(appInfo); - }else{ - if(flag){ - _notAllowList.add(appInfo); - }else{ - _notFoundFcm.add(appInfo); - } - } - } - class SortName implements Comparator { - final Collator localCompare = Collator.getInstance(Locale.getDefault()); - @Override - public int compare(AppInfo a1, AppInfo a2) { - if(localCompare.compare(a1.name,a2.name)>0){ - return 1; - }else if (localCompare.compare(a1.name, a2.name) < 0) { - return -1; - } - return 0; - } - } - final SortName sortName = new SortName(); - _allowList.sort(sortName); - _notAllowList.sort(sortName); - _notFoundFcm.sort(sortName); - _allowList.addAll(_notAllowList); - _allowList.addAll(_notFoundFcm); - this.mAppList = _allowList; - if(_allowList.size() == 0 || _allowList.isEmpty() ||(_allowList.size() == 1 && "com.kooritea.fcmfix".equals(_allowList.get(0).packageName))){ + submitList(buildAppList()); + if(mAppList.size() == 0 || mAppList.isEmpty() ||(mAppList.size() == 1 && "com.kooritea.fcmfix".equals(mAppList.get(0).packageName))){ new AlertDialog.Builder(MainActivity.this) .setTitle("请在系统设置中授予读取应用列表权限") .setMessage("或直接编辑" + getApplicationContext().getFilesDir().getAbsolutePath() + "/config.json(需重启生效)") @@ -212,6 +236,12 @@ public int compare(AppInfo a1, AppInfo a2) { } } + public void submitList(List appList) { + mAppList.clear(); + mAppList.addAll(appList); + notifyDataSetChanged(); + } + @SuppressLint("NotifyDataSetChanged") @NonNull @@ -255,10 +285,12 @@ public int getItemCount() { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - RecyclerView recyclerView = findViewById(R.id.recycler_view); + recyclerView = findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); initXposedService(); + loadConfigFromRemotePreferences(); + configRetryHandler.postDelayed(configRetryRunnable, 300); try { if (ContextCompat.checkSelfPermission(this, IceboxUtils.SDK_PERMISSION) != PackageManager.PERMISSION_GRANTED) { @@ -275,6 +307,18 @@ protected void onCreate(Bundle savedInstanceState) { }, 1000); } + @Override + protected void onResume() { + super.onResume(); + loadConfigFromRemotePreferences(); + } + + @Override + protected void onDestroy() { + configRetryHandler.removeCallbacks(configRetryRunnable); + super.onDestroy(); + } + @Nullable @Override public View onCreateView(@Nullable View parent, @NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs) { From f6accea9b555f5300ba73b39a43742ef56f964d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=81=E5=85=89?= Date: Thu, 7 May 2026 15:55:52 +0800 Subject: [PATCH 3/3] no intent --- app/src/main/AndroidManifest.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0420cedb..17659c43 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -22,10 +22,6 @@ android:name=".MainActivity" android:launchMode="singleInstance" android:exported="true"> - - - -