mirror of
https://github.com/fankes/termux-app.git
synced 2025-09-06 10:45:23 +08:00
Added: Add functions to PackageUtils to check/modify app Component states
These can be used by Termux app and its plugin to disable launcher icons/activities if they are enabled at install time
This commit is contained in:
@@ -4,6 +4,7 @@ import android.app.ActivityManager;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -249,6 +250,8 @@ public class PackageUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the process id of the main app process of a package. This will work for sharedUserId. Note
|
||||
* that some apps have multiple processes for the app like with `android:process=":background"`
|
||||
@@ -275,6 +278,8 @@ public class PackageUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check if app is installed and enabled. This can be used by external apps that don't
|
||||
* share `sharedUserId` with the an app.
|
||||
@@ -318,4 +323,97 @@ public class PackageUtils {
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Enable or disable a {@link ComponentName} with a call to
|
||||
* {@link PackageManager#setComponentEnabledSetting(ComponentName, int, int)}.
|
||||
*
|
||||
* @param context The {@link Context} for operations.
|
||||
* @param packageName The package name of the component.
|
||||
* @param className The {@link Class} name of the component.
|
||||
* @param state If component should be enabled or disabled.
|
||||
* @param toastString If this is not {@code null} or empty, then a toast before setting state.
|
||||
* @param showErrorMessage If an error message toast should be shown.
|
||||
* @return Returns the errmsg if failed to set state, otherwise {@code null}.
|
||||
*/
|
||||
@Nullable
|
||||
public static String setComponentState(@NonNull final Context context, @NonNull String packageName,
|
||||
@NonNull String className, boolean state, String toastString,
|
||||
boolean showErrorMessage) {
|
||||
try {
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
if (packageManager != null) {
|
||||
ComponentName componentName = new ComponentName(packageName, className);
|
||||
if (toastString != null) Logger.showToast(context, toastString, true);
|
||||
packageManager.setComponentEnabledSetting(componentName,
|
||||
state ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
|
||||
PackageManager.DONT_KILL_APP);
|
||||
}
|
||||
return null;
|
||||
} catch (final Exception e) {
|
||||
String errmsg = context.getString(
|
||||
state ? R.string.error_enable_component_failed : R.string.error_disable_component_failed,
|
||||
packageName, className) + ": " + e.getMessage();
|
||||
if (showErrorMessage)
|
||||
Logger.showToast(context, errmsg, true);
|
||||
return errmsg;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if state of a {@link ComponentName} is {@link PackageManager#COMPONENT_ENABLED_STATE_DISABLED}
|
||||
* with a call to {@link PackageManager#getComponentEnabledSetting(ComponentName)}.
|
||||
*
|
||||
* @param context The {@link Context} for operations.
|
||||
* @param packageName The package name of the component.
|
||||
* @param className The {@link Class} name of the component.
|
||||
* @param logErrorMessage If an error message should be logged.
|
||||
* @return Returns {@code true} if disabled, {@code false} if not and {@code null} if failed to
|
||||
* get the state.
|
||||
*/
|
||||
public static Boolean isComponentDisabled(@NonNull final Context context, @NonNull String packageName,
|
||||
@NonNull String className, boolean logErrorMessage) {
|
||||
try {
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
if (packageManager != null) {
|
||||
ComponentName componentName = new ComponentName(packageName, className);
|
||||
// Will throw IllegalArgumentException: Unknown component: ComponentInfo{} if app
|
||||
// for context is not installed or component does not exist.
|
||||
return packageManager.getComponentEnabledSetting(componentName) == PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
if (logErrorMessage)
|
||||
Logger.logStackTraceWithMessage(LOG_TAG, context.getString(R.string.error_get_component_state_failed, packageName, className), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an {@link android.app.Activity} {@link ComponentName} can be called by calling
|
||||
* {@link PackageManager#queryIntentActivities(Intent, int)}.
|
||||
*
|
||||
* @param context The {@link Context} for operations.
|
||||
* @param packageName The package name of the component.
|
||||
* @param className The {@link Class} name of the component.
|
||||
* @param flags The flags to filter results.
|
||||
* @return Returns {@code true} if it exists, otherwise {@code false}.
|
||||
*/
|
||||
public static boolean doesActivityComponentExist(@NonNull final Context context, @NonNull String packageName,
|
||||
@NonNull String className, int flags) {
|
||||
try {
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
if (packageManager != null) {
|
||||
Intent intent = new Intent();
|
||||
intent.setClassName(packageName, className);
|
||||
return packageManager.queryIntentActivities(intent, flags).size() > 0;
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -24,6 +24,10 @@
|
||||
<string name="error_get_package_context_failed_message">Failed to get package context for the \"%1$s\" package.
|
||||
This may be because the app package is not installed or it has different APK signature from the current app.
|
||||
Check install instruction at %2$s for more details.</string>
|
||||
<string name="error_get_component_state_failed">Failed to get %1$s/%2$s component state"</string>
|
||||
<string name="error_enable_component_failed">Failed to enable %1$s/%2$s component"</string>
|
||||
<string name="error_disable_component_failed">Failed to enable %1$s/%2$s component"</string>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -91,6 +95,17 @@
|
||||
|
||||
|
||||
|
||||
<!-- Launcher Icons -->
|
||||
<string name="action_enable_launcher_icon">Enable Launcher Icon</string>
|
||||
<string name="action_disable_launcher_icon">Disable Launcher Icon</string>
|
||||
<string name="msg_enabling_launcher_icon">Enabling %1$s app launcher icon"</string>
|
||||
<string name="msg_disabling_launcher_icon">Disabling %1$s app launcher icon"</string>
|
||||
<string name="setting_launcher_icon_title">Launcher Icon Enabled</string>
|
||||
<string name="setting_launcher_icon_enabled_off">Launcher Icon will be disabled.</string>
|
||||
<string name="setting_launcher_icon_enabled_on">Launcher Icon will be enabled. (Default)</string>
|
||||
|
||||
|
||||
|
||||
<!-- Log Level -->
|
||||
<string name="log_level_title">Log Level</string>
|
||||
<string name="log_level_off">"Off"</string>
|
||||
|
Reference in New Issue
Block a user