getDisableAppPackageNames();
81 |
82 | void uninstallApp(AppInfo appInfo, int position);
83 |
84 | void updateAppName(String packageName, String appName);
85 |
86 | void updateAppIcon(String packageName, Bitmap appIcon);
87 |
88 | void updateHomeApps();
89 |
90 | void cancelTask();
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sscience/stopapp/service/MyAccessibilityService.java:
--------------------------------------------------------------------------------
1 | package com.sscience.stopapp.service;
2 |
3 | import android.accessibilityservice.AccessibilityService;
4 | import android.content.Intent;
5 | import android.os.CountDownTimer;
6 | import android.text.TextUtils;
7 | import android.view.KeyEvent;
8 | import android.view.accessibility.AccessibilityEvent;
9 | import android.widget.Toast;
10 |
11 | import com.science.myloggerlibrary.MyLogger;
12 | import com.sscience.stopapp.R;
13 | import com.sscience.stopapp.activity.SettingActivity;
14 | import com.sscience.stopapp.database.AppInfoDBController;
15 | import com.sscience.stopapp.database.AppInfoDBOpenHelper;
16 | import com.sscience.stopapp.model.AppsRepository;
17 | import com.sscience.stopapp.model.GetRootCallback;
18 | import com.sscience.stopapp.presenter.DisableAppsPresenter;
19 | import com.sscience.stopapp.util.CommonUtil;
20 | import com.sscience.stopapp.util.SharedPreferenceUtil;
21 |
22 | /**
23 | * @author SScience
24 | * @description
25 | * @email chentushen.science@gmail.com
26 | * @data 2017/4/2
27 | */
28 | public class MyAccessibilityService extends AccessibilityService {
29 |
30 | private AppInfoDBController mDBController;
31 | private AppsRepository mAppsRepository;
32 | private CountDownTimer mCountDownTimer;
33 | private String foregroundPackageName;
34 | private boolean isActionBack;
35 |
36 | @Override
37 | public void onAccessibilityEvent(AccessibilityEvent event) {
38 | if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
39 | String packageName = (String) SharedPreferenceUtil.get(this, DisableAppsPresenter.SP_LAUNCH_APP, "");
40 | int spAutoDisable = (int) SharedPreferenceUtil.get(this, SettingActivity.SP_AUTO_DISABLE_APPS, -1);
41 | if (spAutoDisable != -1 && spAutoDisable == 666) {
42 | actionBackDisableApp(event, packageName);
43 | }
44 | foregroundPackageName = event.getPackageName().toString();
45 | if (spAutoDisable != -1 && spAutoDisable != 666) {
46 | actionHomeDisableApp(spAutoDisable, foregroundPackageName, packageName);
47 | }
48 | }
49 | }
50 |
51 | @Override
52 | public boolean onKeyEvent(KeyEvent event) {
53 | int keyCode = event.getKeyCode();
54 | switch (keyCode) {
55 | case KeyEvent.KEYCODE_BACK:
56 | isActionBack = true;
57 | break;
58 |
59 | default:
60 | isActionBack = false;
61 | break;
62 | }
63 | return super.onKeyEvent(event);
64 | }
65 |
66 | /**
67 | * 按返回键推出app自动冻结(目前只支持物理返回按键)
68 | */
69 | private void actionBackDisableApp(AccessibilityEvent event, final String packageName) {
70 | if (!TextUtils.equals(foregroundPackageName, packageName)) {
71 | // 如果上一个前台应用不是启动的停用app,表明早已退出启动的停用app
72 | return;
73 | }
74 | // 获取当前的前台应用,如果当前的前台应用不是启动的停用app,且是按了返回键,则是按返回键退出app
75 | foregroundPackageName = event.getPackageName().toString();
76 | if (!TextUtils.equals(foregroundPackageName, packageName) && isActionBack) {
77 | isActionBack = false;
78 | mAppsRepository.getRoot(AppsRepository.COMMAND_DISABLE + packageName, new GetRootCallback() {
79 | @Override
80 | public void onRoot(boolean isRoot) {
81 | if (isRoot) {
82 | MyLogger.e("已退出App自动冻结的App:" + packageName);
83 | updateDisableApp(packageName);
84 | } else {
85 | Toast.makeText(MyAccessibilityService.this, getString(R.string.if_want_to_use_please_grant_app_root), Toast.LENGTH_SHORT).show();
86 | }
87 | }
88 | });
89 | mAppsRepository.cancelTask();
90 | }
91 | }
92 |
93 | /**
94 | * 回到桌面自动冻结(可一定时间后冻结)
95 | */
96 | private void actionHomeDisableApp(int spAutoDisable, String foregroundPackageName, final String packageName) {
97 | if (TextUtils.equals(foregroundPackageName, packageName)) {
98 | if (mCountDownTimer != null) {
99 | mCountDownTimer.cancel();
100 | mCountDownTimer = null;
101 | }
102 | }
103 | if (TextUtils.isEmpty(packageName) || !TextUtils.equals(foregroundPackageName, CommonUtil.getLauncherPackageName(this))) {
104 | return;
105 | }
106 | if (mCountDownTimer == null) {
107 | mCountDownTimer = new CountDownTimer(spAutoDisable * 1000, 1000) {
108 | @Override
109 | public void onTick(long millisUntilFinished) {
110 | }
111 |
112 | @Override
113 | public void onFinish() {
114 | mAppsRepository.getRoot(AppsRepository.COMMAND_DISABLE + packageName, new GetRootCallback() {
115 | @Override
116 | public void onRoot(boolean isRoot) {
117 | if (isRoot) {
118 | MyLogger.e("回到桌面已自动冻结的App:" + packageName);
119 | updateDisableApp(packageName);
120 | } else {
121 | Toast.makeText(MyAccessibilityService.this, getString(R.string.if_want_to_use_please_grant_app_root), Toast.LENGTH_SHORT).show();
122 | }
123 | }
124 | });
125 | mAppsRepository.cancelTask();
126 | }
127 | };
128 | mCountDownTimer.start();
129 | }
130 | }
131 |
132 | private void updateDisableApp(String packageName) {
133 | // 切换到主界面时,更新app列表
134 | SharedPreferenceUtil.put(MyAccessibilityService.this, RootActionIntentService.APP_UPDATE_HOME_APPS, true);
135 | // 避免重复更新
136 | SharedPreferenceUtil.put(MyAccessibilityService.this, DisableAppsPresenter.SP_LAUNCH_APP, "");
137 | mDBController.updateDisableApp(packageName, 0, AppInfoDBOpenHelper.TABLE_NAME_APP_INFO);
138 | }
139 |
140 | @Override
141 | protected void onServiceConnected() {
142 | MyLogger.e("无障碍服务已开启");
143 | mDBController = new AppInfoDBController(this);
144 | mAppsRepository = new AppsRepository(this);
145 | }
146 |
147 | @Override
148 | public boolean onUnbind(Intent intent) {
149 | MyLogger.e("无障碍服务已关闭");
150 | if (mCountDownTimer != null) {
151 | mCountDownTimer.cancel();
152 | mCountDownTimer = null;
153 | }
154 | mDBController = null;
155 | mAppsRepository = null;
156 | return super.onUnbind(intent);
157 | }
158 |
159 | @Override
160 | public void onInterrupt() {
161 |
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sscience/stopapp/service/RootActionIntentService.java:
--------------------------------------------------------------------------------
1 | package com.sscience.stopapp.service;
2 |
3 | import android.app.IntentService;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.os.Handler;
7 | import android.widget.Toast;
8 |
9 | import com.science.myloggerlibrary.MyLogger;
10 | import com.sscience.stopapp.R;
11 | import com.sscience.stopapp.activity.SettingActivity;
12 | import com.sscience.stopapp.activity.ShortcutActivity;
13 | import com.sscience.stopapp.database.AppInfoDBController;
14 | import com.sscience.stopapp.database.AppInfoDBOpenHelper;
15 | import com.sscience.stopapp.model.AppsRepository;
16 | import com.sscience.stopapp.model.GetRootCallback;
17 | import com.sscience.stopapp.presenter.DisableAppsPresenter;
18 | import com.sscience.stopapp.util.CommonUtil;
19 | import com.sscience.stopapp.util.SharedPreferenceUtil;
20 | import com.sscience.stopapp.util.ShortcutsManager;
21 |
22 | /**
23 | * @author SScience
24 | * @description
25 | * @email chentushen.science@gmail.com
26 | * @data 2017/2/8
27 | */
28 |
29 | public class RootActionIntentService extends IntentService {
30 |
31 | private Handler mHandler;
32 | public static final String APP_UPDATE_HOME_APPS = "app_update_home_apps";
33 |
34 | /**
35 | * Creates an IntentService. Invoked by your subclass's constructor.
36 | *
37 | * Used to name the worker thread, important only for debugging.
38 | */
39 | public RootActionIntentService() {
40 | super("RootActionIntentService");
41 | mHandler = new Handler();
42 | }
43 |
44 | @Override
45 | protected void onHandleIntent(Intent intent) {
46 | String packageName = intent.getStringExtra(ShortcutActivity.EXTRA_PACKAGE_NAME);
47 | MyLogger.e("-----------" + packageName);
48 | launchAppIntent(packageName);
49 | stopSelf();
50 | }
51 |
52 | private void launchAppIntent(String packageName) {
53 | if (!CommonUtil.isAppInstalled(RootActionIntentService.this, packageName)) {
54 | ShortcutsManager manager = new ShortcutsManager(RootActionIntentService.this);
55 | manager.removeShortcut(packageName, getString(R.string.app_had_uninstall));
56 | } else {
57 | try {
58 | // 存储启动的app,用于自动冻结
59 | SharedPreferenceUtil.put(this, DisableAppsPresenter.SP_LAUNCH_APP, packageName);
60 | Intent resolveIntent = getPackageManager().getLaunchIntentForPackage(packageName);
61 | startActivity(resolveIntent);
62 | } catch (NullPointerException e) {
63 | enableApp(packageName);
64 | }
65 | int spAutoDisable = (int) SharedPreferenceUtil.get(this, SettingActivity.SP_AUTO_DISABLE_APPS, -1);
66 | if (spAutoDisable != -1) {
67 | AppsRepository appsRepository = new AppsRepository(this);
68 | appsRepository.openAccessibilityServices(null);
69 | }
70 | }
71 | }
72 |
73 | private void enableApp(final String packageName) {
74 | new AppsRepository(RootActionIntentService.this).getRoot(AppsRepository.COMMAND_ENABLE + packageName, new GetRootCallback() {
75 |
76 | @Override
77 | public void onRoot(boolean isRoot) {
78 | if (isRoot) {
79 | // 已停用的app启动,则需更新主页app为启用
80 | SharedPreferenceUtil.put(RootActionIntentService.this, APP_UPDATE_HOME_APPS, true);
81 | AppInfoDBController appInfoDBController = new AppInfoDBController(RootActionIntentService.this);
82 | appInfoDBController.updateDisableApp(packageName, 1, AppInfoDBOpenHelper.TABLE_NAME_APP_INFO);
83 | launchAppIntent(packageName);
84 | } else {
85 | mHandler.post(new DisplayToast(RootActionIntentService.this
86 | , getString(R.string.if_want_to_use_please_grant_app_root)));
87 | }
88 | }
89 | });
90 | }
91 |
92 | public class DisplayToast implements Runnable {
93 | private final Context mContext;
94 | String mText;
95 |
96 | public DisplayToast(Context mContext, String text) {
97 | this.mContext = mContext;
98 | mText = text;
99 | }
100 |
101 | public void run() {
102 | Toast.makeText(mContext, mText, Toast.LENGTH_SHORT).show();
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sscience/stopapp/util/BackgroundWorker.java:
--------------------------------------------------------------------------------
1 | package com.sscience.stopapp.util;
2 |
3 | import java.util.concurrent.ExecutorService;
4 | import java.util.concurrent.Executors;
5 | import java.util.concurrent.Future;
6 |
7 | /**
8 | * @author SScience
9 | * @description 线程池
10 | * @email chentushen.science@gmail.com
11 | * @data 2017/1/15
12 | */
13 |
14 | public class BackgroundWorker {
15 | private ExecutorService mThreadPool;
16 | private static BackgroundWorker mWorker;
17 |
18 | private BackgroundWorker() {
19 | mThreadPool = Executors.newCachedThreadPool();
20 | }
21 |
22 | public static BackgroundWorker getInstance() {
23 | if (mWorker == null) {
24 | synchronized (BackgroundWorker.class) {
25 | if (mWorker == null) {
26 | mWorker = new BackgroundWorker();
27 | }
28 | }
29 | }
30 | return mWorker;
31 | }
32 |
33 | public Future submitTask(Runnable task) {
34 | return mThreadPool.submit(task);
35 | }
36 |
37 | public void executeTask(Runnable task) {
38 | mThreadPool.execute(task);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sscience/stopapp/util/DiffCallBack.java:
--------------------------------------------------------------------------------
1 | package com.sscience.stopapp.util;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v7.util.DiffUtil;
6 |
7 | import com.sscience.stopapp.bean.AppInfo;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * @author SScience
13 | * @description
14 | * @email chentushen.science@gmail.com
15 | * @data 2017/1/15
16 | */
17 |
18 | public class DiffCallBack extends DiffUtil.Callback {
19 |
20 | public static final String BUNDLE_PAYLOAD = "bundle_payload";
21 | private List mOldData, mNewData;
22 |
23 | public DiffCallBack(List oldData, List newData) {
24 | mOldData = oldData;
25 | mNewData = newData;
26 | }
27 |
28 | @Override
29 | public int getOldListSize() {
30 | return mOldData != null ? mOldData.size() : 0;
31 | }
32 |
33 | @Override
34 | public int getNewListSize() {
35 | return mNewData != null ? mNewData.size() : 0;
36 | }
37 |
38 | @Override
39 | public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
40 | return mOldData.get(oldItemPosition).getAppPackageName().equals(mNewData.get(newItemPosition).getAppPackageName());
41 | }
42 |
43 | @Override
44 | public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
45 | if (mOldData.get(oldItemPosition).isEnable() != mNewData.get(newItemPosition).isEnable()) {
46 | return false;
47 | }
48 | return true;
49 | }
50 |
51 | @Nullable
52 | @Override
53 | public Object getChangePayload(int oldItemPosition, int newItemPosition) {
54 | AppInfo oldBean = mOldData.get(oldItemPosition);
55 | AppInfo newBean = mNewData.get(newItemPosition);
56 | Bundle payLoad = new Bundle();
57 | if (oldBean.isEnable() != newBean.isEnable()) {
58 | payLoad.putInt(BUNDLE_PAYLOAD, newBean.isEnable());
59 | }
60 | if (payLoad == null) {
61 | return null;
62 | }
63 | return payLoad;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sscience/stopapp/util/ImageUtil.java:
--------------------------------------------------------------------------------
1 | package com.sscience.stopapp.util;
2 |
3 | import android.content.Context;
4 | import android.database.Cursor;
5 | import android.graphics.Bitmap;
6 | import android.graphics.BitmapFactory;
7 | import android.graphics.Canvas;
8 | import android.graphics.Matrix;
9 | import android.graphics.Paint;
10 | import android.media.ExifInterface;
11 | import android.net.Uri;
12 | import android.provider.MediaStore;
13 |
14 | import java.io.FileInputStream;
15 | import java.io.FileNotFoundException;
16 | import java.io.IOException;
17 | import java.io.InputStream;
18 |
19 | /**
20 | * @author SScience
21 | * @description
22 | * @email chentushen.science@gmail.com
23 | * @data 2017/4/12
24 | */
25 |
26 | public class ImageUtil {
27 |
28 | public static Bitmap getScaledBitmap(Context context, Uri imageUri, float maxWidth, float maxHeight) {
29 | String filePath = getRealPathFromURI(context, imageUri);
30 | Bitmap scaledBitmap = null;
31 |
32 | BitmapFactory.Options options = new BitmapFactory.Options();
33 |
34 | //by setting this field as true, the actual bitmap pixels are not loaded in the memory. Just the bounds are loaded. If
35 | //you try the use the bitmap here, you will get null.
36 | options.inJustDecodeBounds = true;
37 | Bitmap bmp = BitmapFactory.decodeFile(filePath, options);
38 | if (bmp == null) {
39 | InputStream inputStream = null;
40 | try {
41 | inputStream = new FileInputStream(filePath);
42 | BitmapFactory.decodeStream(inputStream, null, options);
43 | inputStream.close();
44 | } catch (FileNotFoundException exception) {
45 | exception.printStackTrace();
46 | } catch (IOException exception) {
47 | exception.printStackTrace();
48 | }
49 | }
50 |
51 | int actualHeight = options.outHeight;
52 | int actualWidth = options.outWidth;
53 |
54 | if (actualHeight == -1 || actualWidth == -1){
55 | try {
56 | ExifInterface exifInterface = new ExifInterface(filePath);
57 | actualHeight = exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, ExifInterface.ORIENTATION_NORMAL);//获取图片的高度
58 | actualWidth = exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, ExifInterface.ORIENTATION_NORMAL);//获取图片的宽度
59 | } catch (IOException e) {
60 | e.printStackTrace();
61 | }
62 | }
63 |
64 | if (actualWidth < 0 || actualHeight < 0) {
65 | Bitmap bitmap2 = BitmapFactory.decodeFile(filePath);
66 | if (bitmap2 != null){
67 | actualWidth = bitmap2.getWidth();
68 | actualHeight = bitmap2.getHeight();
69 | }else{
70 | return null;
71 | }
72 | }
73 |
74 | float imgRatio = (float) actualWidth / actualHeight;
75 | float maxRatio = maxWidth / maxHeight;
76 |
77 | //width and height values are set maintaining the aspect ratio of the image
78 | if (actualHeight > maxHeight || actualWidth > maxWidth) {
79 | if (imgRatio < maxRatio) {
80 | imgRatio = maxHeight / actualHeight;
81 | actualWidth = (int) (imgRatio * actualWidth);
82 | actualHeight = (int) maxHeight;
83 | } else if (imgRatio > maxRatio) {
84 | imgRatio = maxWidth / actualWidth;
85 | actualHeight = (int) (imgRatio * actualHeight);
86 | actualWidth = (int) maxWidth;
87 | } else {
88 | actualHeight = (int) maxHeight;
89 | actualWidth = (int) maxWidth;
90 | }
91 | }
92 |
93 | //setting inSampleSize value allows to load a scaled down version of the original image
94 | options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);
95 |
96 | //inJustDecodeBounds set to false to load the actual bitmap
97 | options.inJustDecodeBounds = false;
98 |
99 | //this options allow android to claim the bitmap memory if it runs low on memory
100 | options.inPurgeable = true;
101 | options.inInputShareable = true;
102 | options.inTempStorage = new byte[16 * 1024];
103 |
104 | try {
105 | //load the bitmap getTempFile its path
106 | bmp = BitmapFactory.decodeFile(filePath, options);
107 | if (bmp == null) {
108 | InputStream inputStream = null;
109 | try {
110 | inputStream = new FileInputStream(filePath);
111 | BitmapFactory.decodeStream(inputStream, null, options);
112 | inputStream.close();
113 | } catch (FileNotFoundException exception) {
114 | exception.printStackTrace();
115 | } catch (IOException exception) {
116 | exception.printStackTrace();
117 | }
118 | }
119 | } catch (OutOfMemoryError exception) {
120 | exception.printStackTrace();
121 | }
122 | try {
123 | scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
124 | } catch (OutOfMemoryError exception) {
125 | exception.printStackTrace();
126 | }
127 |
128 | float ratioX = actualWidth / (float) options.outWidth;
129 | float ratioY = actualHeight / (float) options.outHeight;
130 |
131 | Matrix scaleMatrix = new Matrix();
132 | scaleMatrix.setScale(ratioX, ratioY, 0, 0);
133 |
134 | Canvas canvas = new Canvas(scaledBitmap);
135 | canvas.setMatrix(scaleMatrix);
136 | canvas.drawBitmap(bmp, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG));
137 |
138 | //check the rotation of the image and display it properly
139 | ExifInterface exif;
140 | try {
141 | exif = new ExifInterface(filePath);
142 | int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
143 | Matrix matrix = new Matrix();
144 | if (orientation == 6) {
145 | matrix.postRotate(90);
146 | } else if (orientation == 3) {
147 | matrix.postRotate(180);
148 | } else if (orientation == 8) {
149 | matrix.postRotate(270);
150 | }
151 | scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
152 | scaledBitmap.getWidth(), scaledBitmap.getHeight(),
153 | matrix, true);
154 | } catch (IOException e) {
155 | e.printStackTrace();
156 | }
157 |
158 | return scaledBitmap;
159 | }
160 |
161 | /**
162 | * 计算inSampleSize
163 | */
164 | private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
165 | final int height = options.outHeight;
166 | final int width = options.outWidth;
167 | int inSampleSize = 1;
168 |
169 | if (height > reqHeight || width > reqWidth) {
170 | final int heightRatio = Math.round((float) height / (float) reqHeight);
171 | final int widthRatio = Math.round((float) width / (float) reqWidth);
172 | inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
173 | }
174 |
175 | final float totalPixels = width * height;
176 | final float totalReqPixelsCap = reqWidth * reqHeight * 2;
177 |
178 | while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
179 | inSampleSize++;
180 | }
181 |
182 | return inSampleSize;
183 | }
184 |
185 | //file uri to real location in filesystem
186 | public static String getRealPathFromURI(Context context, Uri uri) {
187 | Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
188 | if (cursor == null) {
189 | // Uri.fromFile(File file)生成的file://uri
190 | return uri.getPath();
191 | } else {
192 | // content://uri
193 | cursor.moveToFirst();
194 | int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
195 | return cursor.getString(idx);
196 | }
197 | }
198 | }
199 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sscience/stopapp/util/SharedPreferenceUtil.java:
--------------------------------------------------------------------------------
1 | package com.sscience.stopapp.util;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.content.SharedPreferences.Editor;
6 | import android.support.v4.content.SharedPreferencesCompat;
7 |
8 | import java.util.Map;
9 | import java.util.Set;
10 |
11 | /**
12 | * @author SScience
13 | * @description
14 | * @email chentushen.science@gmail.com
15 | * @data 2016/11/27
16 | */
17 |
18 | public class SharedPreferenceUtil {
19 |
20 | public static String FILL_NAME = "file_disable_apps";
21 |
22 | /**
23 | * 存入某个key对应的value值
24 | *
25 | * @param context
26 | * @param key
27 | * @param value
28 | */
29 | public static void put(Context context, String key, Object value) {
30 | SharedPreferences sp = context.getSharedPreferences(FILL_NAME, Context.MODE_PRIVATE);
31 | Editor edit = sp.edit();
32 | if (value instanceof String) {
33 | edit.putString(key, (String) value);
34 | } else if (value instanceof Integer) {
35 | edit.putInt(key, (Integer) value);
36 | } else if (value instanceof Boolean) {
37 | edit.putBoolean(key, (Boolean) value);
38 | } else if (value instanceof Float) {
39 | edit.putFloat(key, (Float) value);
40 | } else if (value instanceof Long) {
41 | edit.putLong(key, (Long) value);
42 | } else if (value instanceof Set) {
43 | edit.putStringSet(key, (Set) value);
44 | }
45 | SharedPreferencesCompat.EditorCompat.getInstance().apply(edit);
46 | }
47 |
48 | /**
49 | * 得到某个key对应的值
50 | *
51 | * @param context
52 | * @param key
53 | * @param defValue
54 | * @return
55 | */
56 | public static Object get(Context context, String key, Object defValue) {
57 | SharedPreferences sp = context.getSharedPreferences(FILL_NAME, Context.MODE_PRIVATE);
58 | if (defValue instanceof String) {
59 | return sp.getString(key, (String) defValue);
60 | } else if (defValue instanceof Integer) {
61 | return sp.getInt(key, (Integer) defValue);
62 | } else if (defValue instanceof Boolean) {
63 | return sp.getBoolean(key, (Boolean) defValue);
64 | } else if (defValue instanceof Float) {
65 | return sp.getFloat(key, (Float) defValue);
66 | } else if (defValue instanceof Long) {
67 | return sp.getLong(key, (Long) defValue);
68 | } else if (defValue instanceof Set) {
69 | return sp.getStringSet(key, (Set) defValue);
70 | }
71 | return null;
72 | }
73 |
74 | /**
75 | * 返回所有数据
76 | *
77 | * @param context
78 | * @return
79 | */
80 | public static Map getAll(Context context) {
81 | SharedPreferences sp = context.getSharedPreferences(FILL_NAME, Context.MODE_PRIVATE);
82 | return sp.getAll();
83 | }
84 |
85 | /**
86 | * 移除某个key值已经对应的值
87 | *
88 | * @param context
89 | * @param key
90 | */
91 | public static void remove(Context context, String key) {
92 | SharedPreferences sp = context.getSharedPreferences(FILL_NAME, Context.MODE_PRIVATE);
93 | Editor edit = sp.edit();
94 | edit.remove(key);
95 | SharedPreferencesCompat.EditorCompat.getInstance().apply(edit);
96 | }
97 |
98 | /**
99 | * 清除所有内容
100 | *
101 | * @param context
102 | */
103 | public static void clear(Context context) {
104 | SharedPreferences sp = context.getSharedPreferences(FILL_NAME, Context.MODE_PRIVATE);
105 | Editor edit = sp.edit();
106 | edit.clear();
107 | SharedPreferencesCompat.EditorCompat.getInstance().apply(edit);
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sscience/stopapp/util/ShortcutsManager.java:
--------------------------------------------------------------------------------
1 | package com.sscience.stopapp.util;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.content.pm.ShortcutInfo;
6 | import android.content.pm.ShortcutManager;
7 | import android.graphics.drawable.Icon;
8 | import android.os.Build;
9 |
10 | import com.sscience.stopapp.R;
11 | import com.sscience.stopapp.activity.ShortcutActivity;
12 | import com.sscience.stopapp.bean.AppInfo;
13 | import com.sscience.stopapp.database.AppInfoDBController;
14 | import com.sscience.stopapp.database.AppInfoDBOpenHelper;
15 |
16 | import java.util.ArrayList;
17 | import java.util.Arrays;
18 | import java.util.List;
19 |
20 | /**
21 | * @author SScience
22 | * @description
23 | * @email chentushen.science@gmail.com
24 | * @data 2017/2/7
25 | */
26 |
27 | public class ShortcutsManager {
28 |
29 | private Context mContext;
30 | public static final String SP_ADD_SHORTCUT_MODE = "sp_shortcut"; // shortcut添加方式
31 | public static final String SP_MANUAL_SHORTCUT = "sp_manual_shortcut"; // shortcut手动添加
32 | public static final String SP_AUTO_SHORTCUT = "sp_auto_shortcut"; // shortcut自动添加
33 | private ShortcutManager mShortcutManager;
34 | private AppInfoDBController mDBController;
35 |
36 | public ShortcutsManager(Context context) {
37 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
38 | mContext = context;
39 | mShortcutManager = context.getSystemService(ShortcutManager.class);
40 | mDBController = new AppInfoDBController(context);
41 | }
42 | }
43 |
44 | /**
45 | * 添加App Shortcut
46 | */
47 | public void addAppShortcut(List appList) {
48 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
49 | List appInfoDB = new ArrayList<>(
50 | mDBController.getDisableApps(AppInfoDBOpenHelper.TABLE_NAME_SHORTCUT_APP_INFO));
51 |
52 | for (AppInfo appInfo : appList) {
53 | if (!mDBController.searchApp(AppInfoDBOpenHelper.TABLE_NAME_SHORTCUT_APP_INFO, appInfo.getAppPackageName())) {
54 | appInfoDB.add(appInfo);
55 | }
56 | }
57 |
58 | mDBController.clearDisableApp(AppInfoDBOpenHelper.TABLE_NAME_SHORTCUT_APP_INFO);
59 | List shortcutList = new ArrayList<>();
60 | for (int i = appInfoDB.size() - 1; i >= 0; i--) {
61 | if (shortcutList.size() < 4) {
62 | shortcutList.add(getShortcut(appInfoDB.get(i)));
63 | mDBController.addDisableApp(appInfoDB.get(i), AppInfoDBOpenHelper.TABLE_NAME_SHORTCUT_APP_INFO);
64 | } else {
65 | removeShortcut(appInfoDB.get(i).getAppPackageName(), mContext.getString(R.string.shortcut_num_limit));
66 | }
67 | }
68 | mShortcutManager.setDynamicShortcuts(shortcutList);
69 | }
70 | }
71 |
72 | /**
73 | * 构造App Shortcut Intent
74 | *
75 | * @param appInfo
76 | * @return
77 | */
78 | private ShortcutInfo getShortcut(AppInfo appInfo) {
79 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
80 | ShortcutInfo shortcut = new ShortcutInfo.Builder(mContext, appInfo.getAppPackageName())
81 | .setShortLabel(appInfo.getAppName())
82 | .setIcon(Icon.createWithBitmap(appInfo.getAppIcon()))
83 | .setIntent(
84 | new Intent(ShortcutActivity.OPEN_APP_SHORTCUT)
85 | .putExtra(ShortcutActivity.EXTRA_PACKAGE_NAME, appInfo.getAppPackageName())
86 | // this dynamic shortcut set up a back stack using Intents, when pressing back, will go to MainActivity
87 | // the last Intent is what the shortcut really opened
88 | // new Intent[]{
89 | // new Intent(Intent.ACTION_MAIN, Uri.EMPTY, mContext, MainActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK),
90 | // new Intent(AppListActivity.ACTION_OPEN_DYNAMIC)
91 | // // intent's action must be set
92 | // }
93 | )
94 | .build();
95 |
96 | return shortcut;
97 | } else {
98 | return null;
99 | }
100 | }
101 |
102 | /**
103 | * 如果桌面有Pinning Shortcuts,且对应的app被用户卸载,则要disable并提示
104 | *
105 | * @param shortcutID
106 | */
107 | public void removeShortcut(String shortcutID, String test) {
108 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
109 | mShortcutManager.disableShortcuts(Arrays.asList(shortcutID), test);
110 | mShortcutManager.removeDynamicShortcuts(Arrays.asList(shortcutID));
111 | mDBController.deleteDisableApp(shortcutID, AppInfoDBOpenHelper.TABLE_NAME_SHORTCUT_APP_INFO);
112 | }
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sscience/stopapp/util/WeakHandler.java:
--------------------------------------------------------------------------------
1 | package com.sscience.stopapp.util;
2 |
3 | import android.os.Handler;
4 | import android.os.Message;
5 |
6 | import java.lang.ref.WeakReference;
7 |
8 | /**
9 | * @author SScience
10 | * @description 弱引用
11 | * @email chentushen.science@gmail.com
12 | * @data 2017/1/15
13 | */
14 |
15 | public class WeakHandler extends Handler {
16 |
17 | public interface IHandler {
18 | void handleMessage(Message msg);
19 | }
20 |
21 | private WeakReference wf;
22 |
23 | public WeakHandler(IHandler handler) {
24 | this.wf = new WeakReference<>(handler);
25 | }
26 |
27 | @Override
28 | public void handleMessage(Message msg) {
29 | super.handleMessage(msg);
30 | IHandler handler = wf.get();
31 | if (handler != null) {
32 | handler.handleMessage(msg);
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sscience/stopapp/widget/AppInfoComparator.java:
--------------------------------------------------------------------------------
1 | package com.sscience.stopapp.widget;
2 |
3 | import android.text.TextUtils;
4 |
5 | import com.sscience.stopapp.bean.AppInfo;
6 |
7 | import java.text.Collator;
8 | import java.util.Comparator;
9 |
10 | /**
11 | * @author SScience
12 | * @description 根据应用名排序
13 | * @email chentushen.science@gmail.com
14 | * @data 2017/2/6
15 | */
16 |
17 | public class AppInfoComparator implements Comparator {
18 |
19 | private final Collator sCollator = Collator.getInstance();
20 |
21 | @Override
22 | public int compare(AppInfo appInfo1, AppInfo appInfo2) {
23 | String sa = appInfo1.getAppName();
24 | if (TextUtils.isEmpty(sa)) {
25 | sa = appInfo1.getAppPackageName();
26 | }
27 | String sb = appInfo2.getAppName();
28 | if (TextUtils.isEmpty(sb)) {
29 | sb = appInfo2.getAppPackageName();
30 | }
31 | return sCollator.compare(sa, sb); // 参考自ApplicationInfo.java中的DisplayNameComparator
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sscience/stopapp/widget/ComponentComparator.java:
--------------------------------------------------------------------------------
1 | package com.sscience.stopapp.widget;
2 |
3 | import com.sscience.stopapp.bean.ComponentInfo;
4 |
5 | import java.text.Collator;
6 | import java.util.Comparator;
7 |
8 | /**
9 | * @author SScience
10 | * @description 根据应用名排序
11 | * @email chentushen.science@gmail.com
12 | * @data 2017/2/6
13 | */
14 |
15 | public class ComponentComparator implements Comparator {
16 |
17 | private final Collator sCollator = Collator.getInstance();
18 |
19 | @Override
20 | public int compare(ComponentInfo componentInfo1, ComponentInfo componentInfo2) {
21 | String sa = componentInfo1.getComponentName().substring(componentInfo1.getComponentName().lastIndexOf(".") + 1);
22 | String sb = componentInfo2.getComponentName().substring(componentInfo2.getComponentName().lastIndexOf(".") + 1);
23 | return sCollator.compare(sa, sb); // 参考自ApplicationInfo.java中的DisplayNameComparator
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sscience/stopapp/widget/MoveFloatingActionButton.java:
--------------------------------------------------------------------------------
1 | package com.sscience.stopapp.widget;
2 |
3 | import android.content.Context;
4 | import android.support.design.widget.FloatingActionButton;
5 | import android.util.AttributeSet;
6 | import android.view.MotionEvent;
7 | import android.view.View;
8 | import android.view.ViewConfiguration;
9 |
10 | /**
11 | * @author SScience
12 | * @description
13 | * @email chentushen.science@gmail.com
14 | * @data 2017/3/29
15 | */
16 |
17 | public class MoveFloatingActionButton extends FloatingActionButton implements View.OnTouchListener {
18 |
19 | private Context mContext;
20 | private float mPosY;
21 | private float mCurPosY;
22 |
23 | public MoveFloatingActionButton(Context context) {
24 | super(context);
25 | mContext = context;
26 | setOnTouchListener(this);
27 | }
28 |
29 | public MoveFloatingActionButton(Context context, AttributeSet attrs) {
30 | super(context, attrs);
31 | mContext = context;
32 | setOnTouchListener(this);
33 | }
34 |
35 | @Override
36 | public boolean onTouch(View v, MotionEvent event) {
37 | switch (event.getAction()) {
38 | case MotionEvent.ACTION_DOWN:
39 | mPosY = event.getRawY();
40 | mCurPosY = mPosY;
41 | break;
42 | case MotionEvent.ACTION_MOVE:
43 | mCurPosY = event.getRawY();
44 | break;
45 | case MotionEvent.ACTION_UP:
46 | int touchSlop = ViewConfiguration.get(mContext).getScaledPagingTouchSlop();
47 | if (mCurPosY - mPosY > 0 && (Math.abs(mCurPosY - mPosY) > touchSlop)) {
48 | //向下滑動
49 | if (mOnMoveListener != null) {
50 | mOnMoveListener.onMove(false);
51 | }
52 | } else if (mCurPosY - mPosY < 0 &&
53 | (Math.abs(mCurPosY - mPosY) > touchSlop)) {
54 | //向上滑动
55 | if (mOnMoveListener != null) {
56 | mOnMoveListener.onMove(true);
57 | }
58 | }
59 | break;
60 | }
61 | return false;
62 | }
63 |
64 | public interface OnMoveListener {
65 | void onMove(boolean isMoveUp);
66 | }
67 |
68 | private OnMoveListener mOnMoveListener;
69 |
70 | public void setOnMoveListener(OnMoveListener onMoveListener) {
71 | mOnMoveListener = onMoveListener;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sscience/stopapp/widget/ScrollAwareFABBehavior.java:
--------------------------------------------------------------------------------
1 | package com.sscience.stopapp.widget;
2 |
3 | import android.content.Context;
4 | import android.support.design.widget.CoordinatorLayout;
5 | import android.support.design.widget.FloatingActionButton;
6 | import android.support.v4.view.ViewCompat;
7 | import android.support.v4.view.ViewPropertyAnimatorListener;
8 | import android.support.v4.view.animation.FastOutSlowInInterpolator;
9 | import android.util.AttributeSet;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import android.view.animation.Interpolator;
13 |
14 | /**
15 | * @author SScience
16 | * @description
17 | * @email chentushen.science@gmail.com
18 | * @data 2017/1/15
19 | */
20 |
21 | public class ScrollAwareFABBehavior extends FloatingActionButton.Behavior {
22 |
23 | private static final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator();
24 | private boolean mIsAnimatingOut = false;
25 |
26 | public ScrollAwareFABBehavior() {
27 | }
28 |
29 | public ScrollAwareFABBehavior(Context context, AttributeSet attrs) {
30 | super();
31 | }
32 |
33 | @Override
34 | public boolean onStartNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child,
35 | final View directTargetChild, final View target, final int nestedScrollAxes) {
36 | // Ensure we react to vertical scrolling
37 | return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;
38 | }
39 |
40 | @Override
41 | public void onNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child,
42 | final View target, final int dxConsumed, final int dyConsumed,
43 | final int dxUnconsumed, final int dyUnconsumed) {
44 | super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
45 | if (dyConsumed > 0 && !this.mIsAnimatingOut) {
46 | // User scrolled down and the FAB is currently visible -> hide the FAB
47 | animateOut(child);
48 | } else if (dyConsumed < 0) {
49 | // User scrolled up and the FAB is currently not visible -> show the FAB
50 | animateIn(child);
51 | }
52 | }
53 |
54 | // Same animation that FloatingActionButton.Behavior uses to hide the FAB when the AppBarLayout exits
55 | private void animateOut(final FloatingActionButton button) {
56 | ViewCompat.animate(button).translationY(button.getHeight() + getMarginBottom(button)).setInterpolator(INTERPOLATOR).withLayer()
57 | .setListener(new ViewPropertyAnimatorListener() {
58 | public void onAnimationStart(View view) {
59 | ScrollAwareFABBehavior.this.mIsAnimatingOut = true;
60 | }
61 |
62 | public void onAnimationCancel(View view) {
63 | ScrollAwareFABBehavior.this.mIsAnimatingOut = false;
64 | }
65 |
66 | public void onAnimationEnd(View view) {
67 | ScrollAwareFABBehavior.this.mIsAnimatingOut = false;
68 | }
69 | }).start();
70 | }
71 |
72 | // Same animation that FloatingActionButton.Behavior uses to show the FAB when the AppBarLayout enters
73 | private void animateIn(FloatingActionButton button) {
74 | ViewCompat.animate(button).translationY(0)
75 | .setInterpolator(INTERPOLATOR).withLayer().setListener(null)
76 | .start();
77 | }
78 |
79 |
80 | private int getMarginBottom(View v) {
81 | int marginBottom = 0;
82 | final ViewGroup.LayoutParams layoutParams = v.getLayoutParams();
83 | if (layoutParams instanceof ViewGroup.MarginLayoutParams) {
84 | marginBottom = ((ViewGroup.MarginLayoutParams) layoutParams).bottomMargin;
85 | }
86 | return marginBottom;
87 | }
88 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/about_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-hdpi/about_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/app_logo_splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-hdpi/app_logo_splash.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-hdpi/ic_action_search.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_android.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-hdpi/ic_android.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_disable_app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-hdpi/ic_disable_app.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_enable_app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-hdpi/ic_enable_app.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_gray_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-hdpi/ic_gray_add.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_shortcut_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-hdpi/ic_shortcut_add.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_white_fab_confirm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-hdpi/ic_white_fab_confirm.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_white_fab_disable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-hdpi/ic_white_fab_disable.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_white_fab_enable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-hdpi/ic_white_fab_enable.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_white_fab_share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-hdpi/ic_white_fab_share.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/no_data.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-hdpi/no_data.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/about_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xhdpi/about_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/app_logo_splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xhdpi/app_logo_splash.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xhdpi/ic_action_search.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_disable_app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xhdpi/ic_disable_app.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_enable_app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xhdpi/ic_enable_app.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_gray_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xhdpi/ic_gray_add.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_shortcut_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xhdpi/ic_shortcut_add.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_white_fab_confirm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xhdpi/ic_white_fab_confirm.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_white_fab_disable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xhdpi/ic_white_fab_disable.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_white_fab_enable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xhdpi/ic_white_fab_enable.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_white_fab_share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xhdpi/ic_white_fab_share.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/no_data.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xhdpi/no_data.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/about_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/about_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/app_logo_splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/app_logo_splash.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/ic_action_search.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_color_lens_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/ic_color_lens_black.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_content_copy_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/ic_content_copy_black.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_delete_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/ic_delete_black.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_disable_app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/ic_disable_app.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_enable_app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/ic_enable_app.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_format_indent_decrease_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/ic_format_indent_decrease_black.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_gray_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/ic_gray_add.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_highlight_off_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/ic_highlight_off_black.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_open_in_new_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/ic_open_in_new_black.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_play_circle_outline_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/ic_play_circle_outline_black.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_playlist_play_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/ic_playlist_play_black.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_shortcut_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/ic_shortcut_add.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_white_fab_confirm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/ic_white_fab_confirm.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_white_fab_disable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/ic_white_fab_disable.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_white_fab_enable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/ic_white_fab_enable.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_white_fab_share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/ic_white_fab_share.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/no_data.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxhdpi/no_data.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/shadow.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/about_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxxhdpi/about_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/app_logo_splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxxhdpi/app_logo_splash.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxxhdpi/ic_action_search.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_disable_app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxxhdpi/ic_disable_app.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_enable_app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxxhdpi/ic_enable_app.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_gray_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxxhdpi/ic_gray_add.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_shortcut_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxxhdpi/ic_shortcut_add.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_white_fab_confirm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxxhdpi/ic_white_fab_confirm.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_white_fab_disable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxxhdpi/ic_white_fab_disable.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_white_fab_enable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxxhdpi/ic_white_fab_enable.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_white_fab_share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxxhdpi/ic_white_fab_share.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/no_data.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable-xxxhdpi/no_data.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/layout_divider.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/share_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/drawable/share_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/splash_screen.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 | -
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
23 |
24 |
31 |
32 |
42 |
43 |
51 |
52 |
53 |
54 |
59 |
60 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
80 |
81 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_app_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
21 |
22 |
30 |
31 |
32 |
40 |
41 |
42 |
43 |
48 |
49 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_component_details.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
21 |
22 |
30 |
31 |
32 |
33 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_setting.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
18 |
19 |
29 |
30 |
37 |
38 |
45 |
46 |
56 |
57 |
66 |
67 |
68 |
69 |
76 |
77 |
84 |
85 |
95 |
96 |
105 |
106 |
107 |
108 |
115 |
116 |
123 |
124 |
135 |
136 |
145 |
146 |
147 |
148 |
155 |
156 |
163 |
164 |
174 |
175 |
182 |
183 |
184 |
185 |
186 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/app_bar_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_edit_app_name.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
18 |
19 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_app_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_app.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
20 |
21 |
31 |
32 |
43 |
44 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_component_details.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
19 |
20 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_disable.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
22 |
23 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/select_launcher_icon.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
21 |
22 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_empty.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_search.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/mipmap-hdpi/ic_launcher_square.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/mipmap-mdpi/ic_launcher_square.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_android.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/mipmap-xhdpi/ic_android.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/mipmap-xhdpi/ic_launcher_square.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_android.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/mipmap-xxhdpi/ic_android.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/mipmap-xxhdpi/ic_launcher_square.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_android.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/mipmap-xxxhdpi/ic_android.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/src/main/res/mipmap-xxxhdpi/ic_launcher_square.png
--------------------------------------------------------------------------------
/app/src/main/res/values-en/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Stop App
5 | Tip
6 | Allow
7 | OK
8 | Deny
9 | Quick Disable
10 | Settings
11 | About
12 | Change Launcher Icon
13 | Custom App Shortcuts
14 | Select
15 | Cancel
16 | Round Icon
17 | Rounded Rectangle Icon
18 | The launcher icon is switched and may take a few seconds to half a minute to take effect!
19 | All apps
20 | System apps
21 | User apps
22 | Disable apps
23 | Would you like to disable [ % s ] ?
24 | Join the stop app list
25 | Out off the stop app list
26 | Uninstall app
27 | Component details
28 | Failure to get root permission!Please grant the root permission!
29 | Quick disable
30 | Quick enable
31 | There are no applications that need to be disabled(ˉ▽ˉ)
32 | Add
33 | Add apps
34 | Add complete!
35 | The app has been disabled(*^_^*)
36 | V %s
37 | About app
38 | about the features of this app
39 | Open source project address
40 | the source code address of the app
41 | Bug report
42 | please submit the bug if you encounter any bug during use
43 | Feedback
44 | please e-mail if you have any comments or suggestions
45 | Share with
46 | Check out the open source App [Stop app]:\n
47 | Focus on freezing app which is not commonly used
48 | Stop App Feedback
49 | App Name:
50 | \nApp Version:
51 | \nDevice Model:
52 | \nAndroid Version:
53 | \nPlease write your feedback here:
54 | Please select email app
55 | Add disable app
56 | Uninstall [%s] successfully
57 | Enable apps successfully
58 | The application is not installed
59 | You can add shortcuts up to 4
60 | Add Shortcut apps
61 | You have not add any shortcut apps
62 | add shortcut
63 | Does not support shortcuts
64 | Open App
65 | Deselect
66 | Enable App
67 | Add Shortcut
68 | Remove from list and enable
69 | Custom app
70 | Custom logo
71 | Custom app name
72 | Remove from list
73 | Press again to exit the app
74 | Successfully created shortcuts!
75 | Successfully operate!
76 | Successfully enable app!
77 | Successfully remove apps from list!
78 | Successfully remove and enable apps from list!
79 | Successfully Disable apps!
80 | Add App Shortcut
81 | Remove App Shortcut
82 | If your app targets Android 7.1 (API level 25) or higher, you can define shortcuts to specific actions in your app.
83 | Your Android version does not support App Shortcut!
84 | Display system disabled apps
85 | Display all disabled apps
86 | Display the system apps on the home page
87 | Display the all apps on the home page
88 | Automatically disable app by accessibility service
89 | Automatically disable app %s
90 | Automatically disable app after action back
91 | Stop App-Automatically Disable
92 | Automatically Disable
93 | Did not find anything
94 | Activity
95 | Service
96 | Receiver
97 | Provider
98 | No data!
99 | search by app name
100 | Do you want to uninstall the [%s] ?
101 | app
102 | Enter custom app name
103 | The picture that you select is too large, please select again!
104 | Custom icons need to read the gallery, please grant read and write permissions!
105 | If you want to custom app logo, you must grant the permission!
106 | The customized logo that you select please follow the android icon specification, the icon size is best not to exceed 40kb!
107 | Automatic disable conditions
108 | after Home immediately
109 | after Home 30s
110 | after Home 60s
111 | after action Back
112 | close auto disable
113 |
114 |
115 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFF
4 | #B2B2B2
5 | #000000
6 | #DCDCDC
7 | #EEEEEE
8 | #48000000
9 |
10 | #212121
11 | #757575
12 | #FFBE00
13 | #737373
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 小黑屋
5 | 提示
6 | 允许
7 | 确定
8 | 拒绝
9 | 一键停用
10 | 设置
11 | 关于
12 | 切换桌面图标
13 | 自定义App Shortcuts
14 | 选择
15 | 取消
16 | 圆形
17 | 圆角矩形
18 | 桌面图标已切换,可能需要数秒到半分钟后生效
19 | 所有应用
20 | 系统应用
21 | 用户应用
22 | 停用应用
23 | 要把 [ %s ] 关进小黑屋吗?
24 | 加入小黑屋
25 | 移除小黑屋
26 | 卸载应用
27 | 组件详情
28 | 暂时没有root权限!请授予本应用root权限!
29 | 一键停用
30 | 一键启用
31 | 小黑屋空空如也(ˉ▽ˉ)
32 | 添加
33 | 添加应用
34 | 添加完成!
35 | 该应用已经加入小黑屋(*^_^*)
36 | V %s
37 | 关于应用
38 | 关于本应用的功能
39 | 开源地址
40 | 本应用源代码地址
41 | 报告错误
42 | 使用遇到任何问题,欢迎联系报告
43 | 反馈建议
44 | 有任何意见或建议,欢迎邮件反馈
45 | 请选择分享方式
46 | 试下免费开源的停用App[小黑屋]吧:\n
47 | 专注停用不(liu)常(mang)用应用,我是小黑屋,我为自己带盐
48 | 小黑屋应用反馈
49 | App名:
50 | \nApp版本:
51 | \n设备型号:
52 | \nAndroid版本:
53 | \n在下面写下您的反馈建议:
54 | 请选择邮件发送软件
55 | 添加停用应用
56 | 卸载[%s]成功
57 | 从列表移除成功
58 | 未安装该应用
59 | App Shortcut最多添加4个
60 | 添加Shortcut应用
61 | 你还未自定义Shortcut应用
62 | 添加快捷方式
63 | 该应用没有用户界面,不支持桌面快捷方式!
64 | 打开应用
65 | 取消选择
66 | 启用应用
67 | 桌面快捷方式
68 | 移除并且启用
69 | 自定义App
70 | 自定义图标
71 | 自定义应用名
72 | 移出小黑屋
73 | 再按一次退出
74 | 创建快捷方式成功!
75 | 操作完成!
76 | 启用应用成功!
77 | 成功移出小黑屋!
78 | 成功移除小黑屋并启用!
79 | 成功关进小黑屋!
80 | 添加App Shortcut
81 | 移除App Shortcut
82 | 长按App图标呼出常用的快捷方式列表,仅支持Android 7.1+
83 | 你的系统版本小于7.1,不支持App Shortcut!
84 | 显示系统停用Apps
85 | 显示所有停用Apps
86 | 在主页停用列表显示系统Apps
87 | 在主页停用列表显示所有Apps
88 | 通过无障碍服务,自动停用App
89 | %s自动停用App
90 | 按返回键退出App时,自动停用App
91 | 小黑屋-自动停用
92 | 自动停用
93 | 暂时无此应用!
94 | 界面
95 | 服务
96 | 广播接收器
97 | 内容提供者
98 | 没有任何数据!
99 | 按应用名搜索
100 | 确认卸载 [%s] 吗?
101 | 应用
102 | 输入应用名
103 | 选择的图片过大,请重新选择!
104 | 自定义图标需要读取图库文件,请授予小黑屋读写权限!
105 | 授予读写权限才能自定义图标!
106 | 选取的图标请按照Google Android启动图标设计规范,大小最好不要超过40kb,以免图标压缩失真!
107 | 自动停用条件
108 | Home键退出立即
109 | Home键退出30秒后
110 | Home键退出60秒后
111 | 返回键退出立即(仅支持物理按键)
112 | 关闭自动停用
113 |
114 |
115 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
14 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/xml-v25/shortcuts.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
12 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/accessibility_service_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/test/java/com/sscience/stopapp/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.sscience.stopapp;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/app/stopapp_release_3_v1.1.1_20170316121413.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/stopapp_release_3_v1.1.1_20170316121413.apk
--------------------------------------------------------------------------------
/app/stopapp_release_5_v1.2.1_20170406105104.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/stopapp_release_5_v1.2.1_20170406105104.apk
--------------------------------------------------------------------------------
/app/stopapp_release_6_v1.3_20170427191236.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/app/stopapp_release_6_v1.3_20170427191236.apk
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.2.3'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | maven { url "https://jitpack.io" }
19 | }
20 | }
21 |
22 | task clean(type: Delete) {
23 | delete rootProject.buildDir
24 | }
25 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/screenshot/Screenshot_20170214-180852.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/screenshot/Screenshot_20170214-180852.png
--------------------------------------------------------------------------------
/screenshot/Screenshot_20170316-120548.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/screenshot/Screenshot_20170316-120548.png
--------------------------------------------------------------------------------
/screenshot/Screenshot_20170427-190046.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XYScience/StopApp/9e126174a7e1141bb479f23183a1d3e1c2a1b55c/screenshot/Screenshot_20170427-190046.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------