From ecd0435fcfb8ed0afa0b416b0755be13863cb549 Mon Sep 17 00:00:00 2001 From: Javier Santos Date: Fri, 17 Jul 2015 19:02:41 +0200 Subject: [PATCH] System apps can be uninstalled --- .../mlmanager/activities/AppActivity.java | 27 ++++++++++-- .../async/DeleteDataInBackground.java | 5 +-- .../async/UninstallInBackground.java | 44 +++++++++++++++++++ .../mlmanager/utils/UtilsDialog.java | 21 ++++++++- .../mlmanager/utils/UtilsRoot.java | 18 ++++++++ app/src/main/res/values/strings.xml | 9 +++- 6 files changed, 115 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/com/javiersantos/mlmanager/async/UninstallInBackground.java diff --git a/app/src/main/java/com/javiersantos/mlmanager/activities/AppActivity.java b/app/src/main/java/com/javiersantos/mlmanager/activities/AppActivity.java index 86a1fac..7d9e334 100644 --- a/app/src/main/java/com/javiersantos/mlmanager/activities/AppActivity.java +++ b/app/src/main/java/com/javiersantos/mlmanager/activities/AppActivity.java @@ -28,6 +28,7 @@ import com.javiersantos.mlmanager.R; import com.javiersantos.mlmanager.async.DeleteDataInBackground; import com.javiersantos.mlmanager.async.ExtractFileInBackground; +import com.javiersantos.mlmanager.async.UninstallInBackground; import com.javiersantos.mlmanager.utils.AppPreferences; import com.javiersantos.mlmanager.utils.UtilsRoot; import com.javiersantos.mlmanager.utils.UtilsApp; @@ -127,11 +128,9 @@ private void setScreenElements() { if (appInfo.isSystem()) { icon_googleplay.setVisibility(View.GONE); start.setVisibility(View.GONE); - uninstall.setVisibility(View.GONE); googleplay.setForeground(null); start.setForeground(null); - uninstall.setForeground(null); } else { googleplay.setOnClickListener(new View.OnClickListener() { @Override @@ -174,6 +173,25 @@ public void onClick(View view) { }); if(UtilsRoot.isRooted() && MLManagerApplication.isPro()) { + if (appInfo.isSystem()) { + uninstall.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + MaterialDialog.Builder materialBuilder = UtilsDialog.showUninstall(context) + .callback(new MaterialDialog.ButtonCallback() { + @Override + public void onPositive(MaterialDialog dialog) { + MaterialDialog dialogUninstalling = UtilsDialog.showTitleContentWithProgress(context + , getResources().getString(R.string.dialog_uninstalling) + , getResources().getString(R.string.dialog_uninstalling_description)); + new UninstallInBackground(context, dialogUninstalling, appInfo).execute(); + dialog.dismiss(); + } + }); + materialBuilder.show(); + } + }); + } cache.setVisibility(View.VISIBLE); cache.setOnClickListener(new View.OnClickListener() { @Override @@ -196,6 +214,9 @@ public void onClick(View view) { , getResources().getString(R.string.dialog_clear_data_success_description, appInfo.getName())).execute(); } }); + } else if (appInfo.isSystem()) { + uninstall.setVisibility(View.GONE); + uninstall.setForeground(null); } // FAB (Share) @@ -257,7 +278,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { Log.i("App", "OK"); finish(); - startActivity(new Intent(this, MainActivity.class)); + startActivity(new Intent(context, MainActivity.class)); } else if (resultCode == RESULT_CANCELED) { Log.i("App", "CANCEL"); } diff --git a/app/src/main/java/com/javiersantos/mlmanager/async/DeleteDataInBackground.java b/app/src/main/java/com/javiersantos/mlmanager/async/DeleteDataInBackground.java index 72dbede..6387b20 100644 --- a/app/src/main/java/com/javiersantos/mlmanager/async/DeleteDataInBackground.java +++ b/app/src/main/java/com/javiersantos/mlmanager/async/DeleteDataInBackground.java @@ -26,8 +26,7 @@ public DeleteDataInBackground(Context context, MaterialDialog dialog, String dir @Override protected Boolean doInBackground(Void... voids) { - boolean status = UtilsRoot.removeWithRootPermission(directory); - return status; + return UtilsRoot.removeWithRootPermission(directory); } @Override @@ -37,7 +36,7 @@ protected void onPostExecute(Boolean status) { if (status) { UtilsDialog.showSnackbar(activity, successDescription, null, null, 2).show(); } else { - UtilsDialog.showTitleContent(context, context.getResources().getString(R.string.dialog_cache_and_data_error), context.getResources().getString(R.string.dialog_cache_and_data_error_description)); + UtilsDialog.showTitleContent(context, context.getResources().getString(R.string.dialog_root_required), context.getResources().getString(R.string.dialog_root_required_description)); } } } \ No newline at end of file diff --git a/app/src/main/java/com/javiersantos/mlmanager/async/UninstallInBackground.java b/app/src/main/java/com/javiersantos/mlmanager/async/UninstallInBackground.java new file mode 100644 index 0000000..a79ca14 --- /dev/null +++ b/app/src/main/java/com/javiersantos/mlmanager/async/UninstallInBackground.java @@ -0,0 +1,44 @@ +package com.javiersantos.mlmanager.async; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.AsyncTask; + +import com.afollestad.materialdialogs.MaterialDialog; +import com.javiersantos.mlmanager.AppInfo; +import com.javiersantos.mlmanager.R; +import com.javiersantos.mlmanager.activities.MainActivity; +import com.javiersantos.mlmanager.utils.UtilsDialog; +import com.javiersantos.mlmanager.utils.UtilsRoot; + +public class UninstallInBackground extends AsyncTask { + private Context context; + private Activity activity; + private MaterialDialog dialog; + private AppInfo appInfo; + + public UninstallInBackground(Context context, MaterialDialog dialog, AppInfo appInfo) { + this.context = context; + this.activity = (Activity) context; + this.dialog = dialog; + this.appInfo = appInfo; + } + + @Override + protected Boolean doInBackground(Void... voids) { + return UtilsRoot.uninstallWithRootPermission(appInfo.getSource()); + } + + @Override + protected void onPostExecute(Boolean status) { + super.onPostExecute(status); + dialog.dismiss(); + if (status) { + activity.finish(); + context.startActivity(new Intent(context, MainActivity.class)); + } else { + UtilsDialog.showTitleContent(context, context.getResources().getString(R.string.dialog_root_required), context.getResources().getString(R.string.dialog_root_required_description)); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/javiersantos/mlmanager/utils/UtilsDialog.java b/app/src/main/java/com/javiersantos/mlmanager/utils/UtilsDialog.java index dfa5569..1cfba9b 100644 --- a/app/src/main/java/com/javiersantos/mlmanager/utils/UtilsDialog.java +++ b/app/src/main/java/com/javiersantos/mlmanager/utils/UtilsDialog.java @@ -15,7 +15,10 @@ public class UtilsDialog { public static MaterialDialog showTitleContent(Context context, String title, String content) { MaterialDialog.Builder materialBuilder = new MaterialDialog.Builder(context) .title(title) - .content(content).positiveText(context.getResources().getString(R.string.button_ok)).cancelable(true).callback(new MaterialDialog.ButtonCallback() { + .content(content) + .positiveText(context.getResources().getString(R.string.button_ok)) + .cancelable(true) + .callback(new MaterialDialog.ButtonCallback() { @Override public void onPositive(MaterialDialog dialog) { dialog.dismiss(); @@ -33,6 +36,22 @@ public static MaterialDialog showTitleContentWithProgress(Context context, Strin return materialBuilder.show(); } + public static MaterialDialog.Builder showUninstall(Context context) { + MaterialDialog.Builder materialBuilder = new MaterialDialog.Builder(context) + .title(context.getResources().getString(R.string.dialog_uninstall_root)) + .content(context.getResources().getString(R.string.dialog_uninstall_root_description)) + .positiveText(context.getResources().getString(R.string.button_uninstall)) + .negativeText(context.getResources().getString(R.string.button_cancel)) + .cancelable(false) + .callback(new MaterialDialog.ButtonCallback() { + @Override + public void onNegative(MaterialDialog dialog) { + dialog.dismiss(); + } + }); + return materialBuilder; + } + // 1: APK Extracted // 2: Snackbar without Button // 3: App unhide diff --git a/app/src/main/java/com/javiersantos/mlmanager/utils/UtilsRoot.java b/app/src/main/java/com/javiersantos/mlmanager/utils/UtilsRoot.java index 578f335..900a8da 100644 --- a/app/src/main/java/com/javiersantos/mlmanager/utils/UtilsRoot.java +++ b/app/src/main/java/com/javiersantos/mlmanager/utils/UtilsRoot.java @@ -89,6 +89,24 @@ public static boolean hideWithRootPermission(String apk, Boolean hidden) { return status; } + public static boolean uninstallWithRootPermission(String source) { + boolean status = false; + try { + String[] command = new String[]{"su", "-c", "rm -r " + source + "\n"}; + + Process process = Runtime.getRuntime().exec(command); + process.waitFor(); + int i = process.exitValue(); + if (i == 0) { + status = true; + } + } catch (Exception e) { + e.printStackTrace(); + } + + return status; + } + public static boolean rebootSystem() { boolean status = false; try { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f0968ac..b8dd015 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -39,6 +39,8 @@ Unable to extract this APK. Please, try to restart your device. Uninstall Uninstall this app right now + Uninstalling %s APK… + ML Manager is uninstalling this app. Please wait. Remove cache Remove the cache for this app Cache deleted @@ -51,10 +53,12 @@ Please wait while all files are being deleted. Data deleted All data for %s has been removed - Root required - To delete data your device must be rooted with root permission given. If you have denied access once: Go to SuperUser app to give access to ML Manager. + Root required + Your device must be rooted with root permission given. If you have denied access once: Go to SuperUser app to give access to ML Manager. Reboot is necessary to display the changes. Do you want to reboot now? %s can\'t be opened because it\'s hidden. Try to unhide before opening this app. + Are you sure you want to uninstall? + You are just one step of removing a system app. Do not delete it if you are unsure, it could cause malfunction of the device. Cancel @@ -63,6 +67,7 @@ Share APK Undo Reboot + Uninstall Delete all extracted APKs