├── README.md ├── build.gradle └── main ├── AndroidManifest.xml ├── assets └── xposed_init ├── ic_launcher-web.png ├── java └── net │ └── fypm │ └── InstallerOpt │ ├── About.java │ ├── BackupInstalledApps.java │ ├── BootReceiver.java │ ├── CheckableLinearLayout.java │ ├── Common.java │ ├── ConfirmCheckSignatures.java │ ├── CustomBackupInstalledAppsListArrayAdapter.java │ ├── CustomBackupListArrayAdapter.java │ ├── Main.java │ ├── MainActivity.java │ ├── ManageBackups.java │ ├── MoveBackups.java │ ├── MultiprocessPreferences.java │ ├── NaturalOrderComparator.java │ ├── PInfo.java │ ├── Reboot.java │ ├── Stats.java │ └── Utils.java └── res ├── drawable ├── ic_notification.png └── toast_frame.9.png ├── layout ├── activity_main.xml ├── backup_installed_apps_row.xml ├── backup_list.xml ├── manage_backups_row.xml └── version_layout.xml ├── menu ├── backup_installed_apps_menu.xml ├── manage_backup_menu.xml └── menu.xml ├── mipmap-hdpi └── ic_launcher.png ├── mipmap-mdpi └── ic_launcher.png ├── mipmap-xhdpi └── ic_launcher.png ├── mipmap-xxhdpi └── ic_launcher.png ├── mipmap-xxxhdpi └── ic_launcher.png ├── values-pl └── strings.xml ├── values-pt └── strings.xml ├── values-ru └── strings.xml ├── values-sk └── strings.xml ├── values-w820dp └── dimens.xml ├── values-zh-rCN └── strings.xml ├── values ├── colors.xml ├── dimens.xml ├── strings.xml └── styles.xml └── xml └── prefs.xml /README.md: -------------------------------------------------------------------------------- 1 | # InstallerOpt 2 | 3 | Module that adds multiple options to install/unintall processes. Based on XInstaller by pylerSM. 4 | 5 | ## Requirements 6 | 7 | - A rooted Android phone 8 | - [Xposed framework](http://forum.xda-developers.com/xposed) 9 | 10 | ## Support 11 | 12 | [XDA thread](http://forum.xda-developers.com/xposed/modules/xposed-installeropt-0-4-t3377008) 13 | 14 | ## License 15 | 16 | Distributed under the [MIT License](http://opensource.org/licenses/MIT). 17 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.3" 6 | 7 | def versionPropsFile = file('version.properties') 8 | 9 | if (versionPropsFile.canRead()) { 10 | def Properties versionProps = new Properties() 11 | 12 | versionProps.load(new FileInputStream(versionPropsFile)) 13 | def value = 0 14 | def runTasks = gradle.startParameter.taskNames 15 | if ('assemble' in runTasks || 'assembleRelease' in runTasks || 'aR' in runTasks) { 16 | value = 1; 17 | } 18 | 19 | def versionMajor = versionProps['VERSION_MAJOR'].toInteger() 20 | def versionMinor = versionProps['VERSION_MINOR'].toInteger() 21 | def versionPatch = versionProps['VERSION_PATCH'].toInteger() + value 22 | def versionBuild = versionProps['VERSION_BUILD'].toInteger() + 1 23 | def version_Code = versionProps['VERSION_CODE'].toInteger() + 1 24 | 25 | versionProps['VERSION_PATCH'] = versionPatch.toString() 26 | versionProps['VERSION_BUILD'] = versionBuild.toString() 27 | versionProps['VERSION_CODE'] = version_Code.toString() 28 | 29 | versionProps.store(versionPropsFile.newWriter(), null) 30 | 31 | defaultConfig { 32 | applicationId 'net.fypm.InstallerOpt' 33 | versionCode version_Code 34 | versionName "${versionMajor}.${versionMinor}.${versionPatch} (${versionBuild})" 35 | minSdkVersion 15 36 | targetSdkVersion 23 37 | /*resConfigs "en"*/ 38 | } 39 | } else { 40 | throw new GradleException("Could not read version.properties!") 41 | } 42 | buildTypes { 43 | release { 44 | minifyEnabled true 45 | shrinkResources true 46 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 47 | applicationVariants.all { variant -> 48 | variant.outputs.each { output -> 49 | //def date = new Date(); 50 | //def formattedDate = date.format('yyyyMMddHHmmss') 51 | output.outputFile = new File(output.outputFile.parent, 52 | output.outputFile.name.replace("app-release", "net.fypm.InstallerOpt" + versionName + "-release") 53 | //output.outputFile.name.replace("-release", "-" + formattedDate) 54 | //for Debug use output.outputFile = new File(output.outputFile.parent, 55 | //output.outputFile.name.replace("-debug", "-" + formattedDate) 56 | ) 57 | } 58 | } 59 | } 60 | debug { 61 | minifyEnabled false 62 | shrinkResources false 63 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 64 | applicationVariants.all { variant -> 65 | variant.outputs.each { output -> 66 | //def date = new Date(); 67 | //def formattedDate = date.format('yyyyMMddHHmmss') 68 | output.outputFile = new File(output.outputFile.parent, 69 | output.outputFile.name.replace("app-debug", "net.fypm.InstallerOpt" + versionName + " " + versionCode + "-debug") 70 | //for Debug use output.outputFile = new File(output.outputFile.parent, 71 | //output.outputFile.name.replace("-debug", "-" + formattedDate) 72 | ) 73 | } 74 | } 75 | } 76 | } 77 | sourceSets { 78 | main.java.srcDirs += 'src/main/java' 79 | } 80 | productFlavors { 81 | } 82 | } 83 | 84 | dependencies { 85 | compile fileTree(include: ['*.jar'], dir: 'libs') 86 | testCompile 'junit:junit:4.12' 87 | compile 'com.android.support:appcompat-v7:23.0.0' 88 | /*compile 'com.crossbowffs.remotepreferences:remotepreferences:0.1'*/ 89 | compile 'com.android.support:support-annotations:23.0.0' 90 | compile 'net.rdrei.android.dirchooser:library:3.2@aar' 91 | compile 'com.gu:option:1.3' 92 | } 93 | 94 | repositories { 95 | jcenter(); 96 | maven { url 'http://guardian.github.com/maven/repo-releases' } 97 | } 98 | 99 | dependencies { 100 | provided 'de.robv.android.xposed:api:82' 101 | } -------------------------------------------------------------------------------- /main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 18 | 21 | 24 | 27 | 28 | 30 | 31 | 32 | 33 | 34 | 35 | 37 | 38 | 39 | 40 | 41 | 42 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 63 | 64 | 65 | 66 | 67 | 68 | 71 | 72 | 73 | 74 | 75 | 76 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /main/assets/xposed_init: -------------------------------------------------------------------------------- 1 | net.fypm.InstallerOpt.Main -------------------------------------------------------------------------------- /main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afxefx/InstallerOpt/28bceace03e02313f64e17e4fd638a3bd8396c87/main/ic_launcher-web.png -------------------------------------------------------------------------------- /main/java/net/fypm/InstallerOpt/About.java: -------------------------------------------------------------------------------- 1 | package net.fypm.InstallerOpt; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.content.DialogInterface; 6 | import android.os.Bundle; 7 | import android.text.SpannableString; 8 | import android.text.method.LinkMovementMethod; 9 | import android.text.util.Linkify; 10 | import android.widget.TextView; 11 | 12 | public class About extends Activity { 13 | 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | AlertDialog.Builder aboutDialog = new AlertDialog.Builder( 18 | this, android.R.style.Theme_DeviceDefault_Dialog); 19 | final TextView message = new TextView(this); 20 | final SpannableString s = 21 | new SpannableString(this.getText(R.string.dialog_message)); 22 | Linkify.addLinks(s, Linkify.WEB_URLS); 23 | message.setText(s); 24 | aboutDialog.setTitle(getString(R.string.about_menu) + " - " + BuildConfig.VERSION_NAME); 25 | aboutDialog.setMessage(s); 26 | aboutDialog.setCancelable(false); 27 | aboutDialog.setPositiveButton(android.R.string.ok, 28 | new DialogInterface.OnClickListener() { 29 | @Override 30 | public void onClick(DialogInterface dialog, int id) { 31 | dialog.dismiss(); 32 | finish(); 33 | } 34 | }); 35 | AlertDialog thisAboutDialog = aboutDialog.create(); 36 | thisAboutDialog.show(); 37 | thisAboutDialog.findViewById(android.R.id.message).setClickable(true); 38 | ((TextView) thisAboutDialog.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /main/java/net/fypm/InstallerOpt/BootReceiver.java: -------------------------------------------------------------------------------- 1 | package net.fypm.InstallerOpt; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.util.Log; 7 | //import android.widget.Toast; 8 | 9 | public class BootReceiver extends BroadcastReceiver { 10 | 11 | private static final String TAG = "InstallerOpt"; 12 | 13 | public BootReceiver() { 14 | 15 | } 16 | 17 | @Override 18 | public void onReceive(Context context, Intent intent) { 19 | if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { 20 | try { 21 | /*Toast.makeText(context, "Boot completed", 22 | Toast.LENGTH_LONG).show();*/ 23 | Log.i(TAG, "Boot Complete"); 24 | } catch (Exception e) { 25 | Log.e(TAG, "BootReceiver.onReceive: ", e); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /main/java/net/fypm/InstallerOpt/CheckableLinearLayout.java: -------------------------------------------------------------------------------- 1 | package net.fypm.InstallerOpt; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.View; 6 | import android.widget.Checkable; 7 | import android.widget.CheckedTextView; 8 | import android.widget.LinearLayout; 9 | 10 | public class CheckableLinearLayout extends LinearLayout implements Checkable { 11 | private CheckedTextView _checkbox; 12 | 13 | public CheckableLinearLayout(Context context, AttributeSet attrs) { 14 | super(context, attrs); 15 | } 16 | 17 | @Override 18 | protected void onFinishInflate() { 19 | super.onFinishInflate(); 20 | // find checked text view 21 | int childCount = getChildCount(); 22 | for (int i = 0; i < childCount; ++i) { 23 | View v = getChildAt(i); 24 | if (v instanceof CheckedTextView) { 25 | _checkbox = (CheckedTextView) v; 26 | } 27 | } 28 | } 29 | 30 | @Override 31 | public boolean isChecked() { 32 | return _checkbox != null && _checkbox.isChecked(); 33 | } 34 | 35 | @Override 36 | public void setChecked(boolean checked) { 37 | if (_checkbox != null) { 38 | _checkbox.setChecked(checked); 39 | } 40 | } 41 | 42 | @Override 43 | public void toggle() { 44 | if (_checkbox != null) { 45 | _checkbox.toggle(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /main/java/net/fypm/InstallerOpt/Common.java: -------------------------------------------------------------------------------- 1 | package net.fypm.InstallerOpt; 2 | 3 | import android.os.Build; 4 | 5 | public class Common { 6 | 7 | //Utils 8 | public static final String ACTION_APP_OPS_SETTINGS = "android.settings.APP_OPS_SETTINGS"; 9 | public static final String ACTION_BACKUP_APK_FILE = "InstallerOpt.intent.action.BACKUP_APK_FILE"; 10 | public static final String ACTION_BACKUP_PREFERENCES = "InstallerOpt.intent.action.BACKUP_PREFERENCES"; 11 | public static final String ACTION_CONFIRM_CHECK_SIGNATURE = "InstallerOpt.intent.action.CONFIRM_CHECK_SIGNATURE"; 12 | public static final String ACTION_DELETE_APK_FILE = "InstallerOpt.intent.action.DELETE_APK_FILE"; 13 | public static final String ACTION_POST_NOTIFICATION = "InstallerOpt.intent.action.POST_NOTIFICATION"; 14 | public static final String ACTION_RELOAD_PREFERENCES = "InstallerOpt.intent.action.RELOAD_PREFERENCES"; 15 | public static final String ACTION_RESET_PREFERENCES = "InstallerOpt.intent.action.RESET_PREFERENCES"; 16 | public static final String ACTION_RESTORE_PREFERENCES = "InstallerOpt.intent.action.RESTORE_PREFERENCES"; 17 | public static final String ACTION_UNINSTALL_SYSTEM_APP = "InstallerOpt.intent.action.UNINSTALL_SYSTEM_APP"; 18 | public static final String ACTION_VIBRATE_DEVICE = "InstallerOpt.intent.action.VIBRATE_DEVICE"; 19 | 20 | public static final String DESCRIPTION = "description"; 21 | public static final String BACKUP_DIR = "backup_dir"; 22 | public static final String DURATION = "duration"; 23 | public static final String FILE = "file"; 24 | public static final String ID = "id"; 25 | public static final String PACKAGE = "package"; 26 | public static final String PREFERENCE = "preference"; 27 | public static final String THIRDLINE = "thirdline"; 28 | public static final String TITLE = "title"; 29 | public static final String VALUE = "value"; 30 | 31 | //Perms 32 | public static final String PERM_WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE"; 33 | public static final String PERM_ACCESS_ALL_EXTERNAL_STORAGE = "android.permission.ACCESS_ALL_EXTERNAL_STORAGE"; 34 | public static final String PERM_WRITE_MEDIA_STORAGE = "android.permission.WRITE_MEDIA_STORAGE"; 35 | 36 | //Prefs 37 | public static final String PREF_APP_HELP = "app_help"; 38 | public static final String PREF_ENABLE_APP_ICON = "enable_hide_icon"; 39 | public static final String PREF_APP_TRANSLATOR = "app_translator"; 40 | public static final String PREF_APP_LOCALE = "app_locale"; 41 | public static final String PREF_APP_VERSION = "app_version"; 42 | public static final String PREF_APP_ABOUT = "about"; 43 | public static final String PREF_APP_BACKUP_RESTORE = "backup_restore_preferences"; 44 | 45 | public static final String PREF_BACKUP_APK_LOCATION = "backup_apk_location"; 46 | public static final String PREF_BACKUP_APK_LOCATION_OLD = "backup_apk_location_old"; 47 | public static final String PREF_BACKUP_PREFERENCES = "backup_preferences"; 48 | public static final String PREF_INSTALL_BACKGROUND_EXCEPTIONS = "install_background_exceptions"; 49 | public static final String PREF_MODIFIED_PREFERENCES = "modified_preferences"; 50 | public static final String PREF_MODIFIED_TIME = "preference_modified_time"; 51 | public static final String PREF_RESTORE_PREFERENCES = "restore_preferences"; 52 | public static final String PREF_RESET_PREFERENCES = "reset_preferences"; 53 | 54 | public static final String PREF_CONTINUE_BACKUP_ON_REBOOT = "continue_backup_on_reboot"; 55 | public static final String PREF_DISABLE = "disable"; 56 | public static final String PREF_DISABLE_AUTO_UPDATE_GOOGLE_PLAY = "disable_auto_update_google_play"; 57 | public static final String PREF_DISABLE_CHECK_DUPLICATED_PERMISSION = "disable_check_duplicated_permissions"; 58 | public static final String PREF_DISABLE_CHECK_LUCKY_PATCHER = "disable_lucky_patcher_presence"; 59 | public static final String PREF_DISABLE_CHECK_PERMISSION = "disable_check_permissions"; 60 | public static final String PREF_DISABLE_CHECK_SDK_VERSION = "disable_check_sdk_version"; 61 | public static final String PREF_DISABLE_CHECK_SIGNATURE = "disable_sig_check"; 62 | public static final String PREF_DISABLE_CHECK_SIGNATURE_FDROID = "disable_check_signatures_fdroid"; 63 | public static final String PREF_DISABLE_FORWARD_LOCK = "disable_forward_lock"; 64 | public static final String PREF_DISABLE_INSTALL_BACKGROUND = "disable_install_background"; 65 | public static final String PREF_DISABLE_INSTALL_SHELL = "disable_install_shell"; 66 | public static final String PREF_DISABLE_UNINSTALL_BACKGROUND = "disable_uninstall_background"; 67 | public static final String PREF_DISABLE_VERIFY_APP = "disable_verify_apps"; 68 | public static final String PREF_DISABLE_VERIFY_JAR = "disable_verify_jar"; 69 | public static final String PREF_DISABLE_VERIFY_SIGNATURE = "enable_disable_verify_signatures"; 70 | public static final String PREF_ENABLE = "enable"; 71 | public static final String PREF_ENABLE_APP_STORAGE_BUTTONS = "enable_app_storage_buttons"; 72 | public static final String PREF_ENABLE_AUTO_BACKUP = "enable_auto_backup"; 73 | public static final String PREF_ENABLE_AUTO_CLOSE_INSTALL = "enable_auto_close_install"; 74 | public static final String PREF_ENABLE_AUTO_CLOSE_INSTALL_VIBRATE = "enable_auto_close_install_vibrate"; 75 | public static final String PREF_ENABLE_AUTO_CLOSE_UNINSTALL = "enable_auto_close_uninstall"; 76 | public static final String PREF_ENABLE_AUTO_ENABLE_CLEAR_BUTTON = "enable_auto_enable_clear_buttons"; 77 | public static final String PREF_ENABLE_AUTO_HIDE_INSTALL = "enable_auto_hide_install"; 78 | public static final String PREF_ENABLE_AUTO_INSTALL = "enable_auto_install"; 79 | public static final String PREF_ENABLE_AUTO_INSTALL_CANCEL_OVERRIDE = "enable_auto_install_cancel_override"; 80 | public static final String PREF_ENABLE_AUTO_LAUNCH_INSTALL = "enable_auto_install_launch"; 81 | public static final String PREF_ENABLE_AUTO_UNINSTALL = "enable_auto_uninstall"; 82 | public static final String PREF_ENABLE_BACKUP_ALL_APPS = "enable_backup_all_apps"; 83 | public static final String PREF_ENABLE_BACKUP_APK_FILE = "enable_backup_apk_files"; 84 | public static final String PREF_ENABLE_BACKUP_APP_PACKAGE = "enable_backup_app_packages"; 85 | public static final String PREF_ENABLE_CHANGE_DEVICE_PROPERTIES = "enable_change_device_properties"; 86 | public static final String PREF_ENABLE_CONFIRM_CHECK_SIGNATURE = "enable_confirm_check_signatures"; 87 | public static final String PREF_ENABLE_DARK_THEME = "enable_darkui"; 88 | public static final String PREF_ENABLE_DEBUG = "enable_debug"; 89 | public static final String PREF_ENABLE_DEBUG_APP = "enable_debug_apps"; 90 | public static final String PREF_ENABLE_DELETE_APK_FILE_INSTALL = "enable_delete_apk_files"; 91 | public static final String PREF_ENABLE_DISABLE_SYSTEM_APP = "enable_disable_system_apps"; 92 | public static final String PREF_ENABLE_DISABLE_USER_APPS = "enable_disable_user_apps"; 93 | public static final String PREF_ENABLE_DOWNGRADE_APP = "enable_downgrade_apps"; 94 | public static final String PREF_ENABLE_EXPERT_MODE = "enable_expert_mode"; 95 | public static final String PREF_ENABLE_EXPORT_APP = "enable_export_apps"; 96 | public static final String PREF_ENABLE_EXTERNAL_SDCARD_FULL_ACCESS = "external_sdcard_full_access"; 97 | public static final String PREF_ENABLE_FORCE_ENGLISH = "enable_force_english"; 98 | public static final String PREF_ENABLE_HIDE_APP_CRASHES = "enable_hide_app_crashes"; 99 | public static final String PREF_ENABLE_INSTALL_EXTERNAL_STORAGE = "enable_install_external_storage"; 100 | public static final String PREF_ENABLE_INSTALL_UNKNOWN_APP = "enable_install_unknown_apps"; 101 | public static final String PREF_ENABLE_INSTALL_UNKNOWN_APP_PROMPT = "enable_install_unknown_apps_prompt"; 102 | public static final String PREF_ENABLE_INSTALL_UNKNOWN_APP_ORIGINAL = "enable_install_unknown_apps_original"; 103 | public static final String PREF_ENABLE_INSTALL_UNKNOWN_APP_PROMPT_ORIGINAL = "enable_install_unknown_apps_prompt_original"; 104 | public static final String PREF_ENABLE_INSTALL_UNSIGNED_APP = "enable_install_unsigned_apps"; 105 | public static final String PREF_ENABLE_KEEP_APP_DATA = "enable_keep_apps_data"; 106 | public static final String PREF_ENABLE_LAUNCH_APP = "enable_launch_app"; 107 | public static final String PREF_ENABLE_MODULE = "enable_module"; 108 | public static final String PREF_ENABLE_MOVE_APP = "enable_move_apps"; 109 | public static final String PREF_ENABLE_NOTIFICATIONS = "enable_notifications"; 110 | public static final String PREF_ENABLE_OPEN_APP_GOOGLE_PLAY = "enable_play_open"; 111 | public static final String PREF_ENABLE_OPEN_APP_OPS = "enable_open_app_ops"; 112 | public static final String PREF_ENABLE_SHOW_BUTTON = "enable_show_buttons"; 113 | public static final String PREF_ENABLE_SHOW_PACKAGE_NAME = "enable_package_name"; 114 | public static final String PREF_ENABLE_SHOW_VERSION = "enable_version"; 115 | public static final String PREF_ENABLE_SHOW_VERSION_CODE = "enable_version_code"; 116 | public static final String PREF_ENABLE_SHOW_VERSION_INLINE = "enable_version_inline"; 117 | public static final String PREF_ENABLE_SHOW_VERSION_TOAST = "enable_version_toast"; 118 | public static final String PREF_ENABLE_UNINSTALL_DEVICE_ADMIN = "enable_uninstall_device_admin"; 119 | public static final String PREF_ENABLE_UNINSTALL_SYSTEM_APP = "enable_uninstall_system_apps"; 120 | public static final String PREF_MAX_BACKUP_VERSIONS = "backup_apk_files_limit"; 121 | public static final String PREF_VERSION_CODE_KEY = "version_code"; 122 | 123 | 124 | // Constants 125 | public static final int LATEST_ANDROID_RELEASE = 24; // Android N 126 | public static final String ANDROID_PKG = "android"; 127 | public static final String APPOPSXPOSED_PKG = "at.jclehner.appopsxposed"; 128 | public static final String EMPTY_STRING = ""; 129 | public static final String GOOGLE_PACKAGEINSTALLER_PKG = "com.google.android.packageinstaller"; 130 | public static final String INSTALLEROPT = "net.fypm.InstallerOpt"; 131 | public static final String LUCKYPATCHER_PKG = "com.android.vending.billing.InAppBillingService.LUCK"; 132 | public static final String MOKEE_PACKAGEINSTALLER_PKG = "com.mokee.packageinstaller"; 133 | public static final String PACKAGE_NAME = Common.class.getPackage().getName(); 134 | public static final String PACKAGE_PREFERENCES = PACKAGE_NAME + "_preferences"; 135 | public static final String PACKAGE_TAG = "InstallerOpt"; 136 | public static final String PACKAGEINSTALLER_PKG = "com.android.packageinstaller"; 137 | public static final String SAMSUNG_PACKAGEINSTALLER_PKG = "com.samsung.android.packageinstaller"; 138 | public static final String SETTINGS_PKG = "com.android.settings"; 139 | public static final String SYSTEM_UI = "com.android.systemui"; 140 | 141 | // Checks 142 | public static final int SDK = Build.VERSION.SDK_INT; 143 | public static final boolean JB_NEWER = SDK >= Build.VERSION_CODES.JELLY_BEAN; 144 | public static final boolean JB_MR1_NEWER = SDK >= Build.VERSION_CODES.JELLY_BEAN_MR1; 145 | public static final boolean JB_MR2_NEWER = SDK >= Build.VERSION_CODES.JELLY_BEAN_MR2; 146 | public static final boolean KITKAT_NEWER = SDK >= Build.VERSION_CODES.KITKAT; 147 | public static final boolean LOLLIPOP_NEWER = SDK >= Build.VERSION_CODES.LOLLIPOP; 148 | public static final boolean LOLLIPOP_MR1_NEWER = SDK >= Build.VERSION_CODES.LOLLIPOP_MR1; 149 | public static final boolean MARSHMALLOW_NEWER = SDK >= 23; // MARSHMALLOW 150 | 151 | // Classes 152 | public static final String APPOPSDETAILS = "com.android.settings.applications.AppOpsDetails"; 153 | public static final String APPOPSXPOSED_APPOPSACTIVITY = "at.jclehner.appopsxposed.AppOpsActivity"; 154 | public static final String APPSTORAGEDETAILS = "com.android.settings.applications.AppStorageSettings"; 155 | public static final String APPERRORDIALOG = "com.android.server.am.AppErrorDialog"; 156 | public static final String DEVICEPOLICYMANAGERSERVICE = (LOLLIPOP_NEWER) ? "com.android.server.devicepolicy.DevicePolicyManagerService" : "com.android.server.DevicePolicyManagerService"; 157 | public static final String INSTALLAPPPROGRESS = "com.android.packageinstaller.InstallAppProgress"; 158 | public static final String INSTALLEDAPPDETAILS = "com.android.settings.applications.InstalledAppDetails"; 159 | public static final String INSTALLEROPTBOOTRECEIVER = "net.fypm.InstallerOpt.BootReceiver"; 160 | public static final String INSTALLEROPTMAINACTIVITY = "net.fypm.InstallerOpt.MainActivity$PrefsFragment"; 161 | public static final String JARVERIFIER = "java.util.jar.JarVerifier$VerifierEntry"; 162 | public static final String OPENSSLSIGNATURE = "com.android.org.conscrypt.OpenSSLSignature"; 163 | public static final String PACKAGEINSTALLERACTIVITY = "com.android.packageinstaller.PackageInstallerActivity"; 164 | public static final String PACKAGEINSTALLERGRANTPERMISSIONSACTIVITY = "com.android.packageinstaller.permission.ui.GrantPermissionsActivity"; 165 | public static final String PACKAGEMANAGERSERVICE = "com.android.server.pm.PackageManagerService"; 166 | public static final String PACKAGEPARSER = "android.content.pm.PackageParser"; 167 | public static final String CLASS_PACKAGE_PARSER_PACKAGE = "android.content.pm.PackageParser.Package"; 168 | public static final String SIGNATURE = "java.security.Signature"; 169 | public static final String SYSTEMUIACTIVITY = "com.android.systemui.SystemUIApplication"; 170 | public static final String UNINSTALLAPPPROGRESS = "com.android.packageinstaller.UninstallAppProgress"; 171 | public static final String UNINSTALLERACTIVITY = "com.android.packageinstaller.UninstallerActivity"; 172 | public static final String UTILS = "com.android.settings.Utils"; 173 | 174 | // Flags 175 | public static final int DEBUG_ENABLE_DEBUGGER = 0x1; 176 | public static final int DELETE_KEEP_DATA = 0x00000001; 177 | public static final int DOESNT_EXIST = -1; 178 | public static final int INSTALL_ALLOW_DOWNGRADE = 0x00000080; 179 | public static final int INSTALL_EXTERNAL = 0x00000008; 180 | public static final int INSTALL_FORWARD_LOCK = 0x00000001; 181 | public static final int INSTALL_SUCCEEDED = 1; 182 | public static final int ROOT_UID = 0; 183 | public static final int SHELL_UID = 2000; 184 | public static final int SYSTEM_UID = 1000; 185 | 186 | } 187 | -------------------------------------------------------------------------------- /main/java/net/fypm/InstallerOpt/ConfirmCheckSignatures.java: -------------------------------------------------------------------------------- 1 | package net.fypm.InstallerOpt; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.app.Activity; 5 | import android.app.AlertDialog; 6 | import android.content.Context; 7 | import android.content.DialogInterface; 8 | import android.content.SharedPreferences; 9 | import android.os.Bundle; 10 | import android.os.Handler; 11 | 12 | @SuppressLint("WorldReadableFiles") 13 | public class ConfirmCheckSignatures extends Activity { 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | @SuppressWarnings("deprecation") 18 | SharedPreferences prefs = getSharedPreferences( 19 | Common.PACKAGE_PREFERENCES, Context.MODE_WORLD_READABLE); 20 | final SharedPreferences.Editor prefsEditor = prefs.edit(); 21 | AlertDialog.Builder signatureCheckDialog = new AlertDialog.Builder( 22 | this, android.R.style.Theme_DeviceDefault_Dialog); 23 | signatureCheckDialog.setTitle(R.string.check_signatures); 24 | signatureCheckDialog 25 | .setMessage(R.string.confirm_check_signatures_message); 26 | signatureCheckDialog.setCancelable(true); 27 | signatureCheckDialog.setPositiveButton(android.R.string.ok, 28 | new DialogInterface.OnClickListener() { 29 | @Override 30 | public void onClick(DialogInterface dialog, int id) { 31 | dialog.dismiss(); 32 | prefsEditor.putBoolean( 33 | Common.PREF_DISABLE_CHECK_SIGNATURE, true) 34 | .apply(); 35 | final Handler handler = new Handler(); 36 | handler.postDelayed(new Runnable() { 37 | @Override 38 | public void run() { 39 | prefsEditor.putBoolean( 40 | Common.PREF_DISABLE_CHECK_SIGNATURE, 41 | false).apply(); 42 | } 43 | }, 30 * 1000); 44 | finish(); 45 | } 46 | }); 47 | signatureCheckDialog.setNegativeButton(android.R.string.cancel, 48 | new DialogInterface.OnClickListener() { 49 | @Override 50 | public void onClick(DialogInterface dialog, int id) { 51 | dialog.dismiss(); 52 | finish(); 53 | } 54 | }); 55 | 56 | AlertDialog confirmCheckSignatureDialog = signatureCheckDialog.create(); 57 | confirmCheckSignatureDialog.show(); 58 | 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /main/java/net/fypm/InstallerOpt/CustomBackupInstalledAppsListArrayAdapter.java: -------------------------------------------------------------------------------- 1 | package net.fypm.InstallerOpt; 2 | 3 | import android.app.Activity; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.ArrayAdapter; 8 | import android.widget.Filter; 9 | import android.widget.ImageView; 10 | import android.widget.TextView; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | public class CustomBackupInstalledAppsListArrayAdapter extends ArrayAdapter { 16 | 17 | private final List list; 18 | private List objects; 19 | private final Activity context; 20 | private Filter filter; 21 | 22 | static class ViewHolder { 23 | protected TextView appname; 24 | //protected TextView pname; 25 | protected TextView status; 26 | protected TextView versioninfo; 27 | protected ImageView appicon; 28 | } 29 | 30 | public CustomBackupInstalledAppsListArrayAdapter(Activity context, List list) { 31 | super(context, R.layout.backup_installed_apps_row, list); 32 | this.context = context; 33 | this.list = list; 34 | this.objects = list; 35 | } 36 | 37 | @Override 38 | public int getCount() { 39 | return objects.size(); 40 | } 41 | 42 | @Override 43 | public PInfo getItem(int position) { 44 | return objects.get(position); 45 | } 46 | 47 | /*@Override 48 | public long getItemId(int position) { 49 | return list.get(position).getId(); 50 | }*/ 51 | 52 | @Override 53 | public View getView(int position, View convertView, ViewGroup parent) { 54 | View view = null; 55 | 56 | if (convertView == null) { 57 | LayoutInflater inflator = context.getLayoutInflater(); 58 | view = inflator.inflate(R.layout.backup_installed_apps_row, null); 59 | final ViewHolder viewHolder = new ViewHolder(); 60 | viewHolder.appname = (TextView) view.findViewById(R.id.appname); 61 | //viewHolder.pname = (TextView) view.findViewById(R.id.pname); 62 | viewHolder.status = (TextView) view.findViewById(R.id.status); 63 | viewHolder.versioninfo = (TextView) view.findViewById(R.id.versioninfo); 64 | viewHolder.appicon = (ImageView) view.findViewById(R.id.appicon); 65 | view.setTag(viewHolder); 66 | } else { 67 | view = convertView; 68 | } 69 | 70 | ViewHolder holder = (ViewHolder) view.getTag(); 71 | holder.appname.setText(list.get(position).getName()); 72 | //holder.pname.setText(list.get(position).getPackageName()); 73 | holder.versioninfo.setText(context.getString(R.string.version_text) + list.get(position).getVersionName()); 74 | holder.status.setText(context.getString(R.string.status_text) + list.get(position).getStatus()); 75 | holder.appicon.setImageDrawable(list.get(position).getAppIcon()); 76 | 77 | return view; 78 | } 79 | 80 | @Override 81 | public Filter getFilter() { 82 | if (filter == null) 83 | filter = new CustomBackupInstalledAppsListArrayAdapter.AppFilter(objects); 84 | return filter; 85 | } 86 | 87 | /** 88 | * Class for filtering in Arraylist listview. Objects need a valid 89 | * 'toString()' method. 90 | * 91 | * @author Tobias Schürg inspired by Alxandr 92 | * (http://stackoverflow.com/a/2726348/570168) 93 | */ 94 | private class AppFilter extends Filter { 95 | 96 | private ArrayList sourceObjects; 97 | 98 | public AppFilter(List objects) { 99 | sourceObjects = new ArrayList(); 100 | synchronized (this) { 101 | sourceObjects.addAll(objects); 102 | } 103 | } 104 | 105 | @Override 106 | protected FilterResults performFiltering(CharSequence chars) { 107 | String filterSeq = chars.toString().toLowerCase(); 108 | FilterResults result = new FilterResults(); 109 | if (filterSeq != null && filterSeq.length() > 0) { 110 | ArrayList filter = new ArrayList(); 111 | 112 | for (T object : sourceObjects) { 113 | // the filtering itself: 114 | if (filterSeq.length() > 1) { 115 | if (object.toString().toLowerCase().contains(filterSeq)) { 116 | filter.add(object); 117 | } 118 | } else { 119 | if (object.toString().toLowerCase().startsWith(filterSeq)) { 120 | filter.add(object); 121 | } 122 | } 123 | } 124 | result.count = filter.size(); 125 | result.values = filter; 126 | } else { 127 | // add all objects 128 | synchronized (this) { 129 | result.values = sourceObjects; 130 | result.count = sourceObjects.size(); 131 | } 132 | } 133 | return result; 134 | } 135 | 136 | @SuppressWarnings("unchecked") 137 | @Override 138 | protected void publishResults(CharSequence constraint, 139 | FilterResults results) { 140 | // NOTE: this function is *always* called from the UI thread. 141 | ArrayList filtered = (ArrayList) results.values; 142 | notifyDataSetChanged(); 143 | clear(); 144 | for (int i = 0, l = filtered.size(); i < l; i++) 145 | add((PInfo) filtered.get(i)); 146 | notifyDataSetInvalidated(); 147 | } 148 | } 149 | 150 | } 151 | -------------------------------------------------------------------------------- /main/java/net/fypm/InstallerOpt/CustomBackupListArrayAdapter.java: -------------------------------------------------------------------------------- 1 | package net.fypm.InstallerOpt; 2 | 3 | import android.app.Activity; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.ArrayAdapter; 8 | import android.widget.Filter; 9 | import android.widget.ImageView; 10 | import android.widget.TextView; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | public class CustomBackupListArrayAdapter extends ArrayAdapter { 16 | 17 | private final List list; 18 | private List objects; 19 | private final Activity context; 20 | private Filter filter; 21 | 22 | static class ViewHolder { 23 | protected TextView appname; 24 | protected TextView backupdate; 25 | protected TextView filesize; 26 | protected TextView status; 27 | protected TextView versioninfo; 28 | protected ImageView appicon; 29 | } 30 | 31 | public CustomBackupListArrayAdapter(Activity context, List list) { 32 | super(context, R.layout.manage_backups_row, list); 33 | this.context = context; 34 | this.list = list; 35 | this.objects = list; 36 | } 37 | 38 | @Override 39 | public int getCount() { 40 | return objects.size(); 41 | } 42 | 43 | @Override 44 | public PInfo getItem(int position) { 45 | return objects.get(position); 46 | } 47 | 48 | /*@Override 49 | public long getItemId(int position) { 50 | return list.get(position).getId(); 51 | }*/ 52 | 53 | @Override 54 | public View getView(int position, View convertView, ViewGroup parent) { 55 | View view = null; 56 | 57 | if (convertView == null) { 58 | LayoutInflater inflator = context.getLayoutInflater(); 59 | view = inflator.inflate(R.layout.manage_backups_row, null); 60 | final ViewHolder viewHolder = new ViewHolder(); 61 | viewHolder.appname = (TextView) view.findViewById(R.id.appname); 62 | viewHolder.backupdate = (TextView) view.findViewById(R.id.backupdate); 63 | viewHolder.filesize = (TextView) view.findViewById(R.id.filesize); 64 | viewHolder.status = (TextView) view.findViewById(R.id.status); 65 | viewHolder.versioninfo = (TextView) view.findViewById(R.id.versioninfo); 66 | viewHolder.appicon = (ImageView) view.findViewById(R.id.appicon); 67 | view.setTag(viewHolder); 68 | } else { 69 | view = convertView; 70 | } 71 | 72 | ViewHolder holder = (ViewHolder) view.getTag(); 73 | holder.appname.setText(list.get(position).getName()); 74 | holder.backupdate.setText(context.getString(R.string.backupdate_text) + list.get(position).getItemModified()); 75 | holder.filesize.setText(context.getString(R.string.size_text) + list.get(position).getItemSizeHuman() + " (" + list.get(position).getItemSize() + context.getString(R.string.byte_text)); 76 | holder.status.setText(context.getString(R.string.status_text) + list.get(position).getStatus()); 77 | holder.versioninfo.setText(context.getString(R.string.version_text) + list.get(position).getVersionName() + " (" + list.get(position).getVersionCode() + ")"); 78 | holder.appicon.setImageDrawable(list.get(position).getAppIcon()); 79 | 80 | return view; 81 | } 82 | 83 | @Override 84 | public Filter getFilter() { 85 | if (filter == null) 86 | filter = new AppFilter(objects); 87 | return filter; 88 | } 89 | 90 | /** 91 | * Class for filtering in Arraylist listview. Objects need a valid 92 | * 'toString()' method. 93 | * 94 | * @author Tobias Schürg inspired by Alxandr 95 | * (http://stackoverflow.com/a/2726348/570168) 96 | */ 97 | private class AppFilter extends Filter { 98 | 99 | private ArrayList sourceObjects; 100 | 101 | public AppFilter(List objects) { 102 | sourceObjects = new ArrayList(); 103 | synchronized (this) { 104 | sourceObjects.addAll(objects); 105 | } 106 | } 107 | 108 | @Override 109 | protected FilterResults performFiltering(CharSequence chars) { 110 | String filterSeq = chars.toString().toLowerCase(); 111 | FilterResults result = new FilterResults(); 112 | if (filterSeq != null && filterSeq.length() > 0) { 113 | ArrayList filter = new ArrayList(); 114 | 115 | for (T object : sourceObjects) { 116 | // the filtering itself: 117 | if (filterSeq.length() > 1) { 118 | if (object.toString().toLowerCase().contains(filterSeq)) { 119 | filter.add(object); 120 | } 121 | } else { 122 | if (object.toString().toLowerCase().startsWith(filterSeq)) { 123 | filter.add(object); 124 | } 125 | } 126 | } 127 | result.count = filter.size(); 128 | result.values = filter; 129 | } else { 130 | // add all objects 131 | synchronized (this) { 132 | result.values = sourceObjects; 133 | result.count = sourceObjects.size(); 134 | } 135 | } 136 | return result; 137 | } 138 | 139 | @SuppressWarnings("unchecked") 140 | @Override 141 | protected void publishResults(CharSequence constraint, 142 | FilterResults results) { 143 | // NOTE: this function is *always* called from the UI thread. 144 | ArrayList filtered = (ArrayList) results.values; 145 | notifyDataSetChanged(); 146 | clear(); 147 | for (int i = 0, l = filtered.size(); i < l; i++) 148 | add((PInfo) filtered.get(i)); 149 | notifyDataSetInvalidated(); 150 | } 151 | } 152 | 153 | } 154 | -------------------------------------------------------------------------------- /main/java/net/fypm/InstallerOpt/MoveBackups.java: -------------------------------------------------------------------------------- 1 | package net.fypm.InstallerOpt; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.content.DialogInterface; 6 | import android.os.Bundle; 7 | 8 | public class MoveBackups extends Activity { 9 | 10 | public static final int RESULT_MOVE_PERFORM = 117; 11 | 12 | @Override 13 | protected void onCreate(Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | AlertDialog.Builder moveBackupsDialog = new AlertDialog.Builder( 16 | this, android.R.style.Theme_DeviceDefault_Dialog); 17 | moveBackupsDialog.setTitle(R.string.move_file_title); 18 | moveBackupsDialog 19 | .setMessage(getText(R.string.move_backups_message)); 20 | moveBackupsDialog.setCancelable(false); 21 | moveBackupsDialog.setPositiveButton(android.R.string.yes, 22 | new DialogInterface.OnClickListener() { 23 | @Override 24 | public void onClick(DialogInterface dialog, int id) { 25 | dialog.dismiss(); 26 | setResult(MoveBackups.RESULT_MOVE_PERFORM); 27 | finish(); 28 | } 29 | }); 30 | moveBackupsDialog.setNegativeButton(android.R.string.cancel, 31 | new DialogInterface.OnClickListener() { 32 | @Override 33 | public void onClick(DialogInterface dialog, int id) { 34 | dialog.dismiss(); 35 | finish(); 36 | } 37 | }); 38 | AlertDialog thisMoveBackupsDialog = moveBackupsDialog.create(); 39 | thisMoveBackupsDialog.show(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /main/java/net/fypm/InstallerOpt/MultiprocessPreferences.java: -------------------------------------------------------------------------------- 1 | package net.fypm.InstallerOpt; 2 | 3 | import java.util.Map.Entry; 4 | 5 | import android.annotation.SuppressLint; 6 | import android.content.ContentProvider; 7 | import android.content.ContentResolver; 8 | import android.content.ContentValues; 9 | import android.content.Context; 10 | import android.content.SharedPreferences; 11 | import android.content.UriMatcher; 12 | import android.database.Cursor; 13 | import android.database.MatrixCursor; 14 | import android.net.Uri; 15 | import android.os.Build; 16 | import android.preference.PreferenceManager; 17 | 18 | public class MultiprocessPreferences extends ContentProvider{ 19 | 20 | public static String PREFFERENCE_AUTHORITY; 21 | public static Uri BASE_URI; 22 | 23 | private static final String TYPE = "type"; 24 | private static final String KEY = "key"; 25 | 26 | private static final String INT_TYPE = "integer"; 27 | private static final String LONG_TYPE = "long"; 28 | private static final String FLOAT_TYPE = "float"; 29 | private static final String BOOLEAN_TYPE = "boolean"; 30 | private static final String STRING_TYPE = "string"; 31 | 32 | private static final int MATCH_DATA = 0x010000; 33 | 34 | private static UriMatcher matcher; 35 | 36 | private static void init(Context context){ 37 | 38 | PREFFERENCE_AUTHORITY = context.getString(R.string.multiprocess_preferences_authority); 39 | 40 | matcher = new UriMatcher(UriMatcher.NO_MATCH); 41 | matcher.addURI(PREFFERENCE_AUTHORITY, "*/*", MATCH_DATA); 42 | 43 | BASE_URI = Uri.parse("content://" + PREFFERENCE_AUTHORITY); 44 | } 45 | 46 | @Override 47 | public boolean onCreate() { 48 | if(matcher == null){ 49 | init(getContext()); 50 | } 51 | return true; 52 | } 53 | 54 | @Override 55 | public String getType(Uri uri) { 56 | return ContentResolver.CURSOR_ITEM_BASE_TYPE + "/vnd." + PREFFERENCE_AUTHORITY + ".item"; 57 | } 58 | 59 | @Override 60 | public int delete(Uri uri, String selection, String[] selectionArgs) { 61 | switch (matcher.match(uri)) { 62 | case MATCH_DATA: 63 | PreferenceManager.getDefaultSharedPreferences(getContext().getApplicationContext()) 64 | .edit().clear().commit(); 65 | break; 66 | default: 67 | throw new IllegalArgumentException("Unsupported uri " + uri); 68 | } 69 | 70 | return 0; 71 | } 72 | 73 | @SuppressLint("NewApi") 74 | @Override 75 | public Uri insert(Uri uri, ContentValues values) { 76 | switch (matcher.match(uri)) { 77 | case MATCH_DATA: 78 | SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(getContext().getApplicationContext()).edit(); 79 | for (Entry entry : values.valueSet()) { 80 | final Object value = entry.getValue(); 81 | final String key = entry.getKey(); 82 | if(value == null){ 83 | editor.remove(key); 84 | }else if (value instanceof String) 85 | editor.putString(key, (String) value); 86 | else if (value instanceof Boolean) 87 | editor.putBoolean(key, (Boolean) value); 88 | else if (value instanceof Long) 89 | editor.putLong(key, (Long) value); 90 | else if (value instanceof Integer) 91 | editor.putInt(key, (Integer) value); 92 | else if (value instanceof Float) 93 | editor.putFloat(key, (Float) value); 94 | else { 95 | throw new IllegalArgumentException("Unsupported type " + uri); 96 | } 97 | } 98 | if(Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO){ 99 | editor.apply(); 100 | }else{ 101 | editor.commit(); 102 | } 103 | break; 104 | default: 105 | throw new IllegalArgumentException("Unsupported uri " + uri); 106 | } 107 | 108 | return null; 109 | } 110 | 111 | @Override 112 | public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 113 | MatrixCursor cursor = null; 114 | switch (matcher.match(uri)) { 115 | case MATCH_DATA: 116 | final String key = uri.getPathSegments().get(0); 117 | final String type = uri.getPathSegments().get(1); 118 | cursor = new MatrixCursor(new String[] { key }); 119 | SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext().getApplicationContext()); 120 | if (!sharedPreferences.contains(key)) 121 | return cursor; 122 | MatrixCursor.RowBuilder rowBuilder = cursor.newRow(); 123 | Object object = null; 124 | if (STRING_TYPE.equals(type)) { 125 | object = sharedPreferences.getString(key, null); 126 | } else if (BOOLEAN_TYPE.equals(type)) { 127 | object = sharedPreferences.getBoolean(key, false) ? 1 : 0; 128 | } else if (LONG_TYPE.equals(type)) { 129 | object = sharedPreferences.getLong(key, 0l); 130 | } else if (INT_TYPE.equals(type)) { 131 | object = sharedPreferences.getInt(key, 0); 132 | } else if (FLOAT_TYPE.equals(type)) { 133 | object = sharedPreferences.getFloat(key, 0f); 134 | } else { 135 | throw new IllegalArgumentException("Unsupported type " + uri); 136 | } 137 | rowBuilder.add(object); 138 | break; 139 | default: 140 | throw new IllegalArgumentException("Unsupported uri " + uri); 141 | } 142 | return cursor; 143 | } 144 | 145 | @Override 146 | public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 147 | throw new UnsupportedOperationException(); 148 | } 149 | 150 | private static String getStringValue(Cursor cursor, String def) { 151 | if(cursor == null) 152 | return def; 153 | String value = def; 154 | if (cursor.moveToFirst()) { 155 | value = cursor.getString(0); 156 | } 157 | cursor.close(); 158 | return value; 159 | } 160 | 161 | private static boolean getBooleanValue(Cursor cursor, boolean def) { 162 | if(cursor == null) 163 | return def; 164 | boolean value = def; 165 | if (cursor.moveToFirst()) { 166 | value = cursor.getInt(0) > 0; 167 | } 168 | cursor.close(); 169 | return value; 170 | } 171 | 172 | private static int getIntValue(Cursor cursor, int def) { 173 | if(cursor == null) 174 | return def; 175 | int value = def; 176 | if (cursor.moveToFirst()) { 177 | value = cursor.getInt(0); 178 | } 179 | cursor.close(); 180 | return value; 181 | } 182 | 183 | private static long getLongValue(Cursor cursor, long def) { 184 | if(cursor == null) 185 | return def; 186 | long value = def; 187 | if (cursor.moveToFirst()) { 188 | value = cursor.getLong(0); 189 | } 190 | cursor.close(); 191 | return value; 192 | } 193 | 194 | private static float getFloatValue(Cursor cursor, float def) { 195 | if(cursor == null) 196 | return def; 197 | float value = def; 198 | if (cursor.moveToFirst()) { 199 | value = cursor.getFloat(0); 200 | } 201 | cursor.close(); 202 | return value; 203 | } 204 | 205 | public static Editor edit(Context context){ 206 | return new Editor(context); 207 | } 208 | 209 | public static MultiprocessSharedPreferences getDefaultSharedPreferences(Context context){ 210 | return new MultiprocessSharedPreferences(context); 211 | } 212 | 213 | public static class Editor{ 214 | 215 | Context context; 216 | 217 | private Editor(Context context){ 218 | this.context = context; 219 | } 220 | 221 | private ContentValues values = new ContentValues(); 222 | 223 | public void apply(){ 224 | context.getContentResolver().insert(getContentUri(context, KEY, TYPE), values); 225 | } 226 | 227 | public void commit(){ 228 | apply(); 229 | } 230 | 231 | public Editor putString(String key, String value) { 232 | values.put(key, value); 233 | return this; 234 | } 235 | 236 | public Editor putLong(String key, long value) { 237 | values.put(key, value); 238 | return this; 239 | } 240 | 241 | public Editor putBoolean(String key, boolean value) { 242 | values.put(key, value); 243 | return this; 244 | } 245 | 246 | public Editor putInt(String key, int value) { 247 | values.put(key, value); 248 | return this; 249 | } 250 | 251 | public Editor putFloat(String key, float value) { 252 | values.put(key, value); 253 | return this; 254 | } 255 | 256 | public void remove(String key) { 257 | values.putNull(key); 258 | } 259 | 260 | /** 261 | * Call content provider method immediately. apply or commit is not required for this case 262 | * So it's sync method. 263 | */ 264 | public void clear(){ 265 | context.getContentResolver().delete(getContentUri(context, KEY, TYPE), null, null); 266 | } 267 | } 268 | 269 | public static class MultiprocessSharedPreferences{ 270 | 271 | private Context context; 272 | 273 | private MultiprocessSharedPreferences(Context context){ 274 | this.context = context; 275 | } 276 | 277 | public Editor edit(){ 278 | return new Editor(context); 279 | } 280 | 281 | public String getString(String key, String def) { 282 | Cursor cursor = context.getContentResolver().query(getContentUri(context, key, STRING_TYPE), null, null, null, null); 283 | return getStringValue(cursor, def); 284 | } 285 | 286 | public long getLong(String key, long def) { 287 | Cursor cursor = context.getContentResolver().query(getContentUri(context, key, LONG_TYPE), null, null, null, null); 288 | return getLongValue(cursor, def); 289 | } 290 | 291 | public float getFloat(String key, float def) { 292 | Cursor cursor = context.getContentResolver().query(getContentUri(context, key, FLOAT_TYPE), null, null, null, null); 293 | return getFloatValue(cursor, def); 294 | } 295 | 296 | public boolean getBoolean(String key, boolean def) { 297 | Cursor cursor = context.getContentResolver().query(getContentUri(context, key, BOOLEAN_TYPE), null, null, null, null); 298 | return getBooleanValue(cursor, def); 299 | } 300 | 301 | public int getInt(String key, int def) { 302 | Cursor cursor = context.getContentResolver().query(getContentUri(context, key, INT_TYPE), null, null, null, null); 303 | return getIntValue(cursor, def); 304 | } 305 | 306 | } 307 | 308 | private static final Uri getContentUri(Context context, String key, String type){ 309 | if(BASE_URI == null){ 310 | init(context); 311 | } 312 | return BASE_URI.buildUpon().appendPath(key).appendPath(type).build(); 313 | } 314 | } -------------------------------------------------------------------------------- /main/java/net/fypm/InstallerOpt/NaturalOrderComparator.java: -------------------------------------------------------------------------------- 1 | package net.fypm.InstallerOpt; 2 | 3 | /* 4 | NaturalOrderComparator.java -- Perform 'natural order' comparisons of strings in Java. 5 | Copyright (C) 2003 by Pierre-Luc Paour 6 | 7 | Based on the C version by Martin Pool, of which this is more or less a straight conversion. 8 | Copyright (C) 2000 by Martin Pool 9 | 10 | This software is provided 'as-is', without any express or implied 11 | warranty. In no event will the authors be held liable for any damages 12 | arising from the use of this software. 13 | 14 | Permission is granted to anyone to use this software for any purpose, 15 | including commercial applications, and to alter it and redistribute it 16 | freely, subject to the following restrictions: 17 | 18 | 1. The origin of this software must not be misrepresented; you must not 19 | claim that you wrote the original software. If you use this software 20 | in a product, an acknowledgment in the product documentation would be 21 | appreciated but is not required. 22 | 2. Altered source versions must be plainly marked as such, and must not be 23 | misrepresented as being the original software. 24 | 3. This notice may not be removed or altered from any source distribution. 25 | */ 26 | 27 | import java.util.*; 28 | 29 | public class NaturalOrderComparator implements Comparator 30 | { 31 | int compareRight(String a, String b) 32 | { 33 | int bias = 0; 34 | int ia = 0; 35 | int ib = 0; 36 | 37 | // The longest run of digits wins. That aside, the greatest 38 | // value wins, but we can't know that it will until we've scanned 39 | // both numbers to know that they have the same magnitude, so we 40 | // remember it in BIAS. 41 | for (;; ia++, ib++) 42 | { 43 | char ca = charAt(a, ia); 44 | char cb = charAt(b, ib); 45 | 46 | if (!Character.isDigit(ca) && !Character.isDigit(cb)) 47 | { 48 | return bias; 49 | } 50 | else if (!Character.isDigit(ca)) 51 | { 52 | return -1; 53 | } 54 | else if (!Character.isDigit(cb)) 55 | { 56 | return +1; 57 | } 58 | else if (ca < cb) 59 | { 60 | if (bias == 0) 61 | { 62 | bias = -1; 63 | } 64 | } 65 | else if (ca > cb) 66 | { 67 | if (bias == 0) 68 | bias = +1; 69 | } 70 | else if (ca == 0 && cb == 0) 71 | { 72 | return bias; 73 | } 74 | } 75 | } 76 | 77 | public int compare(Object o1, Object o2) 78 | { 79 | String a = o1.toString(); 80 | String b = o2.toString(); 81 | 82 | int ia = 0, ib = 0; 83 | int nza = 0, nzb = 0; 84 | char ca, cb; 85 | int result; 86 | 87 | while (true) 88 | { 89 | // only count the number of zeroes leading the last number compared 90 | nza = nzb = 0; 91 | 92 | ca = charAt(a, ia); 93 | cb = charAt(b, ib); 94 | 95 | // skip over leading spaces or zeros 96 | while (Character.isSpaceChar(ca) || ca == '0') 97 | { 98 | if (ca == '0') 99 | { 100 | nza++; 101 | } 102 | else 103 | { 104 | // only count consecutive zeroes 105 | nza = 0; 106 | } 107 | 108 | ca = charAt(a, ++ia); 109 | } 110 | 111 | while (Character.isSpaceChar(cb) || cb == '0') 112 | { 113 | if (cb == '0') 114 | { 115 | nzb++; 116 | } 117 | else 118 | { 119 | // only count consecutive zeroes 120 | nzb = 0; 121 | } 122 | 123 | cb = charAt(b, ++ib); 124 | } 125 | 126 | // process run of digits 127 | if (Character.isDigit(ca) && Character.isDigit(cb)) 128 | { 129 | if ((result = compareRight(a.substring(ia), b.substring(ib))) != 0) 130 | { 131 | return result; 132 | } 133 | } 134 | 135 | if (ca == 0 && cb == 0) 136 | { 137 | // The strings compare the same. Perhaps the caller 138 | // will want to call strcmp to break the tie. 139 | return nza - nzb; 140 | } 141 | 142 | if (ca < cb) 143 | { 144 | return -1; 145 | } 146 | else if (ca > cb) 147 | { 148 | return +1; 149 | } 150 | 151 | ++ia; 152 | ++ib; 153 | } 154 | } 155 | 156 | static char charAt(String s, int i) 157 | { 158 | if (i >= s.length()) 159 | { 160 | return 0; 161 | } 162 | else 163 | { 164 | return s.charAt(i); 165 | } 166 | } 167 | 168 | public static void main(String[] args) 169 | { 170 | String[] strings = new String[] { "1-2", "1-02", "1-20", "10-20", "fred", "jane", "pic01", 171 | "pic2", "pic02", "pic02a", "pic3", "pic4", "pic 4 else", "pic 5", "pic05", "pic 5", 172 | "pic 5 something", "pic 6", "pic 7", "pic100", "pic100a", "pic120", "pic121", 173 | "pic02000", "tom", "x2-g8", "x2-y7", "x2-y08", "x8-y8" }; 174 | 175 | List orig = Arrays.asList(strings); 176 | 177 | System.out.println("Original: " + orig); 178 | 179 | List scrambled = Arrays.asList(strings); 180 | Collections.shuffle(scrambled); 181 | 182 | System.out.println("Scrambled: " + scrambled); 183 | 184 | Collections.sort(scrambled, new NaturalOrderComparator()); 185 | 186 | System.out.println("Sorted: " + scrambled); 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /main/java/net/fypm/InstallerOpt/PInfo.java: -------------------------------------------------------------------------------- 1 | package net.fypm.InstallerOpt; 2 | 3 | import android.graphics.drawable.Drawable; 4 | 5 | import java.util.Comparator; 6 | import java.util.Date; 7 | 8 | public class PInfo implements Comparable { 9 | private String appname; 10 | private String pname; 11 | private int uid; 12 | private String versionName; 13 | private int versionCode; 14 | private Drawable appicon; 15 | private long itemSize; 16 | private String itemSizeHuman; 17 | private Date itemModified; 18 | private String formattedDate; 19 | private String calculatedDigest; 20 | private String apkName; 21 | private String status; 22 | private String sourceDir; 23 | 24 | public PInfo(String appname, String pname, int uid, String versionName, int versionCode, Drawable appicon, long itemSize, String itemSizeHuman, Date itemModified, String formattedDate, String calculatedDigest, String apkName, String status, String sourceDir) { 25 | this.appname = appname; 26 | this.pname = pname; 27 | this.uid = uid; 28 | this.versionName = versionName; 29 | this.versionCode = versionCode; 30 | this.appicon = appicon; 31 | this.itemSize = itemSize; 32 | this.itemSizeHuman = itemSizeHuman; 33 | this.itemModified = itemModified; 34 | this.formattedDate = formattedDate; 35 | this.calculatedDigest = calculatedDigest; 36 | this.apkName = apkName; 37 | this.status = status; 38 | this.sourceDir = sourceDir; 39 | } 40 | 41 | public int compareTo(PInfo other) { 42 | return appname.compareTo(other.appname); 43 | } 44 | 45 | public static Comparator COMPARE_BY_APKNAME = new Comparator() { 46 | public int compare(PInfo one, PInfo other) { 47 | return one.apkName.compareTo(other.apkName); 48 | } 49 | }; 50 | 51 | public static Comparator COMPARE_BY_DATE = new Comparator() { 52 | public int compare(PInfo one, PInfo other) { 53 | return one.itemModified.compareTo(other.itemModified); 54 | } 55 | }; 56 | 57 | public static Comparator COMPARE_BY_SIZE = new Comparator() { 58 | public int compare(PInfo one, PInfo other) { 59 | return Long.valueOf(one.itemSize).compareTo(Long.valueOf(other.itemSize)); 60 | } 61 | }; 62 | 63 | public static Comparator COMPARE_BY_STATUS = new Comparator() { 64 | public int compare(PInfo one, PInfo other) { 65 | return one.status.compareTo(other.status); 66 | } 67 | }; 68 | 69 | public String getName() { 70 | return appname; 71 | } 72 | 73 | public Drawable getAppIcon() { 74 | return appicon; 75 | } 76 | 77 | public int getUid() { 78 | return uid; 79 | } 80 | 81 | public String getPackageName() { 82 | return pname; 83 | } 84 | 85 | public int getVersionCode() { 86 | return versionCode; 87 | } 88 | 89 | public String getVersionName() { 90 | return versionName; 91 | } 92 | 93 | public long getItemSize() { 94 | return itemSize; 95 | } 96 | 97 | public String getItemSizeHuman() { 98 | return itemSizeHuman; 99 | } 100 | 101 | public Date getItemModifiedRaw() { 102 | return itemModified; 103 | } 104 | 105 | public String getItemModified() { 106 | return formattedDate; 107 | } 108 | 109 | public String getMD5() { 110 | return calculatedDigest; 111 | } 112 | 113 | public String getApkName() { 114 | return apkName; 115 | } 116 | 117 | public String getStatus() { 118 | return status; 119 | } 120 | 121 | public String getSourceDir() { 122 | return sourceDir; 123 | } 124 | 125 | public String toString() { 126 | return appname; 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /main/java/net/fypm/InstallerOpt/Reboot.java: -------------------------------------------------------------------------------- 1 | package net.fypm.InstallerOpt; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.content.DialogInterface; 6 | import android.os.Bundle; 7 | import android.widget.Toast; 8 | 9 | public class Reboot extends Activity { 10 | 11 | public static final int RESULT_CANCELED = 116; 12 | 13 | @Override 14 | protected void onCreate(Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | AlertDialog.Builder rebootDialog = new AlertDialog.Builder( 17 | this, android.R.style.Theme_DeviceDefault_Dialog); 18 | rebootDialog.setTitle(R.string.enable_reboot_message); 19 | rebootDialog 20 | .setMessage(getText(R.string.sdcard_access_message)); 21 | rebootDialog.setCancelable(false); 22 | rebootDialog.setPositiveButton(android.R.string.yes, 23 | new DialogInterface.OnClickListener() { 24 | @Override 25 | public void onClick(DialogInterface dialog, int id) { 26 | dialog.dismiss(); 27 | MultiprocessPreferences.getDefaultSharedPreferences(Reboot.this).edit().putBoolean(Common.PREF_ENABLE_EXTERNAL_SDCARD_FULL_ACCESS, true).apply(); 28 | MultiprocessPreferences.getDefaultSharedPreferences(Reboot.this).edit().putBoolean(Common.PREF_ENABLE_BACKUP_APK_FILE, false).apply(); 29 | MultiprocessPreferences.getDefaultSharedPreferences(Reboot.this).edit().putBoolean(Common.PREF_CONTINUE_BACKUP_ON_REBOOT, true).apply(); 30 | try { 31 | Process proc = Runtime.getRuntime() 32 | .exec(new String[]{"su", "-c", "reboot"}); 33 | proc.waitFor(); 34 | } catch (Exception ex) { 35 | ex.printStackTrace(); 36 | Toast.makeText(Reboot.this, R.string.reboot_failed, Toast.LENGTH_LONG).show(); 37 | 38 | } 39 | finish(); 40 | } 41 | }); 42 | rebootDialog.setNegativeButton(android.R.string.cancel, 43 | new DialogInterface.OnClickListener() { 44 | @Override 45 | public void onClick(DialogInterface dialog, int id) { 46 | dialog.dismiss(); 47 | setResult(Reboot.RESULT_CANCELED); 48 | finish(); 49 | } 50 | }); 51 | AlertDialog thisRebootDialog = rebootDialog.create(); 52 | thisRebootDialog.show(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /main/java/net/fypm/InstallerOpt/Stats.java: -------------------------------------------------------------------------------- 1 | package net.fypm.InstallerOpt; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.content.DialogInterface; 6 | import android.os.Build; 7 | import android.os.Bundle; 8 | import android.os.StatFs; 9 | import android.util.Log; 10 | import android.widget.Toast; 11 | 12 | import java.io.File; 13 | import java.util.ArrayList; 14 | import java.util.Arrays; 15 | import java.util.LinkedList; 16 | import java.util.List; 17 | 18 | public class Stats extends Activity { 19 | 20 | private static final String TAG = "InstallerOpt"; 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | String backupDir = MultiprocessPreferences.getDefaultSharedPreferences(this).getString(Common.PREF_BACKUP_APK_LOCATION, null); 26 | AlertDialog.Builder statsDialog = new AlertDialog.Builder( 27 | this, android.R.style.Theme_DeviceDefault_Dialog); 28 | statsDialog.setTitle(R.string.stats_menu); 29 | if (backupDir != null) { 30 | File f = new File(backupDir); 31 | if (!f.exists()) { 32 | if (f.mkdir()) { 33 | Log.e(TAG, "Backup directory did not exist and was created, possibly deleted outside of InstallerOpt???"); 34 | Toast.makeText(this, R.string.backup_location_missing_message, Toast.LENGTH_LONG).show(); 35 | } 36 | } 37 | final File PACKAGE_DIR = new File(backupDir + File.separator); 38 | long mSize = getFileSize(PACKAGE_DIR); 39 | String fileCount = getFileCount(PACKAGE_DIR) + getString(R.string.apps_text); 40 | if (fileCount != null) { 41 | statsDialog.setMessage(String.format("%s %s %s %s %-22s %10s %-22s %10s %-20s %s", 42 | getString(R.string.backup_location), PACKAGE_DIR.toString(), 43 | getString(R.string.backup_last_backed_up), getLatestFilefromDir(backupDir), 44 | getString(R.string.backup_used), humanReadableByteCount(mSize, true), 45 | getString(R.string.backup_free), humanReadableByteCount(getAvailableSpaceInBytes(backupDir), true), 46 | getString(R.string.backup_total_items), fileCount 47 | )); 48 | statsDialog.setCancelable(false); 49 | statsDialog.setPositiveButton(R.string.delete_all_button_text, 50 | new DialogInterface.OnClickListener() { 51 | @Override 52 | public void onClick(DialogInterface dialog, int id) { 53 | dialog.dismiss(); 54 | deleteRecursive(PACKAGE_DIR); 55 | finish(); 56 | } 57 | }); 58 | statsDialog.setNegativeButton(android.R.string.cancel, 59 | new DialogInterface.OnClickListener() { 60 | @Override 61 | public void onClick(DialogInterface dialog, int id) { 62 | dialog.dismiss(); 63 | finish(); 64 | } 65 | }); 66 | } 67 | } else { 68 | statsDialog 69 | .setMessage(R.string.enable_backup_message); 70 | statsDialog.setCancelable(true); 71 | statsDialog.setNegativeButton(android.R.string.cancel, 72 | new DialogInterface.OnClickListener() { 73 | @Override 74 | public void onClick(DialogInterface dialog, int id) { 75 | dialog.dismiss(); 76 | finish(); 77 | } 78 | }); 79 | } 80 | AlertDialog thisStatsDialog = statsDialog.create(); 81 | thisStatsDialog.show(); 82 | } 83 | 84 | public static void deleteRecursive(File fileOrDirectory) { 85 | if (fileOrDirectory.isDirectory()) { 86 | for (File child : fileOrDirectory.listFiles()) { 87 | deleteRecursive(child); 88 | } 89 | } 90 | if (fileOrDirectory.delete()) { 91 | Log.i(TAG, "deleteRecursive: Successfully deleted"); 92 | } 93 | } 94 | 95 | public static long getAvailableSpaceInBytes(String path) { 96 | long availableSpace = -1L; 97 | StatFs stat = new StatFs(path); 98 | if (Build.VERSION.SDK_INT >= 18) { 99 | availableSpace = stat.getAvailableBlocksLong() * stat.getBlockSizeLong(); 100 | } else { 101 | availableSpace = stat.getAvailableBlocks() * stat.getBlockSize(); 102 | } 103 | return availableSpace; 104 | } 105 | 106 | public static int getFileCount(final File file) { 107 | ArrayList backup_dir = new ArrayList(Arrays.asList(file.list())); 108 | int result = backup_dir.size(); 109 | return result; 110 | } 111 | 112 | public static long getFileSize(final File file) { 113 | if (file == null || !file.exists()) 114 | return 0; 115 | if (!file.isDirectory()) 116 | return file.length(); 117 | final List dirs = new LinkedList(); 118 | dirs.add(file); 119 | long result = 0; 120 | while (!dirs.isEmpty()) { 121 | final File dir = dirs.remove(0); 122 | if (!dir.exists()) 123 | continue; 124 | final File[] listFiles = dir.listFiles(); 125 | if (listFiles == null || listFiles.length == 0) 126 | continue; 127 | for (final File child : listFiles) { 128 | result += child.length(); 129 | if (child.isDirectory()) 130 | dirs.add(child); 131 | } 132 | } 133 | return result; 134 | } 135 | 136 | private String getLatestFilefromDir(String dirPath) { 137 | File dir = new File(dirPath); 138 | File[] files = dir.listFiles(); 139 | if (files == null || files.length == 0) { 140 | return "N/A"; 141 | } 142 | 143 | File lastModifiedFile = files[0]; 144 | for (int i = 1; i < files.length; i++) { 145 | if (lastModifiedFile.lastModified() < files[i].lastModified()) { 146 | lastModifiedFile = files[i]; 147 | } 148 | } 149 | return lastModifiedFile.getName(); 150 | } 151 | 152 | public static String humanReadableByteCount(long bytes, boolean si) { 153 | int unit = si ? 1000 : 1024; 154 | if (bytes < unit) return bytes + " B"; 155 | int exp = (int) (Math.log(bytes) / Math.log(unit)); 156 | String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i"); 157 | return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /main/res/drawable/ic_notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afxefx/InstallerOpt/28bceace03e02313f64e17e4fd638a3bd8396c87/main/res/drawable/ic_notification.png -------------------------------------------------------------------------------- /main/res/drawable/toast_frame.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afxefx/InstallerOpt/28bceace03e02313f64e17e4fd638a3bd8396c87/main/res/drawable/toast_frame.9.png -------------------------------------------------------------------------------- /main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 15 | -------------------------------------------------------------------------------- /main/res/layout/backup_installed_apps_row.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 | 21 | 26 | 27 | 33 | 34 | 38 | 39 | 45 | 46 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 74 | 75 | -------------------------------------------------------------------------------- /main/res/layout/backup_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 19 | 20 | 21 | 22 | 23 | 60 | -------------------------------------------------------------------------------- /main/res/layout/manage_backups_row.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 | 21 | 26 | 27 | 33 | 34 | 38 | 39 | 45 | 46 | 52 | 53 | 59 | 60 | 66 | 67 | 68 | 69 | 70 | 81 | 82 | -------------------------------------------------------------------------------- /main/res/layout/version_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 14 | 28 | 29 | 41 | 42 | 56 | 57 | 69 | 70 | 81 | 82 | 96 | 97 | 109 | 110 | 124 | 125 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /main/res/menu/backup_installed_apps_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | -------------------------------------------------------------------------------- /main/res/menu/manage_backup_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 24 | 25 | 26 | 28 | 30 | 32 | -------------------------------------------------------------------------------- /main/res/menu/menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 9 | 10 | 12 | 14 | 16 | 17 | 18 | 20 | -------------------------------------------------------------------------------- /main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afxefx/InstallerOpt/28bceace03e02313f64e17e4fd638a3bd8396c87/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afxefx/InstallerOpt/28bceace03e02313f64e17e4fd638a3bd8396c87/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afxefx/InstallerOpt/28bceace03e02313f64e17e4fd638a3bd8396c87/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afxefx/InstallerOpt/28bceace03e02313f64e17e4fd638a3bd8396c87/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afxefx/InstallerOpt/28bceace03e02313f64e17e4fd638a3bd8396c87/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /main/res/values-pl/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | O aplikacji 5 | Zaawansowane 6 | InstallerOpt 7 | Aplikacja została odinstalowana 8 | Ustawienia informacji o aplikacji 9 | Ustawienia instalacji aplikacji 10 | Ustawienia aplikacji 11 | Ustawienia odinstalowania aplikacji 12 | \nFolder kopii zapasowej free: 13 | \n\nOstatnia kopia zapasowa:\n 14 | Lokalizacja fodleru kopii zapasowej:\n 15 | Katalog kopii zapasowej nie istnieje i został stworzony, możliwe usunięcie poza InstallerOpt? 16 | \n\nŁączne kopie zapasowe: 17 | \n\nUżywany folder kopii zapasowej: 18 | Sprawdzanie podpisów 19 | Potwierdzenie sprawdzania podpisów 20 | Wyłącz sprawdzanie podpisów dla tej instalacji? 21 | \nObecna wersja: 22 | \nKod obecnej wersji: 23 | Usuń 24 | Temat wsparcia XDA: http://forum.xda-developers.com/xposed/modules/xposed-installeropt-0-4-t3377008\n\nGithub: https://github.com/afxefx/InstallerOpt 25 | Wyłącz 26 | Włącz 27 | Proszę włączyć kopię zapasową plików APK i wybrać folder kopii zapasowej, aby zobaczyć statystyki 28 | Włącz i uruchom ponownie? 29 | Rozmiar starych i nowych folderów nie pasuje do siebie, usunięcie starego folderu anulowane 30 | Nowy folder kopii zapasowej nie ma wystarczającej ilości wolnego miejsca, proszę wybrać inny 31 | Zarządzanie 32 | Ustawienia różne 33 | Nowy folder kopii zapasowej różni się od starego, chcesz przenieść stare kopie zapasowe do nowej lokalizacji? 34 | Przeniesienie zakończone powodzeniem 35 | Przenoszenie pliku* 36 | *z* 37 | Przygotowanie do przenoszenia plików do nowej lokalizacji kopii zapasowej 38 | Przenieść stare kopie zapasowe? 39 | Nowa wersja: 40 | Kod nowej wersji: 41 | Brak plików w starym folderze kopii zapasowej 42 | Nie można zapisać do wybranego folderu, proszę wybrać inny 43 | Oops, odmówiono uprawnienia do odczytu/zapisu na pamięci masowej urządzenia 44 | Uprawnienia przyznane, teraz możliwy osczyt/zapis na pamięci masowej urządzenia 45 | Uruchom ponownie 46 | Uruchomienie ponowne nie powiodło się, proszę zrobić to ręcznie! 47 | Resetowanie ustawień w celu uniknięcia konfliktów 48 | Pełny dostęp do zewnętrznej karty SD jest potrzebny tylko do tworzenia kopii zapasowych na zewnętrznych kartach SD, czy chcesz włączyć a następnie uruchomić ponownie? 49 | Status kopii zapasowej 50 | Moduł został zaktualizowany 51 | Uprawnienie do zapisu jest potrzebne, aby działała funkcja utworzenia kopii zapasowej plików APK 52 | 53 | Ile starych wersji kopii zapasowych zachować 54 | Limit kopii zapasowych 55 | Zezwól na instalowanie aplikacji ze zduplikowanymi uprawnieniami 56 | Wyłącz sprawdzanie zduplikowanych uprawnień 57 | Zezwól na instalowanie aplikacji bez przeprowadzania kontroli uprawnień 58 | Wyłącz sprawdzanie uprawnień 59 | Zawsze przywracaj ostatnią wersję SDK 60 | Wyłącz sprawdzanie SDK 61 | Wyłącza instalowanie aplikacji w tle 62 | Wyłącz instalowanie w tle 63 | Wyłącza odinstalowanie aplikacji w tle 64 | Wyłącz odinstalowanie w tle 65 | Zezwól na instalowanie niezweryfikowanych aplikacji 66 | Wyłącz weryfikację aplikacji 67 | Niedopasowane certyfikaty dotyczące plików JAR będą dozwolone 68 | Wyłącz weryfikację JAR 69 | Włącza przyciski wyczyść pamięć i dane przed obliczeniem rozmiaru 70 | Włącz przyciski dla aplikacji 71 | Automatycznie zamyka okno po zakończeniu instalacji aplikacji 72 | Zamykanie automatycznej instalacji 73 | Wibracja telefonu po zakończeniu instalacji przy użyciu opcji automatycznej instalacji 74 | Wibracja automatycznej instalacji 75 | Automatycznie zamyka okno po zakończeniu odinstalowania 76 | Zamykanie automatycznego odinstalowania 77 | Automatycznie ukrywa okno instalacji 78 | Ukrywanie automatycznej instalacji 79 | Automatyczne uruchomienie aplikacji po ukończeniu instalacji 80 | Uruchomienie po automatycznej instalacji 81 | Automatycznie instaluje aplikację bez interakcji z użytkownikiem 82 | Automatyczna instalacja 83 | Automatycznie odinstalowuje aplikację bez interakcji z użytkownikiem 84 | Automatyczne odinstalowanie 85 | Tworzenie kopii zapasowych plików APK po zainstalowaniu w folderze wybranym przez użytkownika 86 | Kopia zapasowa plików APK 87 | Przełącz na ciemny motyw 88 | Ciemny motyw 89 | Włącza debugowanie dla wszystkich aplikacji 90 | Debugowanie aplikacji 91 | Włącza dodatkowy rejestr InstallerOpt 92 | Debugowanie 93 | Usuwa pliki APK po instalacji 94 | Usuń pliki APK 95 | Próba ukrycia obecności Lucky Patcher dla innych aplikacji 96 | Lucky Patcher 97 | Zezwól na instalowanie aplikacji z niedopasowanymi podpisami 98 | Wyłącz sprawdzanie podpisów 99 | Włącza możliwość wyłączenia aplikacji systemowych, długie przytrzymanie wykonuje odinstalowanie 100 | Aplikacje systemowe 101 | Modyfikuje przycisk odinstalowania aplikacji w oknie informacji o aplikacji na wyłączony (wyłącz), długie przytrzymanie wykonuje odinstalowanie 102 | Wyłącz aplikacje użytkownika 103 | Zezwól na instalowanie aplikacji z niezweryfikowanymi podpisami 104 | Wyłącz weryfikację podpisu 105 | Zezwól na instalowanie starszych wersji aplikacji 106 | Starsza wersja aplikacji 107 | Wymusza język angielski dla tego modułu, niezależnie od obecnego ustawienia systemu 108 | Wymuś angielski 109 | Ukryj okno dialogowe kiedy aplikacja zostanie zatrzymana 110 | Wyłącz okno dialogowe FC 111 | Usuwa ikonę aplikacji z launchera 112 | Ikona aplikacji 113 | Zezwól na instalowanie nieznanych aplikacji 114 | Nieznane aplikacje 115 | Dane aplikacji nie zostaną usunięte po odinstalowaniu aplikacji 116 | Zachowaj dane aplikacji 117 | Kliknięcie ikony aplikacji podczas przeglądania informacji o aplikacji, aby uruchomić aplikację 118 | Uruchomienie aplikacji 119 | Kliknięcie nazwy aplikacji podczas przeglądania informacji o aplikacji, aby zobaczyć nazwę pakietu 120 | Wyświetlanie nazwy pakietu 121 | Długie przytrzymanie ikony aplikacji podczas przeglądania informacji o aplikacji, aby otworzyć w Sklepie Play 122 | Otwórz w Sklepie Play 123 | Zezwól na interakcje z przyciskami pod powiadomieniami toast 124 | Pokaż przyciski 125 | Włącza możliwość odinstalowania aplikacji ustawionych jako administrator urządzenia 126 | Odinstalowanie administratora urządzenia 127 | Włącza możliwość odinstalowania aplikacji systemowych przez długie przytrzymanie 128 | Odinstalowanie aplikacji systemowych 129 | Wyświetla kod obecnej i nowej wersji aplikacji przed zainstalowaniem 130 | Wyświetlanie kodu wersji 131 | Wyświetla informację o wersji w oknie instalacji 132 | Informacja o wersji 133 | Wyświetla obecną i nową wersję aplikacji przed zainstalowaniem 134 | Wyświetlanie wersji 135 | Wyświetla informację o wersji w powiadomieniu toast 136 | Informacja o wersji w powiadomieniu 137 | Zezwala na odczyt/zapis na zewnętrznej karcie SD (wymaga ponownego uruchomienia) 138 | Pełny dostęp do zewnętrznej karty SD 139 | Preferencje Eksperta - POSTĘPOWAĆ OSTROŻNIE! 140 | Otwórz App Ops 141 | Otwórz App Ops po zainstalowaniu aplikacji 142 | Wyłącza instalowanie aplikacji przez powłokę 143 | Wyłącz instalację przez powłokę 144 | Usuwanie kopii zapasowej zakończono pomyślnie 145 | Usuń wybrane kopie zapasowe 146 | Przygotowanie do usunięcia plików z lokalizacji kopii zapasowej 147 | Zarządzaj kopiami zapasowymi 148 | Nie wybrano kopii zapasowej 149 | Przywróć wybrane kopie zapasowe 150 | Przygotowanie do przywracania plików z lokalizacji kopii zapasowej 151 | Przywracanie kopii zapasowej zakończono pomyślnie 152 | Informacje o pliku 153 | Informacje o pliku 154 | Usuwanie pliku* 155 | Przywróć 156 | Przywracanie pliku* 157 | \n\nData kopii pliku:\n 158 | \n\nSuma kontrolna MD5:\n 159 | Nazwa pliku:\n 160 | \n\nRozmiar pliku:\n 161 | Dodać wyjątki? 162 | Ta opcja będzie blokować wszystkie instalacje w tle i może kolidować z automatycznym przywracaniem np. w Titanium Backup, chcesz dodać wyjątki? 163 | Brak wybranych wyjątków, wybierz aplikację i spróbuj ponownie 164 | Sortuj 165 | Nazwa - A-Z 166 | Nazwa - Z-A 167 | Rozmiar - Od najmniejszego do największego 168 | Rozmiar - Od największego do najmniejszego 169 | Instalacja aplikacji na pamięci zewnętrznej, jeśli włączone. Pamięć wewnętrzna, jeśli wyłączone 170 | Instalowanie na pamięci zewnętrznej 171 | Parsowanie aplikacji* 172 | *z* 173 | Parsowanie kopii zapasowej* 174 | *z* 175 | Status - Rosnąco 176 | Status - Malejąco 177 | \nObecna wersja: 178 | \nKod obecnej wersji: 179 | Ładowanie aplikacji… 180 | Ładowanie kopii zapasowych… 181 | Tworzenie kopii zapasowej pliku* 182 | *z* 183 | Kopia zapasowa zainstalowanych aplikacji 184 | Kopia zapasowa 185 | Przygotowanie do tworzenia kopii zapasowej aplikacji do lokalizacji kopii zapasowej 186 | Kopia zapasowa preferencji 187 | Brak zapisanych preferencji 188 | Pomyślnie wykonano kopię zapasową preferencji 189 | Pomyślnie zresetowano preferencje 190 | Pomyślnie przywrócono preferencje 191 | Preferencje 192 | Resetuj preferencje 193 | Przywróć preferencje 194 | Udostępnij 195 | Włącz powiadomienia dla akcji InstallerOpt 196 | Powiadomienia 197 | Komunikat nieznanych aplikacji 198 | Blokuje zainstalowanie aplikacji, ale wyświetla komunikat czy pozwolić na zainstalowanie 199 | Główny przełącznik 200 | Odznacz, aby wyłączyć wszystkie funkcje InstallerOpt 201 | Moduł InstallerOpt 202 |  wybranych aplikacji 203 |  wybranych kopii zapasowych 204 | Niepowodzenie instalacji 205 | Kod błędu:  206 | Instalacja zakończona sukcesem 207 |  zainstalowana 208 | Filtr… 209 | Data - Od najstarszej do najnowszej 210 | Data - Od najnowszej do najstarszej 211 |  niezainstalowana 212 | Data kopii zapasowej:  213 |  bajtów) 214 | Rozmiar:  215 | Status:  216 | Wersja:  217 |  aplikacji 218 | Niedostępne 219 | -------------------------------------------------------------------------------- /main/res/values-pt/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Sobre 5 | Avançado 6 | InstallerOpt 7 | Desinstalação concluída 8 | Preferências de Informações do Aplicativo 9 | Preferências de Instalação de Aplicativos 10 | Preferências do Aplicativo 11 | Preferências de Desinstalação de Aplicativos 12 | Interruptor Geral 13 | Backups Excluídos com Sucesso 14 | Preparando para excluir arquivos do local de backup 15 | Excluir Backups Selecionados 16 | \n\nData do backup:\n 17 | \n\nChecksum MD5:\n 18 | Nome do Arquivo:\n 19 | \n\nTamanho do Arquivo:\n 20 | Informações do Arquivo 21 | Fazendo backup do arquivo* 22 | *de* 23 | Preparando para fazer backup dos aplicativo(s) para o local de backup 24 | \nEspaço livre na pasta de backup: 25 | Backup de Apps Instalados 26 | \n\nÚltimo backup:\n 27 | Local da pasta de backup:\n 28 | A pasta de backup não existia e foi criada, possivelmente excluída fora do InstallerOpt??? 29 | Restauração de Backup Concluída 30 | Preparando para restaurar arquivos do local de backup 31 | Restaurar Backups Selecionados 32 | Nenhum arquivo de backup selecionado, por favor selecione um backup e tente novamente 33 | \n\nTotal de backups: 34 | \n\nPasta de backup utilizada: 35 | Verificando assinaturas 36 | Confirmando verificação de assinaturas 37 | Desativar verificação de assinaturas para essa instalação? 38 | Versão atual: 39 | Código de versão atual: 40 | \nVersão atual: 41 | \nCódigo de versão atual: 42 | Excluir tudo 43 | Excluir 44 | Excluindo arquivo* 45 | Tópico de suporte no XDA: http://forum.xda-developers.com/xposed/modules/xposed-installeropt-0-4-t3377008\n\nGitHub: https://github.com/afxefx/InstallerOpt 46 | Desativar 47 | Ativar 48 | Por favor ative a opção de backup dos APKs instalados e selecione sua pasta de backup para ver as estatísticas 49 | Adicionar Exceções? 50 | Ativar e Reiniciar? 51 | Essa opção irá bloquear todas as instalações em segundo plano e pode interferir com restaurações automáticas em apps como Titanium Backup, gostaria de adicionar exceções? 52 | Nenhuma exceção selecionada, por favor selecione um aplicativo e tente novamente 53 | Preferências Avançadas - PROCEDA COM CUIDADO! 54 | O tamanho da pasta antiga difere da nova pasta, exclusão da pasta antiga cancelada 55 | A nova pasta de backup não possui espaço livre suficiente, por favor escolha outra pasta 56 | Carregando backups... 57 | Carregando aplicativos... 58 | Gerenciar 59 | Gerenciar Backups 60 | Preferências Diversas 61 | A nova pasta de backup difere do local anterior, gostaria de mover os backups antigos para a nova pasta? 62 | Backups Movidos com Sucesso 63 | Movendo arquivo* 64 | *de* 65 | Preparando para mover os arquivos para o novo local de backup 66 | Mover backups antigos? 67 | Nova versão: 68 | Novo código de versão: 69 | Nenhum arquivo presente na pasta de backup anterior 70 | Não foi possível gravar na pasta selecionada, por favor selecione outro local 71 | Processando aplicativo* 72 | *de* 73 | Processando backup* 74 | *de* 75 | Oops, você acabou de negar a permissão para ler/gravar nos dispositivos de armazenamento 76 | Permissão concedida, agora você pode ler/gravar nos dispositivos de armazenamento 77 | Reiniciar 78 | Preferências 79 | Backup das preferências realizado com sucesso 80 | Backup das preferências restaurado com sucesso 81 | Preferências redefinidas com sucesso 82 | Fazer backup das preferências 83 | Restaurar backup das preferências 84 | Redefinir preferências 85 | Backup das preferências não encontrado 86 | Reinicialização automática falhou, por favor reinicie manualmente! 87 | Redefinindo preferências para evitar conflitos 88 | Restaurar 89 | Restaurando arquivo* 90 | Acesso Completo ao Cartão de Memória Externo só é necessário para realizar backups em cartões de memória externos, gostaria de ativar o acesso e então reiniciar? 91 | Backup 92 | Compartilhar 93 | Classificar 94 | Nome - Crescente 95 | Nome - Decrescente 96 | Tamanho - Crescente 97 | Tamanho - Decrescente 98 | Estado - Crescente 99 | Estado - Decrescente 100 | Informações do Backup 101 | Módulo atualizado 102 | Permissão de gravação no armazenamento externo é necessária para que a funcionalidade de backup dos APKs funcione 103 | 104 | Quantidade de backups antigos que serão mantidos 105 | Limite do Histórico de Backups 106 | Ignora permissões duplicadas declaradas pelos aplicativos 107 | Desativar Verificação de Permissões Duplicadas 108 | Permite a instalação de aplicativos sem a verificação de permissões 109 | Desativar Verificação de Permissões 110 | Sempre retorna a versão de SDK mais recente 111 | Desativar Verificação da SDK 112 | Desabilita a instalação de aplicativos em segundo plano 113 | Desativar Instalação em Segundo Plano 114 | Desabilita a instalação de aplicativos pelo shell 115 | Desativar Instalação pelo Shell 116 | Desabilita a desinstalação de aplicativos em segundo plano 117 | Desativar Desinstalação em Segundo Plano 118 | Permite instalar aplicativos não verificados 119 | Desativar Verificação de Aplicativos 120 | Certificados inválidos em arquivos JAR serão aceitos 121 | Desativar Verificação JAR 122 | Habilita os botões de limpar dados e cache sem esperar pelo cálculo do espaço utilizado 123 | Ativar Botões de Armazenamento do App 124 | Fecha automaticamente a janela de instalação de aplicativo após finalizar 125 | Fechar Instalação Automaticamente 126 | Vibra o aparelho ao finalizar a instalação ao utilizar as opções de instalação automática 127 | Vibrar ao Instalar Automaticamente 128 | Fecha automaticamente a janela de desinstalação de aplicativo ao finalizar 129 | Fechar Desinstalação Automaticamente 130 | Oculta automaticamente a janela de instalação 131 | Ocultar Instalação Automaticamente 132 | Abre o aplicativo automaticamene ao finalizar a instalação 133 | Abrir App Automaticamente 134 | Instala o aplicativo automaticamente sem interação do usuário 135 | Instalar Automaticamente 136 | Desinstala aplicativo automaticamente sem interação do usuário 137 | Desinstalar Automaticamente 138 | Cria um backup do APK após a instalação na pasta especificada pelo usuário 139 | Fazer Backup dos APKs 140 | Alterna para o tema escuro 141 | Tema Escuro 142 | Permite depuração em todos os aplicativos 143 | Depurar Aplicativos 144 | Habilita log adicional para o InstallerOpt 145 | Depuração 146 | Exclui o APK após a instalação 147 | Excluir APKs 148 | Tenta ocultar a presença do Lucky Patcher de outros aplicativos 149 | Esconder Lucky Patcher 150 | Permite instalar aplicativos com assinaturas inválidas 151 | Desativar Verificação de Assinaturas 152 | Permite desativar aplicativos de sistema, clique longo no botão desinstala o aplicativo 153 | Desativar Aplicativos do Sistema 154 | Modifica botão de desinstalação na tela de informações do aplicativo para permitir que aplicativos instalados pelo usuário possam ser desativados, clique longo no botão desinstala o aplicativo 155 | Desativar Aplicativos do Usuário 156 | Permite instalar aplicativos com assinaturas não verificadas 157 | Desativar Verificação de Assinaturas 158 | Permite instalar versões antigas de aplicativos já instalados 159 | Downgrade de Apps 160 | Força o idioma inglês para esse módulo independentemente do idioma local do sistema 161 | Forçar Inglês 162 | Oculta a mensagem de erro quando um aplicativo trava 163 | Desativar Mensagem FC 164 | Desmarque para ocultar o ícone do módulo no launcher 165 | Mostrar Ícone do Módulo 166 | Aplicativos serão instalados no armazenamento externo se ativado, ou no armazenamento interno se desativado 167 | Instalar no Armazenamento Externo 168 | Permite instalar aplicativos de fontes desconhecidas 169 | Instalar Aplicativos Desconhecidos 170 | Bloqueia instalação de apps desconhecidos mas pergunta o que fazer ao usuário em cada instalação 171 | Perguntar ao Instalar Aplicativos Desconhecidos 172 | Dados do aplicativo não são excluídos ao desinstalar o app 173 | Manter Dados do Aplicativo 174 | Clicar no ícone do aplicativo na tela de informações do app abre o aplicativo 175 | Abrir Aplicativo pelo Ícone 176 | Desmarque para desativar todas as funções do InstallerOpt 177 | Habilitar InstallerOpt 178 | Ativa notificações para as ações do InstallerOpt 179 | Notificações 180 | Abre o App Ops automaticamente após a instalação do aplicativo 181 | Abrir App Ops 182 | Clicar no nome do aplicativo na tela de informações do app mostra o nome do pacote 183 | Mostrar Nome do Pacote 184 | Clique longo no ícone do aplicativo na tela de informações do app abre a página do aplicativo na Play Store 185 | Abrir na Play Store 186 | Permite interagir com botões embaixo das notificações toasts 187 | Mostrar Botões 188 | Permite desinstalar aplicativos definidos como administradores do dispositivo 189 | Desinstalar Administradores do Dispositivo 190 | Permite desinstalar aplicativos de sistema com um clique longo 191 | Desinstalar Aplicativos de Sistema 192 | Mostra código de versão atual e nova do aplicativo antes de instalar 193 | Mostrar Código de Versão 194 | Mostra informações de versão na janela de instalação 195 | Versão na Janela de Instalação 196 | Mostra versão atual e nova do aplicativo antes de instalar 197 | Mostrar Versão 198 | Mostra informações de versão em uma notificação toast 199 | Versão em Notificação Toast 200 | Permite ler/gravar no cartão SD externo (requer reinício) 201 | Acesso Completo ao Cartão SD Externo 202 |  application(s) selected 203 |  backup(s) selected 204 | Install Failure 205 | Error code:  206 | Install Success 207 |  installed 208 | Filter… 209 | Date - Ascending 210 | Date - Descending 211 |  not installed 212 | Backup Date:  213 |  bytes) 214 | Size:  215 | Status:  216 | Version:  217 |  apps 218 | Not Available 219 | 220 | -------------------------------------------------------------------------------- /main/res/values-ru/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | О программе 4 | Дополнительно 5 | InstallerOpt 6 | Приложение удалено 7 | Параметры окна информации приложения 8 | Параметры установки приложений 9 | Параметры приложений 10 | Параметры удаления приложений 11 | Удаление резервной копии завершено 12 | Подготовка к удалению файлов резервной копии 13 | Удалить выбранные резервные копии 14 | \n\nДата рез.копии:\n 15 | \n\nMD5 контр.сумма:\n 16 | Имя файла:\n 17 | \n\nРазмер файла:\n 18 | Инфо о файле 19 | Создание рез.копии* 20 | *из* 21 | Подготовка к резервированию приложений 22 | \nСвободно в папке рез.копий: 23 | Рез.копия приложений 24 | \n\nПоследняя рез.копия:\n 25 | Расположение рез.копий:\n 26 | Папка рез.копий отсутствует, возможно удалена вне InstallerOpt??? 27 | Резервная копия восстановлена 28 | Подготовка к восстановлению файлов 29 | Восстановить выбранные рез.копии 30 | Рез.копии не выбраны, выберите и попробуйте снова 31 | \n\nВсего зарезервировано: 32 | \n\nЗанято в папке рез.копий: 33 | Проверка подписей 34 | Подтверждение проверки подписей 35 | Отключить проверку подписей для этой установки? 36 | Установленная версия: 37 | Код установленной версии: 38 | \nУстановленная версия: 39 | \nКод установленной версии: 40 | Удалить все 41 | Удалить 42 | Удаление файла* 43 | Тема на XDA: http://forum.xda-developers.com/xposed/modules/xposed-installeropt-0-4-t3377008\n\nGithub: https://github.com/afxefx/InstallerOpt 44 | Выкл 45 | Вкл 46 | Включите опцию рез.копирования APK и выберите папку рез.копий 47 | Добавить исключения? 48 | Включить и перезагрузить? 49 | Эта опция блокирует все фоновые установки и может конфликтовать с автоматическими установщиками вроде Titanium Backup, добавить исключение? 50 | Исключения не выбраны, выберите приложение и попробуйте снова 51 | Экспертные параметры - ПРИМЕНЯТЬ ОСТОРОЖНО! 52 | Размеры старой и новой папок не совпадают, удаление старой папки отменено 53 | В новой папке недостаточно свободного места, выберите другую 54 | Загрузка рез.копий... 55 | Загрузка приложений... 56 | Управление 57 | Управление рез.копиями 58 | Дополнительные параметры 59 | Новая папка отличается от старой, перенести старые рез.копии в новое расположение? 60 | Перенос завершен 61 | Перенос файла* 62 | *из* 63 | Подготовка к переносу файлов в новое расположение 64 | Перенести старые рез.копии? 65 | Новая версия: 66 | Код новой версии: 67 | В старой папке отсутствуют файлы 68 | Запись в выбранную папку невозможна, выберите другую 69 | Обработка приложения* 70 | *из* 71 | Обработка рез.копии* 72 | *из* 73 | Нет разрешения для чтения/записи на устройства хранения 74 | Разрешение получено, теперь возможны чтение/запись на устройства хранения 75 | Перезагрузка 76 | Перезагрузка не удалась, попробуйте вручную! 77 | Сброс настроек для избежанияи конфликтов 78 | Восстановить 79 | Восстановление файла* 80 | Полный доступ к SD карте нужен только для резервирования на внешние SD карты, разрешить и перезагрузить? 81 | Резервирование 82 | Сортировка 83 | Имя - По возрастанию 84 | Имя - По убыванию 85 | Размер - По возрастанию 86 | Размер - По убыванию 87 | Статус - По возрастанию 88 | Статус - По убыванию 89 | Статистика 90 | Модуль был обновлен 91 | Для рез.копирования APK нужное разрешение на запись на внешний носитель 92 | 93 | Сколько резервных копий приложения хранить 94 | Лимит версий 95 | Игнорировать дублирующиеся разрешения, объявленные приложениями 96 | Отключить проверку дублирующихся разрешений 97 | Устанавливать приложения без проверки разрешений 98 | Отключить проверку разрешений 99 | Всегда возвращать самую последнюю версию SDK 100 | Отключить проверку SDK 101 | Фоновая установка (например Titanum Backup) будет невозможна 102 | Отключить фоновую установку 103 | Установка через терминал будет невозможна 104 | Отключить установку через терминал 105 | Фоновое удаление (например Titanum Backup) будет невозможно 106 | Отключить фоновое удаление 107 | Будет разрешена установка непроверенных приложений 108 | Отключить проверку приложений 109 | Будут разрешены несовместимые сертификаты в JAR файлах 110 | Отключить проверку JAR 111 | Включить кнопки "Очистить данные" и "Очистить кэш" до подсчета размера приложения 112 | Включить кнопки сразу 113 | Автоматически закрывать окно установки приложения по завершению установки 114 | Авто-закрытие после установки 115 | Вибрировать по завершению установки при использовании параметров авто-установки 116 | Вибрация авто-установки 117 | Автоматически закрывать окно удаления приложения по завершению удаления 118 | Закрытие после удаления 119 | Автоматически скрывать окно установки 120 | Скрытие установки 121 | Автоматически запускать приложение по завершению установки 122 | Запуск после установки 123 | Автоматически устанавливать приложение без взаимодействия с пользователем 124 | Авто-установка 125 | Автоматически удалять приложение без взаимодействия с пользователем 126 | Авто-удаление 127 | После установки создавать резервную копию файлов APK в выбранной пользователем папке 128 | Рез.копия APK 129 | Переключиться на темную тему оформления 130 | Темная тема 131 | Включить отладку всех приложений 132 | Отладка приложений 133 | Включить дополнительное журналирование InstallerOpt 134 | Отладка 135 | После установки удалять APK файлы 136 | Удалять APK 137 | Пытаться скрыть присутствие Lucky Patcher от других приложений 138 | Lucky Patcher 139 | Разрешить установку приложений с некорректной подписью 140 | Отключить проверку подписи 141 | Разрешает выключить системное приложение, долгое нажатие на кнопку - удаляет его 142 | Обработка системных приложений 143 | Кнопка "Удалить" выключает приложение, долгое нажатие на кнопку - удаляет его 144 | Выключать пользовательские приложения 145 | Разрешить установку приложений с неподтвержденной подписью 146 | Отключить подтверждение подписи 147 | Разрешить установку старых версий приложения поверх более новых 148 | Понижать версию 149 | Включить английский интерфейс, не смотря на текущие установки системы 150 | Интерфейс на Английском 151 | Скрыть диалог FC (Force Close) если приложение закрывается с ошибкой 152 | Отключить диалог FC 153 | Снимите галку, чтобы скрыть значок приложения в лаунчере 154 | Значок в лаунчере 155 | Если включено - устанавливать приложения на внешний носитель, если выключено - на внутренний 156 | Установка на внешний носитель 157 | Разрешить установку из неизвестных источников 158 | Неизвестные источники 159 | Не удалять данные приложения при удалении самого приложения 160 | Сохранить данные 161 | В окне информации о приложении нажатие по значку запускает приложение 162 | Запуск по значку 163 | Запускать App Ops после установки приложения 164 | Запустить App Ops 165 | В окне информации о приложении нажатие по имени приложения отобразит имя пакета 166 | Отображать имя пакета 167 | В окне информации о приложении долгое нажатие по значку откроет страницу приложения в Play Маркете 168 | Открыть в Play Маркете 169 | Показать кнопки под всплывающими сообщениями 170 | Показать кнопки 171 | Разрешить удаление приложений-администраторов устройства 172 | Удалять администраторов 173 | Разрешить удаление системных приложений долгим нажатием 174 | Удалять системные 175 | Показывать текущий и новый код версии прилолжения перед установкой 176 | Код версии 177 | Отображать информацию о версиях внутри диалога установки 178 | Версии внутри диалога 179 | Показывать текущую и новую версию приложения перед установкой 180 | Версия приложения 181 | Отображать информацию о версиях во всплывающей подсказке 182 | Всплывающая подсказка 183 | Разрешить чтение/запись на внешнюю SD карту (требуется перезагрузка) 184 | Полный доступ к внешней SD карте 185 | Сохранить настройки 186 | Нет сохраненных настроек 187 | Настройки сохранены 188 | Настройки сброшены 189 | Настройки восстановлены 190 | Настройки 191 | Сбросить настройки 192 | Восстановить настройки 193 | Поделиться 194 | Разрешить уведомения для действий InstallerOpt 195 | Уведомления 196 | Блокирует установку из неизвестных источников, но выводит запрос при каждой установке 197 | Запрос для неизвестных 198 | Главный переключатель 199 | Выключите, чтобы запретить функции InstallerOpt 200 | Модуль InstallerOpt 201 |  приложений выбрано 202 |  рез.копий выбрано 203 | Ошибка установки 204 | Код ошибки:  205 | Успешная установка 206 |  установлено 207 | Фильтр… 208 | Дата - По возрастанию 209 | Дата - По убыванию 210 |  не установлено 211 | Дата рез.копии:  212 |  байт) 213 | Размер:  214 | Статус:  215 | Версия:  216 |  приложений 217 | Не доступно 218 | 219 | -------------------------------------------------------------------------------- /main/res/values-sk/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | O aplikácii 4 | InstallerOpt 5 | Aplikácia bola odinštalovaná 6 | Podpora na XDA: http://forum.xda-developers.com/xposed/modules/xposed-installeropt-0-4-t3377008\n\nGithub: https://github.com/afxefx/InstallerOpt 7 | Zakázať 8 | Povoliť 9 | Reštartovať 10 | Aktuálna verzia: 11 | Kód aktuálnej verzie: 12 | Nová verzia: 13 | Kód novej verzie: 14 | Nastavenia boli obnovené aby sa predišlo konfliktom 15 | Modul bol aktualizovaný 16 | Povolenie bolo udelené 17 | Povolenie bolo odopreté 18 | Reštartovanie zlyhalo, prosím, reštartujte ručne! 19 | 20 | 21 | Štatistiky zálohovania 22 | \nZálohovací adresár voľné: 23 | Zálohovací adresár umiestnenie:\n 24 | \n\nZálohovací adresár použité: 25 | \\n\\nCelkovo zálohované: 26 | \\n\\nPosledné zálohované:\\n 27 | Vymazať 28 | Prosím, povoľte možnosť zálohovať APK súbory a zvoľte zálohovací adresár pre zobrazenie štatistiky 29 | Veľkosť starého a nového adresára nie je rovnaká, vymazanie starého adresára bolo zrušené 30 | Nový zálohovací adresár nemá dostatok voľného miesta, prosím, zvoľte iný 31 | Nový zálohovací adresár je iný ako starý, chcete presunúť vaše staré zálohy na nové umiestnenie? 32 | Presun bol úspešne dokončený 33 | Presúvanie súborov* 34 | *z* 35 | Príprava presunu súborov na nové umiestnenie 36 | Pre fungovanie zálohovania APK súborov je potrebné povolenie pre zápis 37 | V starom adresári nie sú žiadne súbory 38 | Spravovať 39 | Do zvoleného adresára nie je možné zapisovať, prosím, vyberte iný 40 | Zálohovací adresár neexistoval a bol vytvorený, pravdepodobne bol vymazaný mimo InstallerOpt?! 41 | Limit verzií v zálohe 42 | Určuje počet starých verzií ponechaných v zálohe 43 | 44 | 45 | 46 | Predvoľby aplikácie 47 | Zakázanie dialógu zastavenia aplikácie 48 | Skryje dialóg zobrazovaný pri nečakanom zastavení aplikácie 49 | Deaktivovanie užívateľských aplikácií 50 | Upraví tlačidlo pre odinštalovanie v informáciách o aplikácii na deaktivovanie aplikácie, dlhé podržanie ju odinštaluje 51 | Povoliť tlačidlá pre úložisko aplikácií 52 | Povolí tlačidlá pre vymazanie dát pred výpočtom veľkostí 53 | Stav systémovej aplikácie 54 | Povolí deaktivovanie systémových aplikácií, dlhé podržanie ju odinštaluje 55 | 56 | 57 | Predvoľby informácií o aplikácii 58 | Spustenie aplikácie pomocou ikony 59 | Povolí spustenie aplikácie po kliknutí na ikonu aplikácie v informáciách o aplikácii 60 | Otvorenie v Obchode Play 61 | Povolí otvorenie v Obchode Play po dlhom podržaní na ikone aplikácie v informáciách o aplikácii 62 | Zobrazenie mena balíčku 63 | Povolí zobrazenie mena balíčka po kliknutí na meno aplikácie v informáciách o aplikácii 64 | 65 | 66 | Predvoľby inštalovania aplikácie 67 | Automatické skrytie inštalácie 68 | Automaticky skryje okno inštalácie 69 | Automatická inštalácia 70 | Autoamticky nainštaluje aplikáciu bez zásahu používateľa 71 | Automatické zavretie po nainštalovaní 72 | Automaticky zavrie okno po nainštalovaní 73 | Automatické spustenie po nainštalovaní 74 | Automaticky spustí aplikáciu po nainštalovaní 75 | Vibrovanie pri automatickom inštalovaní 76 | Telefón zavibruje po dokončení inštalácie s použitím funkcie automatická inštalácia 77 | Zálohovanie súborov APK 78 | Zálohuje APK súbory po nainštalovaní 79 | Mazanie súborov APK 80 | Vymaže APK súbory po nainštalovaní 81 | Zakázať overovanie aplikácie 82 | Povolí nainštalovanie neoverené aplikácie 83 | Zakázať kontrolovanie podpisov 84 | Povolí nainštalovanie aplikácií s nezhodnými podpismi 85 | Zobrazenie kódu verzie 86 | Zobrazí kód aktuálnej a novej verzie pri inštalovaní aplikácie 87 | Zobrazenie verzie 88 | Zobrazí aktuálnu a novú verziu pri inštalovaní aplikácie 89 | Informácie o verzii v dialógu 90 | Zobrazí informácie o verzií v inštalačnom dialógu 91 | Toast informácie o verzii 92 | Zobrazí informácie o verzii v toast upozornení 93 | Neznáme aplikácie 94 | Povolí nainštalovanie neznámych aplikácií 95 | Ponechať dáta aplikácie 96 | Dáta aplikácie nebudú vymazané pri odinštalovaní aplikácie 97 | 98 | 99 | Predvoľby odinštalovania aplikácie 100 | Automatické odinštalovanie 101 | Autoamticky odinštaluje aplikáciu bez zásahu používateľa 102 | Automatické zavretie po odinštalovaní 103 | Automaticky zavrie okno po odinštalovaní 104 | Odinštalovanie systémových aplikácií 105 | Povolí odinštalovanie systémových aplikácií cez dlhé podržanie 106 | Odinštalovanie sprcávcov zariadenia 107 | Povolí odinštalovanie aplikácie nastavenej ako správca zariadenia 108 | 109 | 110 | Rôzne predvoľby 111 | Downgrade aplikácií 112 | Povolí inštalovanie starších verzií aplikácií 113 | Úplný prístup k externej karte SD 114 | Umožňuje prístup pre čítanie/zápis na externú kartu SD (vyžaduje reštart) 115 | Povoliť a reštartovať? 116 | Úplný prístup k externej karte SD je potrebný iba pre zálohovanie APK súborov na externú kartu, chcete prístup povoliť a potom reštartovať? 117 | Zobrazenie tlačidiel 118 | Povolí interakciu tlačidiel pod toast upozornením 119 | 120 | 121 | Pokročilé 122 | Ikona aplikácie 123 | Odstráni ikonu aplikácie z launchera 124 | Tmavá téma 125 | Prepne na tmavú tému 126 | Ladenie 127 | Povolí dodatočné záznamy pre InstallerOpt 128 | Vynútiť angličtinu 129 | Vynúti anglický jazyk pre tento modul bez ohľadu na systémové nastavenia 130 | 131 | 132 | 133 | Kontrolovanie podpisov 134 | Potvrdzovanie kontroly podpisov 135 | Zakázať kontrolu podpisov pre túto inštaláciu? 136 | Zakázať overovanie podpisov 137 | Povolí nainštalovanie aplikácie s neoverenými podpismi 138 | Zakázať overovanie JAR 139 | Nezhodné certifikáty JAR súborov budú povolené 140 | Zakázať kontrolovanie zdvojených povolení 141 | Povolí nainštalovanie aplikácií so zdvojenými povoleniami 142 | Zakázať kontrolovanie povolení 143 | Povolí nainštalovanie aplikácií bez skontrolovania povolení 144 | Ladenie aplikácií 145 | Povolí ladenie pre všetky aplikácie 146 | Zakázať kontrolu SDK 147 | Vždy vráti najnovšiu verziu SDK 148 | Zakázať inštalovanie na pozadí 149 | Zakáže inštalovanie aplikácií na pozadí 150 | Zakázať odinštalovanie na pozadí 151 | Zakáže odinštalovanie aplikácií na pozadí 152 | Lucky Patcher 153 | Pokúsi sa skryť prítomnosť Lucky Patcher pred ostatnými aplikáciami 154 | Presunúť staré zálohy? 155 | Expertné predvoľby - POSTUPUJTE OPATRNE! 156 | Otvoriť App Ops 157 | Otvorí App Ops po nainštalovaní aplikácie 158 | Zakáže inštalovanie aplikácií pomocou Shell 159 | Zakázať inštalovanie pomocou Shell 160 | Pripravuje sa odstránenie súborov zo zálohovacieho adresára 161 | Vymazanie zálohy prebehlo úspešne 162 | Vymazať vybrané zálohy 163 | Spravovať zálohy 164 | Nie sú vybrané žiadne zálohy 165 | Obnoviť vybrané zálohy 166 | Pripravuje sa obnovenie súborov zo zálohovacieho adresára 167 | Obnovenie zálohy prebehlo úspešne 168 | Info o súbore 169 | Info o súbore 170 | Mazanie súboru* 171 | Obnovovanie súboru* 172 | Obnoviť 173 | \\n\\nDátum zálohy:\\n 174 | \\n\\nKontrolný súčet MD5:\\n 175 | Názov súboru:\\n 176 | \\n\\nVeľkosť súboru:\\n 177 | Pridať výnimky? 178 | Táto možnosť zablokuje všetky inštalácie na pozadí a môže brániť automatickému obnovovaniu napr. z Titanium Backup, chcete pridať výnimky? 179 | Nie sú pridané žiadne výnimky, prosím, vyberte aplikáciu a skúste znova 180 | Zoradiť 181 | Názov - A-Z 182 | Názov - Z-A 183 | Veľkosť - od najmenších 184 | Veľkosť - od najväščích 185 | Ak je povolené, aplikácie budú nainštalované na externé úložisko, na interné ak je zakázané 186 | Inštalovať ne externé úložisko 187 | Analýza aplikácie* 188 | *z* 189 | Analýza zálohy* 190 | *z* 191 | Stav - vzostupne 192 | Stav - zostupne 193 | \\nAktuálna verzia: 194 | \\nKód aktuálnej verzie: 195 | Načítavanie aplikácií… 196 | Načítavanie záloh… 197 | Zálohovanie súboru* 198 | *z* 199 | Zálohovať nainštalované aplikácie 200 | Zálohovať 201 | Pripravuje sa zálohovanie aplikácie do zálohovacieho adresára 202 | Zálohovať nastavenia 203 | Neboli nájdené žiadne uložené nastavenia 204 | Nastavenia boli úspešne uložené 205 | Nastavenia boli úspešne vymazané 206 | Nastavenia boli úspešne obnovené 207 | Nastavenia 208 | Vymazať nastavenia 209 | Obnoviť nastavenia 210 | Zdieľať 211 | Upozornenia 212 | Povoliť upozornenia pre akcie InstallerOpt 213 | Blokuje inštalovanie neznámych aplikácií, ale zobrazí výzvu na potlačenie pri každej inštalácii 214 | Výzva neznámych aplikácií 215 | Hlavný prepínač 216 | Vypnutím zakážete všetky funckie InstallerOpt 217 | InstallerOpt modul 218 | Vybraných aplikácií:   219 | Vybraných záloh:   220 | Inštalácia zlyhala 221 | Kód chyby:   222 | Inštalácia bola úspešná 223 | Nainštalovaných:   224 | Filter… 225 | Dátum - od najstarších 226 | Dátum - od najnovších 227 | Nenainštalovaných:   228 | Dátum zálohy:   229 |  bajtov) 230 | Veľkosť:   231 | Stav:   232 | Odinštalovanie bolo úspešné 233 | Aplikácia bola odinštalovaná 234 | Verzia:   235 |   aplikácií 236 | Nie je dostupné 237 | 238 | 239 | -------------------------------------------------------------------------------- /main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /main/res/values-zh-rCN/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 关于 4 | 高级 5 |  个应用 6 | InstallerOpt 7 | 应用已被卸载 8 | 应用信息设置 9 | 应用安装设置 10 | 已选择 个应用 11 | 应用设置 12 | 应用卸载设置 13 | 删除备份成功 14 | 准备从备份位置删除选择的备份 15 | 删除选择的备份 16 | \n\n文件备份日期:\n 17 | \n\nMD5校验和:\n 18 | 备份文件* 19 | 文件名:\n 20 | */* 21 | 准备备份应用到备份位置 22 | \n\n文件大小:\n 23 | 文件信息 24 | \n备份文件夹: 25 | 备份已安装的应用 26 | \n\n上次备份:\n 27 | 备份文件夹位置:\n 28 | 备份目录不存在,已经重新创建,您是否曾在本应用外将其删除??? 29 | 备份 30 | 备份恢复成功 31 | 准备从备份位置恢复选择的备份 32 | 恢复选择的备份 33 | 没有选择备份,请选择一个备份然后再试 34 | \n\n备份总计: 35 | \n\n使用的备份文件夹: 36 | 备份日期:  37 | 备份参数 38 | 已选择 个备份(s) 39 |  bytes) 40 | 检查签名 41 | 确认签名检查 42 | 对这个应用禁用签名检查? 43 | 当前版本: 44 | 当前版本号: 45 | \n当前版本: 46 | \n当前版本号: 47 | 删除所有 48 | 删除 49 | 删除文件* 50 | XDA支持页面:http://forum.xda-developers.com/xposed/modules/xposed-installeropt-0-4-t3377008\n\nGithub: https://github.com/afxefx/InstallerOpt 51 | 禁用 52 | 启用 53 | 请启用备份APK选项并选择备份文件夹以查看统计 54 | 添加例外? 55 | 启用并重新启动? 56 | 这个选项会屏蔽所有后台安装,可能干扰钛备份等自动恢复软件,您想添加例外吗? 57 | 没有选择例外,请选择一个应用后再试 58 | 专家设置 - 继续前注意! 59 | 新旧文件夹大小不匹配,删除被取消 60 | 新的备份文件夹没有足够的空间,请重新选择 61 | 安装失败 62 |  未安装 63 | 错误代码:  64 | 安装成功 65 |  已安装 66 | 正在加载应用… 67 | 正在加载备份... 68 | 管理 69 | 管理备份 70 | 主开关 71 | 其它参数 72 | 新旧备份文件夹不同,您想把旧文件夹中的内容转移到新文件夹中吗? 73 | 转移成功完成 74 | 转移文件* 75 | */* 76 | 准备转移文件到新的备份位置 77 | 移动旧备份? 78 | 新装版本: 79 | 新装版本号: 80 | 未找到已保存的设置 81 | 现在旧备份文件夹中没有文件 82 | 无法写入选择的文件夹,请选择另外的文件夹 83 | 84 | 不可用 85 | 描述应用程序* 86 | */* 87 | 描述备份* 88 | */* 89 | 糟糕,您拒绝了写入存储设备的权限 90 | 存储权限已获得,您可以读写 91 | 参数已成功备份 92 | 参数已成功重置 93 | 参数成功恢复 94 | 参数 95 | 重新启动 96 | 重新启动失败,请手动操作! 97 | 重置设置以避免冲突 98 | 重置参数 99 | 恢复 100 | 恢复文件* 101 | 恢复参数 102 | 外部SD卡的完全访问权限只是为备份使用,您希望启用它然后重新启动吗? 103 | 过滤… 104 | 分享 105 | 大小:  106 | 日期 - 旧到新 107 | 日期 - 新到旧 108 | 分类 109 | 名称 - 升序 110 | 名称 - 降序 111 | 大小 - 升序 112 | 大小 - 降序 113 | 状态 - 升序 114 | 状态 - 降序 115 | 备份状态 116 | 状态:  117 | 卸载成功 118 | 应用已卸载 119 | 模块已经更新 120 | 版本:  121 | 需要外部存储访问权限以确保备份功能正常工作 122 | 123 | 保留多少备份版本 124 | 备份版本限制 125 | 允许安装使用权限重复的应用 126 | 禁用重复权限检查 127 | 允许不经过权限检查就安装应用 128 | 禁用权限检查 129 | 永远报告为最新版本的SDK 130 | 禁用SDK检查 131 | 禁用后台安装应用 132 | 禁用后台安装 133 | 禁用通过终端Shell安装 134 | 禁用终端Shell安装 135 | 禁用后台卸载应用 136 | 禁用后台卸载 137 | 允许安装未经验证的应用 138 | 禁用应用验证 139 | 允许JAR文件证书不匹配 140 | 禁用JAR验证 141 | 启用将清除数据按钮转换为应用存储占用计算 142 | 启用应用存储按钮 143 | 安装完成后自动关闭窗口 144 | 安装后自动关闭 145 | 当使用自动安装命令时安装完成后震动 146 | 自动安装后震动 147 | 卸载完成后自动关闭窗口 148 | 卸载后自动关闭 149 | 自动隐藏安装窗口 150 | 自动隐藏安装 151 | 安装完成后自动启动应用 152 | 安装后自动启动 153 | 自动安装应用而无需用户交互 154 | 自动安装 155 | 自动卸载应用而无需用户交互 156 | 自动卸载 157 | 安装后在用户指定的文件夹中备份APK 158 | 备份APKs 159 | 切换到黑色主题 160 | 黑色主题 161 | 对所有应用启用调试 162 | 应用调试 163 | 启用InstallerOpt的额外日志输出 164 | 调试 165 | 在安装后删除APK 166 | 删除APKs 167 | 尝试对其他应用隐藏幸运破解器 168 | 幸运破解器 169 | 允许安装不同签名的应用 170 | 禁用签名检查 171 | 允许停用系统应用,长按为卸载 172 | 系统应用状态 173 | 将卸载按钮转换为停用,长按为卸载 174 | 停用用户应用 175 | 允许安装未经签名的应用 176 | 禁用签名验证 177 | 允许降级安装应用 178 | 降级应用 179 | 强制该模块英文而不考虑当前语言环境 180 | 强制英文 181 | 移除强行关闭确定按钮的超时对话框 182 | 禁用强行关闭超时对话框 183 | 从启动器中移除应用图标 184 | 应用图标 185 | 应用在开启时会安装在外部存储,关闭时会安装在内部存储 186 | 安装到外部存储 187 | 阻止未知应用安装,但在每次安装时提示覆盖 188 | 未知应用程序提示 189 | 允许安装未知应用 190 | 未知应用 191 | 在卸载后保留应用数据 192 | 保留应用数据 193 | 在查看应用信息时点击应用图标以打开应用 194 | 应用图标打开 195 | 取消选中将禁用所有InstallerOpt功能 196 | InstallerOpt模块 197 | 为InstallerOpt启用通知栏操作 198 | 通知栏 199 | 应用安装后打开App Ops 200 | 打开App Ops 201 | 在查看应用信息时长按应用名以显示包名 202 | 显示包名 203 | 在查看应用信息时长按应用图标以在Play商店中打开应用 204 | 在Play商店打开 205 | 允许点击消息框下的按钮 206 | 显示按钮 207 | 启用卸载被设置为设备管理器的应用 208 | 卸载设备管理器 209 | 启用长按卸载系统应用 210 | 卸载系统应用 211 | 在安装前显示新旧版本号 212 | 显示版本号 213 | 在安装对话框内显示版本信息 214 | 内部版本信息 215 | 在安装前显示现有的和新的应用版本 216 | 显示版本 217 | 在消息框中显示版本信息 218 | 版本信息消息框 219 | 允许读写外部SD卡(需要重新启动) 220 | 外部SD卡完整访问权限 221 | 222 | 223 | -------------------------------------------------------------------------------- /main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | #FFFFFF 7 | #000000 8 | 9 | -------------------------------------------------------------------------------- /main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | About 4 | Advanced 5 |  apps 6 | InstallerOpt 7 | App was uninstalled 8 | Application Info Preferences 9 | Application Install Preferences 10 |  application(s) selected 11 | Application Preferences 12 | Application Uninstall Preferences 13 | Backup Deletion Completed Successfully 14 | Preparing to delete files from backup location 15 | Delete Selected Backups 16 | \n\nFile backup date:\n 17 | \n\nMD5 checksum:\n 18 | Backing up file* 19 | File Name:\n 20 | *of* 21 | Preparing to backup application(s) to backup location 22 | \n\nFile Size:\n 23 | File Info 24 | \nBackup folder free: 25 | Backup Installed Apps 26 | \n\nLast backed up:\n 27 | Backup folder location:\n 28 | Backup directory did not exist and was created, possibly deleted outside of InstallerOpt? 29 | Backup 30 | Backup Restore Completed Successfully 31 | Preparing to restore files from backup location 32 | Restore Selected Backups 33 | No backups selected, please select a backup and try again 34 | \n\nTotal backed up: 35 | \n\nBackup folder used: 36 | Backup Date:  37 | Backup preferences 38 |  backup(s) selected 39 |  bytes) 40 | Checking signatures 41 | Confirming signatures check 42 | Disable signatures check for this installation? 43 | Current version: 44 | Current version code: 45 | \nCurrent version code: 46 | \nCurrent version: 47 | Delete All 48 | Delete 49 | Deleting file* 50 | XDA support thread: http://forum.xda-developers.com/xposed/modules/xposed-installeropt-0-4-t3377008\n\nGithub: https://github.com/afxefx/InstallerOpt 51 | Disable 52 | Enable 53 | Please enable backup APK option and choose your backup folder to see stats 54 | Add Exceptions? 55 | Enable and Reboot? 56 | This option will block all background installs and may interfere with automated restorations like Titanium Backup, would you like to add exceptions? 57 | No exceptions selected, please select an application and try again 58 | Expert Preferences - PROCEED WITH CAUTION! 59 | Old and new folders sizes do not match, deletion of old folder cancelled 60 | New backup folder does not have enough free space, please choose another 61 | Install Failure 62 |  not installed 63 | Error code:  64 | Install Success 65 |  installed 66 | Loading applications… 67 | Loading backups… 68 | Manage 69 | Manage Backups 70 | Master Switch 71 | Misc Preferences 72 | New backup folder differs from the old one, would you like to move your old backups to the new location? 73 | Move Completed Successfully 74 | Moving file* 75 | *of* 76 | Preparing to move files to new backup location 77 | Move old backups? 78 | New version: 79 | New version code: 80 | No saved preferences found 81 | No files present in old backup folder 82 | Unable to write to chosen folder, please choose another 83 | 84 | Not Available 85 | Parsing application* 86 | *of* 87 | Parsing backup* 88 | *of* 89 | Oops, you just denied the permission to read/write to storage devices 90 | Permission granted now you can read/write to storage devices 91 | Preferences successfully backed up 92 | Preferences successfully reset 93 | Preferences successfully restored 94 | Preferences 95 | Reboot 96 | Reboot operation failed, please do so manually! 97 | Resetting preferences to avoid conflicts 98 | Reset preferences 99 | Restore 100 | Restoring file* 101 | Restore preferences 102 | External SD Card Full Access is only needed for backing up to external SD cards, would you like it enabled and then reboot? 103 | Filter… 104 | Share 105 | Size:  106 | Date - Oldest to Newest 107 | Date - Newest to Oldest 108 | Sort 109 | Name - A-Z 110 | Name - Z-A 111 | Size - Smallest to Largest 112 | Size - Largest to Smallest 113 | Status - Ascending 114 | Status - Descending 115 | Backup Stats 116 | Status:  117 | Uninstall Success 118 | App was uninstalled 119 | Module has been updated 120 | Version:  121 | External write permission is needed for backup APK functionality to work 122 | 123 | How many old backup versions to keep 124 | Backup Version Limit 125 | Ignore duplicate permissions declared by applications 126 | Disable Duplicate Permissions Check 127 | Allow installing applications without doing permission checks 128 | Disable Permission Checks 129 | Always returns the latest version of the SDK 130 | Disable SDK Check 131 | Disables installing applications in the background 132 | Disable Background Install 133 | Disables installing applications through shell 134 | Disable Shell Install 135 | Disables uninstalling applications in the background 136 | Disable Background Uninstall 137 | Allow installing unverified applications 138 | Disable Application Verification 139 | Mismatched certificates on JAR files will be allowed 140 | Disable JAR Verification 141 | Enables clear storage and data buttons prior to size calculation 142 | Enable App Storage Buttons 143 | Automatically closes application installation window upon completion 144 | Auto Install Close 145 | Vibrates phone on install completion when using auto install options 146 | Auto Install Vibrate 147 | Automatically closes uninstallation window when complete 148 | Auto Uninstall Close 149 | Automatically hides installation window 150 | Auto Hide Install 151 | Automatically launches application upon installation completion 152 | Auto Install Launch 153 | Automatically installs application without user interaction 154 | Auto Install 155 | Automatically uninstalls application without user interaction 156 | Auto Uninstall 157 | Backs up APK files after install to user selected folder 158 | Backup APKs 159 | Switches to dark theme 160 | Dark Theme 161 | Enables debugging on all applications 162 | Debug Applications 163 | Enables additional logging for InstallerOpt 164 | Debug 165 | Delete APK files after install 166 | Delete APKs 167 | Attempts to hide Lucky Patcher presence from other applications 168 | Lucky Patcher 169 | Allow installing applications with mismatched signatures 170 | Disable Signature Checks 171 | Enables system apps to be disabled, long click performs uninstall 172 | System Application State 173 | Modifies uninstall button in application info to disable(turn off) application, long click performs uninstall 174 | Disable User Applications 175 | Allow installing applications with unverified signatures 176 | Disable Signature Verification 177 | Allow installing older versions of applications 178 | Downgrade Apps 179 | Force english for this module regardless of current locale 180 | Force English 181 | Removes timeout applied to OK button of Force Close dialog 182 | Disable FC Dialog Timeout 183 | Uncheck to hide application icon from launcher 184 | Application Icon 185 | Applications install to external storage if enabled, internal storage if disabled 186 | Install to External Storage 187 | Blocks unknown app installs, but prompts to override on each install 188 | Unknown Apps Prompt 189 | Allow unknown applications to be installed 190 | Unknown Apps 191 | App data is not deleted when application is uninstalled 192 | Keep App Data 193 | Click application icon when viewing application info to launch application 194 | Icon Application Launch 195 | Uncheck to disable all InstallerOpt functions 196 | InstallerOpt Module 197 | Enables notifications for InstallerOpt actions 198 | Notifications 199 | Opens App Ops after installation of application 200 | Open App Ops 201 | Click application name when viewing application info to see package name 202 | Package Name Display 203 | Long click application icon when viewing application info to open in Playstore 204 | Open in Playstore 205 | Allow buttons under toasts to be interacted with 206 | Show buttons 207 | Enables the ability to uninstall applications set as device administrators 208 | Uninstall Device Admins 209 | Enables the ability to uninstall system applications via long click 210 | Uninstall System Applications 211 | Shows current and new version code of application prior to installing 212 | Version Code Display 213 | Shows version information inline with install dialog 214 | Version Info Inline 215 | Shows current and new version of application prior to installing 216 | Version Display 217 | Shows version information in a toast 218 | Version Info Toast 219 | Allows read/write to external SD Card(requires reboot) 220 | External SD Card Full Access 221 | net.fypm.InstallerOpt.MultiprocessPreferences.PREFFERENCE_AUTHORITY 222 | -------------------------------------------------------------------------------- /main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /main/res/xml/prefs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 17 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 55 | 56 | 57 | 63 | 69 | 75 | 81 | 87 | 93 | 99 | 105 | 111 | 117 | 123 | 129 | 135 | 141 | 147 | 153 | 159 | 160 | 161 | 167 | 173 | 179 | 185 | 191 | 197 | 198 | 199 | 205 | 211 | 217 | 223 | 229 | 235 | 241 | 247 | 254 | 260 | 266 | 267 | 268 | 274 | 275 | 276 | 282 | 288 | 294 | 300 | 306 | 307 | 308 | --------------------------------------------------------------------------------