新增 可以使用"查看使用统计权限"增强currentPackage()的准确性,在代码中通过auto.setFlags("useUsageStats")启用
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
|
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||||
|
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
|
||||||
|
|
||||||
|
|
||||||
<!-- 非Auto.js运行必需,不会主动申请,某些脚本可以自行申请-->
|
<!-- 非Auto.js运行必需,不会主动申请,某些脚本可以自行申请-->
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import org.autojs.autojs.ui.floating.layoutinspector.LayoutHierarchyFloatyWindow
|
|||||||
import org.autojs.autojs.ui.main.MainActivity_;
|
import org.autojs.autojs.ui.main.MainActivity_;
|
||||||
import org.autojs.autojs.ui.explorer.ExplorerView;
|
import org.autojs.autojs.ui.explorer.ExplorerView;
|
||||||
import org.autojs.autojs.theme.dialog.ThemeColorMaterialDialogBuilder;
|
import org.autojs.autojs.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||||
|
|
||||||
import com.stardust.util.ClipboardUtil;
|
import com.stardust.util.ClipboardUtil;
|
||||||
import com.stardust.util.Func1;
|
import com.stardust.util.Func1;
|
||||||
import com.stardust.view.accessibility.LayoutInspector;
|
import com.stardust.view.accessibility.LayoutInspector;
|
||||||
@@ -260,7 +261,7 @@ public class CircularMenu implements Recorder.OnStateChangedListener, LayoutInsp
|
|||||||
@OnClick(R.id.settings)
|
@OnClick(R.id.settings)
|
||||||
void settings() {
|
void settings() {
|
||||||
mWindow.collapse();
|
mWindow.collapse();
|
||||||
mRunningPackage = AutoJs.getInstance().getInfoProvider().getLatestPackage();
|
mRunningPackage = AutoJs.getInstance().getInfoProvider().getLatestPackageByUsageStatsIfGranted();
|
||||||
mRunningActivity = AutoJs.getInstance().getInfoProvider().getLatestActivity();
|
mRunningActivity = AutoJs.getInstance().getInfoProvider().getLatestActivity();
|
||||||
mSettingsDialog = new OperationDialogBuilder(mContext)
|
mSettingsDialog = new OperationDialogBuilder(mContext)
|
||||||
.item(R.id.accessibility_service, R.drawable.ic_service_green, R.string.text_accessibility_settings)
|
.item(R.id.accessibility_service, R.drawable.ic_service_green, R.string.text_accessibility_settings)
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
package org.autojs.autojs.ui.main.drawer;
|
package org.autojs.autojs.ui.main.drawer;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.AppOpsManager;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
@@ -21,6 +24,7 @@ import com.bumptech.glide.request.RequestOptions;
|
|||||||
import com.bumptech.glide.request.target.CustomViewTarget;
|
import com.bumptech.glide.request.target.CustomViewTarget;
|
||||||
import com.bumptech.glide.request.target.SimpleTarget;
|
import com.bumptech.glide.request.target.SimpleTarget;
|
||||||
import com.bumptech.glide.request.transition.Transition;
|
import com.bumptech.glide.request.transition.Transition;
|
||||||
|
import com.stardust.app.AppOpsKt;
|
||||||
import com.stardust.app.GlobalAppContext;
|
import com.stardust.app.GlobalAppContext;
|
||||||
import com.stardust.notification.NotificationListenerService;
|
import com.stardust.notification.NotificationListenerService;
|
||||||
|
|
||||||
@@ -113,6 +117,7 @@ public class DrawerFragment extends androidx.fragment.app.Fragment {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private DrawerMenuItem mNotificationPermissionItem = new DrawerMenuItem(R.drawable.ic_ali_notification, R.string.text_notification_permission, 0, this::goToNotificationServiceSettings);
|
private DrawerMenuItem mNotificationPermissionItem = new DrawerMenuItem(R.drawable.ic_ali_notification, R.string.text_notification_permission, 0, this::goToNotificationServiceSettings);
|
||||||
|
private DrawerMenuItem mUsageStatsPermissionItem = new DrawerMenuItem(R.drawable.ic_ali_notification, R.string.text_usage_stats_permission, 0, this::goToUsageStatsSettings);
|
||||||
private DrawerMenuItem mForegroundServiceItem = new DrawerMenuItem(R.drawable.ic_service_green, R.string.text_foreground_service, R.string.key_foreground_servie, this::toggleForegroundService);
|
private DrawerMenuItem mForegroundServiceItem = new DrawerMenuItem(R.drawable.ic_service_green, R.string.text_foreground_service, R.string.key_foreground_servie, this::toggleForegroundService);
|
||||||
|
|
||||||
private DrawerMenuItem mFloatingWindowItem = new DrawerMenuItem(R.drawable.ic_robot_64, R.string.text_floating_window, 0, this::showOrDismissFloatingWindow);
|
private DrawerMenuItem mFloatingWindowItem = new DrawerMenuItem(R.drawable.ic_robot_64, R.string.text_floating_window, 0, this::showOrDismissFloatingWindow);
|
||||||
@@ -163,6 +168,7 @@ public class DrawerFragment extends androidx.fragment.app.Fragment {
|
|||||||
mStableModeItem,
|
mStableModeItem,
|
||||||
mNotificationPermissionItem,
|
mNotificationPermissionItem,
|
||||||
mForegroundServiceItem,
|
mForegroundServiceItem,
|
||||||
|
mUsageStatsPermissionItem,
|
||||||
|
|
||||||
new DrawerMenuGroup(R.string.text_script_record),
|
new DrawerMenuGroup(R.string.text_script_record),
|
||||||
mFloatingWindowItem,
|
mFloatingWindowItem,
|
||||||
@@ -226,6 +232,17 @@ public class DrawerFragment extends androidx.fragment.app.Fragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void goToUsageStatsSettings(DrawerMenuItemViewHolder holder) {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean enabled = AppOpsKt.isOpPermissionGranted(getContext(), AppOpsManager.OPSTR_GET_USAGE_STATS);
|
||||||
|
boolean checked = holder.getSwitchCompat().isChecked();
|
||||||
|
if ((checked && !enabled) || (!checked && enabled)) {
|
||||||
|
IntentUtil.requestAppUsagePermission(getContext());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void showOrDismissFloatingWindow(DrawerMenuItemViewHolder holder) {
|
void showOrDismissFloatingWindow(DrawerMenuItemViewHolder holder) {
|
||||||
boolean isFloatingWindowShowing = FloatyWindowManger.isCircularMenuShowing();
|
boolean isFloatingWindowShowing = FloatyWindowManger.isCircularMenuShowing();
|
||||||
boolean checked = holder.getSwitchCompat().isChecked();
|
boolean checked = holder.getSwitchCompat().isChecked();
|
||||||
@@ -390,7 +407,9 @@ public class DrawerFragment extends androidx.fragment.app.Fragment {
|
|||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||||
setChecked(mNotificationPermissionItem, NotificationListenerService.Companion.getInstance() != null);
|
setChecked(mNotificationPermissionItem, NotificationListenerService.Companion.getInstance() != null);
|
||||||
}
|
}
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
setChecked(mUsageStatsPermissionItem, AppOpsKt.isOpPermissionGranted(getContext(), AppOpsManager.OPSTR_GET_USAGE_STATS));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enableAccessibilityService() {
|
private void enableAccessibilityService() {
|
||||||
|
|||||||
@@ -273,7 +273,7 @@
|
|||||||
<string name="text_reset_succeed">重置成功</string>
|
<string name="text_reset_succeed">重置成功</string>
|
||||||
<string name="text_cannot_read_file">无法读取文件</string>
|
<string name="text_cannot_read_file">无法读取文件</string>
|
||||||
<string name="text_service">服务</string>
|
<string name="text_service">服务</string>
|
||||||
<string name="text_notification_permission">通知权限</string>
|
<string name="text_notification_permission">通知读取权限</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="text_open_main_activity">打开主界面</string>
|
<string name="text_open_main_activity">打开主界面</string>
|
||||||
@@ -429,4 +429,5 @@
|
|||||||
<string name="text_night_mode">夜间模式</string>
|
<string name="text_night_mode">夜间模式</string>
|
||||||
<string name="key_night_mode">key_night_mode</string>
|
<string name="key_night_mode">key_night_mode</string>
|
||||||
<string name="text_run_on_startup">Auto.js启动时</string>
|
<string name="text_run_on_startup">Auto.js启动时</string>
|
||||||
|
<string name="text_usage_stats_permission">查看使用统计权限</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -110,7 +110,8 @@ module.exports = function(runtime, global){
|
|||||||
}
|
}
|
||||||
|
|
||||||
const flagsMap = {
|
const flagsMap = {
|
||||||
"findOnUiThread": 1
|
"findOnUiThread": 1,
|
||||||
|
"useUsageStats": 2
|
||||||
};
|
};
|
||||||
|
|
||||||
var auto = function(mode){
|
var auto = function(mode){
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import android.app.Application;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.RequiresApi;
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
@@ -67,7 +68,7 @@ public abstract class AutoJs {
|
|||||||
mAppUtils = createAppUtils(mContext);
|
mAppUtils = createAppUtils(mContext);
|
||||||
mGlobalConsole = createGlobalConsole();
|
mGlobalConsole = createGlobalConsole();
|
||||||
mNotificationObserver = new AccessibilityNotificationObserver(mContext);
|
mNotificationObserver = new AccessibilityNotificationObserver(mContext);
|
||||||
mAccessibilityInfoProvider = new AccessibilityInfoProvider(mContext.getPackageManager());
|
mAccessibilityInfoProvider = new AccessibilityInfoProvider(mContext);
|
||||||
mScriptEngineService = buildScriptEngineService();
|
mScriptEngineService = buildScriptEngineService();
|
||||||
ScriptEngineService.setInstance(mScriptEngineService);
|
ScriptEngineService.setInstance(mScriptEngineService);
|
||||||
init();
|
init();
|
||||||
@@ -205,7 +206,7 @@ public abstract class AutoJs {
|
|||||||
private class AccessibilityBridgeImpl extends AccessibilityBridge {
|
private class AccessibilityBridgeImpl extends AccessibilityBridge {
|
||||||
|
|
||||||
public AccessibilityBridgeImpl(UiHandler uiHandler) {
|
public AccessibilityBridgeImpl(UiHandler uiHandler) {
|
||||||
super(createAccessibilityConfig(), uiHandler);
|
super(mContext, createAccessibilityConfig(), uiHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
package com.stardust.autojs.core.accessibility;
|
package com.stardust.autojs.core.accessibility;
|
||||||
|
|
||||||
|
import android.app.AppOpsManager;
|
||||||
|
import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import android.view.accessibility.AccessibilityNodeInfo;
|
import android.view.accessibility.AccessibilityNodeInfo;
|
||||||
import android.view.accessibility.AccessibilityWindowInfo;
|
import android.view.accessibility.AccessibilityWindowInfo;
|
||||||
|
|
||||||
|
import com.stardust.app.AppOpsKt;
|
||||||
import com.stardust.autojs.runtime.accessibility.AccessibilityConfig;
|
import com.stardust.autojs.runtime.accessibility.AccessibilityConfig;
|
||||||
|
import com.stardust.util.IntentUtil;
|
||||||
import com.stardust.util.UiHandler;
|
import com.stardust.util.UiHandler;
|
||||||
import com.stardust.view.accessibility.AccessibilityInfoProvider;
|
import com.stardust.view.accessibility.AccessibilityInfoProvider;
|
||||||
import com.stardust.view.accessibility.AccessibilityNotificationObserver;
|
import com.stardust.view.accessibility.AccessibilityNotificationObserver;
|
||||||
@@ -27,17 +33,20 @@ public abstract class AccessibilityBridge {
|
|||||||
public static final int MODE_FAST = 1;
|
public static final int MODE_FAST = 1;
|
||||||
|
|
||||||
public static final int FLAG_FIND_ON_UI_THREAD = 1;
|
public static final int FLAG_FIND_ON_UI_THREAD = 1;
|
||||||
|
public static final int FLAG_USE_USAGE_STATS = 2;
|
||||||
|
|
||||||
private int mMode = MODE_NORMAL;
|
private int mMode = MODE_NORMAL;
|
||||||
private int mFlags = 0;
|
private int mFlags = 0;
|
||||||
private final AccessibilityConfig mConfig;
|
private final AccessibilityConfig mConfig;
|
||||||
private WindowFilter mWindowFilter;
|
private WindowFilter mWindowFilter;
|
||||||
private final UiHandler mUiHandler;
|
private final UiHandler mUiHandler;
|
||||||
|
private final Context mContext;
|
||||||
|
|
||||||
public AccessibilityBridge(AccessibilityConfig config, UiHandler uiHandler) {
|
public AccessibilityBridge(Context context, AccessibilityConfig config, UiHandler uiHandler) {
|
||||||
mConfig = config;
|
mConfig = config;
|
||||||
mUiHandler = uiHandler;
|
mUiHandler = uiHandler;
|
||||||
mConfig.seal();
|
mConfig.seal();
|
||||||
|
mContext = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void ensureServiceEnabled();
|
public abstract void ensureServiceEnabled();
|
||||||
@@ -80,7 +89,6 @@ public abstract class AccessibilityBridge {
|
|||||||
mWindowFilter = windowFilter;
|
mWindowFilter = windowFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public abstract AccessibilityInfoProvider getInfoProvider();
|
public abstract AccessibilityInfoProvider getInfoProvider();
|
||||||
|
|
||||||
public void setMode(int mode) {
|
public void setMode(int mode) {
|
||||||
@@ -93,6 +101,13 @@ public abstract class AccessibilityBridge {
|
|||||||
|
|
||||||
public void setFlags(int flags) {
|
public void setFlags(int flags) {
|
||||||
mFlags = flags;
|
mFlags = flags;
|
||||||
|
if ((mFlags & FLAG_USE_USAGE_STATS) != 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
if (!AppOpsKt.isOpPermissionGranted(mContext, AppOpsManager.OPSTR_GET_USAGE_STATS)) {
|
||||||
|
IntentUtil.requestAppUsagePermission(mContext);
|
||||||
|
throw new SecurityException("没有\"查看使用情况\"权限");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getInfoProvider().setUseUsageStats((mFlags & FLAG_USE_USAGE_STATS) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
|||||||
@@ -1,33 +1,41 @@
|
|||||||
package com.stardust.view.accessibility
|
package com.stardust.view.accessibility
|
||||||
|
|
||||||
import android.accessibilityservice.AccessibilityService
|
import android.accessibilityservice.AccessibilityService
|
||||||
|
import android.app.AppOpsManager
|
||||||
|
import android.app.usage.UsageStatsManager
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.pm.ActivityInfo
|
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
|
import android.os.Build
|
||||||
import android.view.accessibility.AccessibilityEvent
|
import android.view.accessibility.AccessibilityEvent
|
||||||
import android.view.accessibility.AccessibilityNodeInfo
|
import androidx.annotation.RequiresApi
|
||||||
|
import com.stardust.app.isOpPermissionGranted
|
||||||
import com.stardust.view.accessibility.AccessibilityDelegate
|
|
||||||
|
|
||||||
import java.util.Arrays
|
|
||||||
import java.util.Collections
|
|
||||||
import java.util.HashSet
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on 2017/3/9.
|
* Created by Stardust on 2017/3/9.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class AccessibilityInfoProvider(private val mPackageManager: PackageManager) : AccessibilityDelegate {
|
class AccessibilityInfoProvider(private val context: Context) : AccessibilityDelegate {
|
||||||
|
|
||||||
|
private val mPackageManager: PackageManager = context.packageManager
|
||||||
|
|
||||||
@Volatile
|
@Volatile
|
||||||
var latestPackage = ""
|
private var mLatestPackage: String = ""
|
||||||
private set
|
|
||||||
|
val latestPackage: String
|
||||||
|
get() {
|
||||||
|
if (useUsageStats && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
|
||||||
|
mLatestPackage = getLatestPackageByUsageStats()
|
||||||
|
}
|
||||||
|
return mLatestPackage
|
||||||
|
}
|
||||||
|
|
||||||
@Volatile
|
@Volatile
|
||||||
var latestActivity = ""
|
var latestActivity = ""
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
var useUsageStats: Boolean = true
|
||||||
|
|
||||||
override val eventTypes: Set<Int>?
|
override val eventTypes: Set<Int>?
|
||||||
get() = AccessibilityDelegate.ALL_EVENT_TYPES
|
get() = AccessibilityDelegate.ALL_EVENT_TYPES
|
||||||
|
|
||||||
@@ -38,6 +46,29 @@ class AccessibilityInfoProvider(private val mPackageManager: PackageManager) : A
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getLatestPackageByUsageStatsIfGranted(): String {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1 && context.isOpPermissionGranted(AppOpsManager.OPSTR_GET_USAGE_STATS)) {
|
||||||
|
return getLatestPackageByUsageStats()
|
||||||
|
}
|
||||||
|
return mLatestPackage
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.LOLLIPOP_MR1)
|
||||||
|
fun getLatestPackageByUsageStats(): String {
|
||||||
|
val usageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
|
||||||
|
val current = System.currentTimeMillis()
|
||||||
|
val usageStats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, current - 60 * 60 * 1000, current)
|
||||||
|
return if (usageStats.isEmpty()) {
|
||||||
|
""
|
||||||
|
} else {
|
||||||
|
usageStats.sortBy {
|
||||||
|
it.lastTimeStamp
|
||||||
|
}
|
||||||
|
usageStats.last().packageName
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private fun setLatestComponent(latestPackage: CharSequence?, latestClass: CharSequence?) {
|
private fun setLatestComponent(latestPackage: CharSequence?, latestClass: CharSequence?) {
|
||||||
if (latestPackage == null || latestClass == null)
|
if (latestPackage == null || latestClass == null)
|
||||||
return
|
return
|
||||||
@@ -51,7 +82,6 @@ class AccessibilityInfoProvider(private val mPackageManager: PackageManager) : A
|
|||||||
} catch (ignored: PackageManager.NameNotFoundException) {
|
} catch (ignored: PackageManager.NameNotFoundException) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
mLatestPackage = latestPackage.toString()
|
||||||
this.latestPackage = latestPackage.toString()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
20
common/src/main/java/com/stardust/app/AppOps.kt
Normal file
20
common/src/main/java/com/stardust/app/AppOps.kt
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package com.stardust.app
|
||||||
|
|
||||||
|
import android.app.AppOpsManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.KITKAT)
|
||||||
|
fun Context.isOpPermissionGranted(permission: String): Boolean {
|
||||||
|
val appOps = getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
|
||||||
|
val mode = appOps.checkOpNoThrow(permission, android.os.Process.myUid(), packageName)
|
||||||
|
|
||||||
|
return if (mode == AppOpsManager.MODE_DEFAULT && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
checkCallingOrSelfPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) == PackageManager.PERMISSION_GRANTED
|
||||||
|
} else {
|
||||||
|
mode == AppOpsManager.MODE_ALLOWED
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,8 +4,12 @@ import android.content.ActivityNotFoundException;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
import androidx.core.content.FileProvider;
|
import androidx.core.content.FileProvider;
|
||||||
|
|
||||||
|
import android.os.Build;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.stardust.R;
|
import com.stardust.R;
|
||||||
@@ -182,4 +186,15 @@ public class IntentUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
public static void requestAppUsagePermission(Context context) {
|
||||||
|
Intent intent = new Intent(android.provider.Settings.ACTION_USAGE_ACCESS_SETTINGS);
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
try {
|
||||||
|
context.startActivity(intent);
|
||||||
|
} catch (ActivityNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user