Send notification when received broadcast from edservice
This commit is contained in:
parent
54098c1dbc
commit
fd6a3f9a93
|
|
@ -55,19 +55,20 @@
|
|||
</activity>
|
||||
|
||||
<receiver
|
||||
android:name=".receivers.PackageChangeReceiver"
|
||||
android:exported="false">
|
||||
android:name=".util.NotificationUtil$RebootReceiver"
|
||||
android:exported="false" />
|
||||
|
||||
<receiver
|
||||
android:name=".receivers.EdServiceReceiver"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.INTERACT_ACROSS_USERS_FULL">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.PACKAGE_ADDED" />
|
||||
<action android:name="android.intent.action.PACKAGE_CHANGED" />
|
||||
<action android:name="android.intent.action.PACKAGE_REMOVED" />
|
||||
<action android:name="io.github.lsposed.action.MODULE_UPDATED" />
|
||||
<action android:name="io.github.lsposed.action.MODULE_NOT_ACTIVATAED" />
|
||||
|
||||
<data android:scheme="package" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver
|
||||
android:name=".util.NotificationUtil$RebootReceiver"
|
||||
android:exported="false" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
|
|
|
|||
|
|
@ -3,9 +3,7 @@ package org.meowcat.edxposed.manager;
|
|||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
|
|
@ -17,7 +15,6 @@ import androidx.annotation.NonNull;
|
|||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import org.meowcat.edxposed.manager.adapters.AppHelper;
|
||||
import org.meowcat.edxposed.manager.receivers.PackageChangeReceiver;
|
||||
import org.meowcat.edxposed.manager.ui.activity.CrashReportActivity;
|
||||
import org.meowcat.edxposed.manager.util.ModuleUtil;
|
||||
import org.meowcat.edxposed.manager.util.NotificationUtil;
|
||||
|
|
@ -106,7 +103,6 @@ public class App extends Application implements Application.ActivityLifecycleCal
|
|||
|
||||
createDirectories();
|
||||
NotificationUtil.init();
|
||||
registerReceivers();
|
||||
|
||||
registerActivityLifecycleCallbacks(this);
|
||||
|
||||
|
|
@ -123,18 +119,6 @@ public class App extends Application implements Application.ActivityLifecycleCal
|
|||
}
|
||||
}
|
||||
|
||||
private void registerReceivers() {
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
|
||||
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
|
||||
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
|
||||
filter.addDataScheme("package");
|
||||
registerReceiver(new PackageChangeReceiver(), filter);
|
||||
|
||||
PendingIntent.getBroadcast(this, 0,
|
||||
new Intent(this, PackageChangeReceiver.class), 0);
|
||||
}
|
||||
|
||||
@SuppressLint({"PrivateApi", "NewApi"})
|
||||
private void createDirectories() {
|
||||
mkdir("conf");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
package org.meowcat.edxposed.manager.receivers;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
|
||||
import org.meowcat.edxposed.manager.util.NotificationUtil;
|
||||
|
||||
public class EdServiceReceiver extends BroadcastReceiver {
|
||||
|
||||
private static String getPackageName(Intent intent) {
|
||||
Uri uri = intent.getData();
|
||||
return (uri != null) ? uri.getSchemeSpecificPart() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
String packageName = getPackageName(intent);
|
||||
if (packageName == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String appName = "null";
|
||||
try {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
pm.getApplicationInfo(packageName, 0);
|
||||
appName = (String) pm.getApplicationInfo(packageName, 0).loadLabel(pm);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (intent.getAction().equals("io.github.lsposed.action.MODULE_NOT_ACTIVATAED")) {
|
||||
NotificationUtil.showNotActivatedNotification(packageName, appName);
|
||||
} else if (intent.getAction().equals("io.github.lsposed.action.MODULE_UPDATED")) {
|
||||
NotificationUtil.showModulesUpdatedNotification(appName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
package org.meowcat.edxposed.manager.receivers;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
||||
import org.meowcat.edxposed.manager.util.ModuleUtil;
|
||||
import org.meowcat.edxposed.manager.util.ModuleUtil.InstalledModule;
|
||||
import org.meowcat.edxposed.manager.util.NotificationUtil;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class PackageChangeReceiver extends BroadcastReceiver {
|
||||
private static ModuleUtil moduleUtil = null;
|
||||
|
||||
private static String getPackageName(Intent intent) {
|
||||
Uri uri = intent.getData();
|
||||
return (uri != null) ? uri.getSchemeSpecificPart() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
if (Objects.requireNonNull(intent.getAction()).equals(Intent.ACTION_PACKAGE_REMOVED) && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false))
|
||||
// Ignore existing packages being removed in order to be updated
|
||||
return;
|
||||
|
||||
String packageName = getPackageName(intent);
|
||||
if (packageName == null)
|
||||
return;
|
||||
|
||||
if (intent.getAction().equals(Intent.ACTION_PACKAGE_CHANGED)) {
|
||||
// make sure that the change is for the complete package, not only a
|
||||
// component
|
||||
String[] components = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST);
|
||||
if (components != null) {
|
||||
boolean isForPackage = false;
|
||||
for (String component : components) {
|
||||
if (packageName.equals(component)) {
|
||||
isForPackage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isForPackage)
|
||||
return;
|
||||
}
|
||||
} else if (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) {
|
||||
NotificationUtil.cancel(packageName, NotificationUtil.NOTIFICATION_MODULE_NOT_ACTIVATED_YET);
|
||||
return;
|
||||
}
|
||||
|
||||
moduleUtil = getModuleUtilInstance();
|
||||
|
||||
moduleUtil.updateModulesList(false);
|
||||
InstalledModule module = ModuleUtil.getInstance().reloadSingleModule(packageName);
|
||||
if (module == null
|
||||
|| intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) {
|
||||
// Package being removed, disable it if it was a previously active
|
||||
// Xposed mod
|
||||
if (moduleUtil.isModuleEnabled(packageName)) {
|
||||
moduleUtil.setModuleEnabled(packageName, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (moduleUtil.isModuleEnabled(packageName)) {
|
||||
NotificationUtil.showModulesUpdatedNotification();
|
||||
} else {
|
||||
NotificationUtil.showNotActivatedNotification(packageName, module.getAppName());
|
||||
}
|
||||
}
|
||||
|
||||
private ModuleUtil getModuleUtilInstance() {
|
||||
if (moduleUtil == null) {
|
||||
moduleUtil = ModuleUtil.getInstance();
|
||||
}
|
||||
return moduleUtil;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,19 @@
|
|||
package org.meowcat.edxposed.manager.util;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
import android.os.PowerManager;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.core.app.NotificationChannelCompat;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.topjohnwu.superuser.Shell;
|
||||
|
|
@ -20,7 +21,9 @@ import com.topjohnwu.superuser.Shell;
|
|||
import org.meowcat.edxposed.manager.App;
|
||||
import org.meowcat.edxposed.manager.R;
|
||||
import org.meowcat.edxposed.manager.ui.activity.MainActivity;
|
||||
import org.meowcat.edxposed.manager.ui.activity.ModulesActivity;
|
||||
|
||||
@SuppressLint("UnspecifiedImmutableFlag")
|
||||
public final class NotificationUtil {
|
||||
|
||||
public static final int NOTIFICATION_MODULE_NOT_ACTIVATED_YET = 0;
|
||||
|
|
@ -32,15 +35,12 @@ public final class NotificationUtil {
|
|||
private static final int PENDING_INTENT_ACTIVATE_MODULE_AND_REBOOT = 4;
|
||||
private static final int PENDING_INTENT_ACTIVATE_MODULE = 5;
|
||||
|
||||
private static final String HEADS_UP = "heads_up";
|
||||
private static final String FRAGMENT_ID = "fragment";
|
||||
|
||||
private static final String NOTIFICATION_MODULES_CHANNEL = "modules_channel";
|
||||
private static final String NOTIFICATION_MODULES_CHANNEL = "modules_channel_2";
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private static Context context = null;
|
||||
private static NotificationManager notificationManager;
|
||||
private static SharedPreferences prefs;
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private static NotificationManagerCompat notificationManager;
|
||||
|
||||
public static void init() {
|
||||
if (context != null) {
|
||||
|
|
@ -48,13 +48,14 @@ public final class NotificationUtil {
|
|||
}
|
||||
|
||||
context = App.getInstance();
|
||||
prefs = App.getPreferences();
|
||||
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager = NotificationManagerCompat.from(context);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
NotificationChannel channelModule = new NotificationChannel(NOTIFICATION_MODULES_CHANNEL, context.getString(R.string.nav_item_modules), NotificationManager.IMPORTANCE_DEFAULT);
|
||||
notificationManager.createNotificationChannel(channelModule);
|
||||
}
|
||||
NotificationChannelCompat.Builder channel = new NotificationChannelCompat.Builder(NOTIFICATION_MODULES_CHANNEL,
|
||||
NotificationManager.IMPORTANCE_HIGH)
|
||||
.setName(context.getString(R.string.nav_item_modules))
|
||||
.setSound(null, null)
|
||||
.setVibrationPattern(null);
|
||||
notificationManager.createNotificationChannel(channel.build());
|
||||
}
|
||||
|
||||
public static void cancel(String tag, int id) {
|
||||
|
|
@ -66,58 +67,52 @@ public final class NotificationUtil {
|
|||
}
|
||||
|
||||
public static void showNotActivatedNotification(String packageName, String appName) {
|
||||
Intent intent = new Intent(context, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).putExtra(FRAGMENT_ID, 1);
|
||||
Intent intent = new Intent(context, ModulesActivity.class)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
PendingIntent pModulesTab = PendingIntent.getActivity(context, PENDING_INTENT_OPEN_MODULES, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
String title = context.getString(R.string.module_is_not_activated_yet);
|
||||
NotificationCompat.Builder builder = getNotificationBuilder(title, appName, NOTIFICATION_MODULES_CHANNEL)
|
||||
NotificationCompat.Builder builder = getNotificationBuilder(title, appName)
|
||||
.setContentIntent(pModulesTab);
|
||||
if (prefs.getBoolean(HEADS_UP, true)) {
|
||||
builder.setPriority(2);
|
||||
|
||||
// Only show the quick activation button if any module has been
|
||||
// enabled before,
|
||||
// to ensure that the user know the way to disable the module later.
|
||||
if (!ModuleUtil.getInstance().getEnabledModules().isEmpty()) {
|
||||
Intent iActivateAndReboot = new Intent(context, RebootReceiver.class);
|
||||
iActivateAndReboot.putExtra(RebootReceiver.EXTRA_ACTIVATE_MODULE, packageName);
|
||||
PendingIntent pActivateAndReboot = PendingIntent.getBroadcast(context, PENDING_INTENT_ACTIVATE_MODULE_AND_REBOOT,
|
||||
iActivateAndReboot, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
Intent iActivate = new Intent(context, RebootReceiver.class);
|
||||
iActivate.putExtra(RebootReceiver.EXTRA_ACTIVATE_MODULE, packageName);
|
||||
iActivate.putExtra(RebootReceiver.EXTRA_ACTIVATE_MODULE_AND_RETURN, true);
|
||||
PendingIntent pActivate = PendingIntent.getBroadcast(context, PENDING_INTENT_ACTIVATE_MODULE,
|
||||
iActivate, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
builder.addAction(new NotificationCompat.Action.Builder(R.drawable.ic_apps, context.getString(R.string.activate_and_reboot), pActivateAndReboot).build());
|
||||
builder.addAction(new NotificationCompat.Action.Builder(R.drawable.ic_apps, context.getString(R.string.activate_only), pActivate).build());
|
||||
}
|
||||
Intent iActivateAndReboot = new Intent(context, RebootReceiver.class);
|
||||
iActivateAndReboot.putExtra(RebootReceiver.EXTRA_ACTIVATE_MODULE, packageName);
|
||||
PendingIntent pActivateAndReboot = PendingIntent.getBroadcast(context, PENDING_INTENT_ACTIVATE_MODULE_AND_REBOOT,
|
||||
iActivateAndReboot, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
Intent iActivate = new Intent(context, RebootReceiver.class);
|
||||
iActivate.putExtra(RebootReceiver.EXTRA_ACTIVATE_MODULE, packageName);
|
||||
iActivate.putExtra(RebootReceiver.EXTRA_ACTIVATE_MODULE_AND_RETURN, true);
|
||||
PendingIntent pActivate = PendingIntent.getBroadcast(context, PENDING_INTENT_ACTIVATE_MODULE,
|
||||
iActivate, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
NotificationCompat.BigTextStyle style = new NotificationCompat.BigTextStyle();
|
||||
style.setBigContentTitle(title);
|
||||
style.bigText(context.getString(R.string.module_is_not_activated_yet_detailed, appName));
|
||||
builder.setStyle(style);
|
||||
|
||||
// Only show the quick activation button if any module has been
|
||||
// enabled before,
|
||||
// to ensure that the user know the way to disable the module later.
|
||||
if (!ModuleUtil.getInstance().getEnabledModules().isEmpty()) {
|
||||
builder.addAction(new NotificationCompat.Action.Builder(R.drawable.ic_apps, context.getString(R.string.activate_and_reboot), pActivateAndReboot).build());
|
||||
builder.addAction(new NotificationCompat.Action.Builder(R.drawable.ic_apps, context.getString(R.string.activate_only), pActivate).build());
|
||||
}
|
||||
|
||||
notificationManager.notify(packageName, NOTIFICATION_MODULE_NOT_ACTIVATED_YET, builder.build());
|
||||
}
|
||||
|
||||
public static void showModulesUpdatedNotification() {
|
||||
Intent intent = new Intent(context, MainActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.putExtra(FRAGMENT_ID, 0);
|
||||
public static void showModulesUpdatedNotification(String appName) {
|
||||
Intent intent = new Intent(context, MainActivity.class)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
PendingIntent pInstallTab = PendingIntent.getActivity(context, PENDING_INTENT_OPEN_INSTALL,
|
||||
intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
PendingIntent pInstallTab = PendingIntent.getActivity(context, PENDING_INTENT_OPEN_INSTALL, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
String title = context
|
||||
.getString(R.string.xposed_module_updated_notification_title);
|
||||
String message = context
|
||||
.getString(R.string.xposed_module_updated_notification);
|
||||
NotificationCompat.Builder builder = getNotificationBuilder(title, message, NOTIFICATION_MODULES_CHANNEL)
|
||||
NotificationCompat.Builder builder = getNotificationBuilder(title, appName)
|
||||
.setContentIntent(pInstallTab);
|
||||
if (prefs.getBoolean(HEADS_UP, true)) {
|
||||
builder.setPriority(2);
|
||||
}
|
||||
|
||||
Intent iSoftReboot = new Intent(context, RebootReceiver.class);
|
||||
iSoftReboot.putExtra(RebootReceiver.EXTRA_SOFT_REBOOT, true);
|
||||
PendingIntent pSoftReboot = PendingIntent.getBroadcast(context, PENDING_INTENT_SOFT_REBOOT,
|
||||
|
|
@ -133,10 +128,11 @@ public final class NotificationUtil {
|
|||
notificationManager.notify(null, NOTIFICATION_MODULES_UPDATED, builder.build());
|
||||
}
|
||||
|
||||
private static NotificationCompat.Builder getNotificationBuilder(String title, String message, String channel) {
|
||||
return new NotificationCompat.Builder(context, channel)
|
||||
private static NotificationCompat.Builder getNotificationBuilder(String title, String message) {
|
||||
return new NotificationCompat.Builder(context, NOTIFICATION_MODULES_CHANNEL)
|
||||
.setContentTitle(title)
|
||||
.setContentText(message)
|
||||
.setSound(null)
|
||||
.setVibrate(new long[]{0})
|
||||
.setAutoCancel(true)
|
||||
.setSmallIcon(R.drawable.ic_notification)
|
||||
|
|
@ -175,11 +171,18 @@ public final class NotificationUtil {
|
|||
return;
|
||||
}
|
||||
|
||||
boolean isSoftReboot = intent.getBooleanExtra(EXTRA_SOFT_REBOOT,
|
||||
false);
|
||||
int returnCode = isSoftReboot
|
||||
? Shell.su("setprop ctl.restart surfaceflinger; setprop ctl.restart zygote").exec().getCode()
|
||||
: Shell.su("reboot").exec().getCode();
|
||||
boolean softReboot = intent.getBooleanExtra(EXTRA_SOFT_REBOOT, false);
|
||||
String command;
|
||||
if (softReboot) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && ((PowerManager) context.getSystemService(Context.POWER_SERVICE)).isRebootingUserspaceSupported()) {
|
||||
command = "/system/bin/svc power reboot userspace";
|
||||
} else {
|
||||
command = "setprop ctl.restart surfaceflinger; setprop ctl.restart zygote";
|
||||
}
|
||||
} else {
|
||||
command = "/system/bin/svc power reboot";
|
||||
}
|
||||
int returnCode = Shell.su(command).exec().getCode();
|
||||
|
||||
if (returnCode != 0) {
|
||||
Log.e(App.TAG, "NotificationUtil -> Could not reboot");
|
||||
|
|
|
|||
Loading…
Reference in New Issue