0

在这方面,我正在研究应用程序储物柜我构建的代码可以在下面看到。我的问题是我的代码在版本 20 (Lollipop) 以下运行,并且不适用于高于版本 20。

我已经应用了该站点上打印的几乎所有解决方案,但都失败了。有时但很少我让应用程序储物柜工作,但对于设置等有限的应用程序。这是我获取包名称的方式:

 private String getTopPackageName() {


    if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        UsageStatsManager usm = (UsageStatsManager) this.getSystemService(Context.USAGE_STATS_SERVICE);
        long time = System.currentTimeMillis();
        List<UsageStats> appList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,  time-1000*1000, time);
        if (appList != null && appList.size() > 0) {
            SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>();
            for (UsageStats usageStats : appList) {
                mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
            }
            if (mySortedMap != null && !mySortedMap.isEmpty()) {
                currentApp = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
            }
        }
    } else {
        mActivityManager = (ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> tasks = mActivityManager.getRunningAppProcesses();
        currentApp = tasks.get(0).processName;
    }

    return currentApp;
}

这也是我的整个服务班

public class AppLockService extends Service {

public static final String BROADCAST_SERVICE_STARTED = "com.appslocker.locker.intent.action.service_started";
/**
 * Sent to {@link MainActivity} when the service has been stopped
 */
public static final String BROADCAST_SERVICE_STOPPED = "com.appslocker.locker.intent.action.service_stopped";
/**
 * This category allows the receiver to receive actions relating to the
 * state of the service, such as when it is started or stopped
 */
public static final String CATEGORY_STATE_EVENTS = "com.appslocker.locker.intent.category.service_start_stop_event";

private static final int REQUEST_CODE = 0x1234AF;
public static final int NOTIFICATION_ID = 0xABCD32;
private static final String TAG = "AppLockService";

/**
 * Use this action to stop the intent
 */
private static final String ACTION_STOP = "com.apsscloker.locker.intent.action.stop_lock_service";
/**
 * Starts the alarm
 */
private static final String ACTION_START = "com.appslocker.locker.intent.action.start_lock_service";
/**
 * When specifying this action, the service will initialize everything
 * again.<br>
 * This has only effect if the service was explicitly started using
 * {@link #getRunIntent(Context)}
 */
private static final String ACTION_RESTART = "com.appslocker.locker.intent.action.restart_lock_service";

private static final String EXTRA_FORCE_RESTART = "com.appslocker.locker.intent.extra.force_restart";
private ActivityManager mActivityManager;

/**
 * 0 for disabled
 */
private long mShortExitMillis;

private boolean mRelockScreenOff;
private boolean mShowNotification;

private boolean mExplicitStarted;
private boolean mAllowDestroy;
private boolean mAllowRestart;
private Handler mHandler;
private BroadcastReceiver mScreenReceiver;
private String currentApp;
/**
 * This map contains locked apps in the form<br>
 * <PackageName, ShortExitEndTime>
 */
private Map<String, Boolean> mLockedPackages;
private Map<String, Runnable> mUnlockMap;

@Override
public IBinder onBind(Intent i) {
    return new LocalBinder();
}

public class LocalBinder extends Binder {
    public AppLockService getInstance() {
        return AppLockService.this;
    }
}

private final class ScreenReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
            Log.i(TAG, "Screen ON");
            // Trigger package again
            mLastPackageName = "";
            startAlarm(AppLockService.this);
        }
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            Log.i(TAG, "Screen OFF");
            stopAlarm(AppLockService.this);
            if (mRelockScreenOff) {
                lockAll();
            }
        }
    }
}

;

@Override
public void onCreate() {
    super.onCreate();
    Log.d(TAG, "onCreate");

}

/**
 * Starts everything, including notification and repeating alarm
 *
 * @return True if all OK, false if the service is not allowed to start (the
 * caller should stop the service)
 */
private boolean init() {
    Log.d(TAG, "init");
    if (new PrefUtils(this).isCurrentPasswordEmpty()) {
        Log.w(TAG, "Not starting service, current password empty");
        return false;
    }


    mHandler = new Handler();
    mActivityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);

    mUnlockMap = new HashMap<>();
    mLockedPackages = new HashMap<>();
    mScreenReceiver = new ScreenReceiver();
    IntentFilter filter = new IntentFilter();
    filter.addAction(Intent.ACTION_SCREEN_ON);
    filter.addAction(Intent.ACTION_SCREEN_OFF);
    registerReceiver(mScreenReceiver, filter);

    final Set<String> apps = PrefUtils.getLockedApps(this);
    for (String s : apps) {
        mLockedPackages.put(s, true);
    }
    PrefUtils prefs = new PrefUtils(this);
    boolean delay = prefs.getBoolean(R.string.pref_key_delay_status,
            R.bool.pref_def_delay_status);

    if (delay) {
        int secs = prefs.parseInt(R.string.pref_key_delay_time,
                R.string.pref_def_delay_time);
        mShortExitMillis = secs * 1000;
    }

    mRelockScreenOff = prefs.getBoolean(
            R.string.pref_key_relock_after_screenoff,
            R.bool.pref_def_relock_after_screenoff);

    startNotification();
    startAlarm(this);

    // Tell MainActivity we're done
    Intent i = new Intent(BROADCAST_SERVICE_STARTED);
    i.addCategory(CATEGORY_STATE_EVENTS);
    sendBroadcast(i);
    return true;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // Log.d(TAG, "test");
    if (intent == null || ACTION_START.equals(intent.getAction())) {
        if (!mExplicitStarted) {
            Log.d(TAG, "explicitStarted = false");
            if (init() == false) {
                doStopSelf();
                return START_NOT_STICKY;
            }
            mExplicitStarted = true;
        }
        checkPackageChanged();
    } else if (ACTION_RESTART.equals(intent.getAction())) {
        if (mExplicitStarted
                || intent.getBooleanExtra(EXTRA_FORCE_RESTART, false)) {
            Log.d(TAG,
                    "ACTION_RESTART (force="
                            + intent.getBooleanExtra(EXTRA_FORCE_RESTART,
                            false));
            // init();
            doRestartSelf(); // not allowed, so service will restart
        } else {
            doStopSelf();
        }
    } else if (ACTION_STOP.equals(intent.getAction())) {
        Log.d(TAG, "ACTION_STOP");
        doStopSelf();
    }

    return START_STICKY;
}

private String mLastPackageName;


private void checkPackageChanged() {
    final String packageName = getTopPackageName();
    // final String completeName = packageName + "/"
    // + top.topActivity.getShortClassName();

    if (!packageName.equals(mLastPackageName)) {
        Log.d(TAG, "appchanged " + " (" + mLastPackageName + ">"
                + packageName + ")");

        onAppClose(mLastPackageName, packageName);
        onAppOpen(packageName, mLastPackageName);
    }

    // prepare for next call
    mLastPackageName = packageName;
    // mLastCompleteName = completeName;
}

private void onAppOpen(final String open, final String close) {
    if (mLockedPackages.containsKey(open)) {
        onLockedAppOpen(open);
    }
}

private void onLockedAppOpen(final String open) {
    final boolean locked = mLockedPackages.get(open);
    // Log.d(TAG, "onLockedAppOpen (locked=" + locked + ")");
    if (locked) {
        showLocker(open);
    }
    removeRelockTimer(open);
}

private void showLocker(String packageName) {
    Intent intent = LockService.getLockIntent(getApplicationContext(), packageName);
    intent.setAction(LockService.ACTION_COMPARE);
    intent.putExtra(LockService.EXTRA_PACKAGENAME, packageName);
    startService(intent);

}

private void showLockerForCategory(String category) {
    Intent intent = LockService.getLockIntentForCategory(this, category);
    intent.setAction(LockService.ACTION_COMPARE);
    intent.putExtra(LockService.EXTRA_CATEGORY, category);
    startService(intent);

}

private void onAppClose(String close, String open) {
    if (mLockedPackages.containsKey(close)) {
        onLockedAppClose(close, open);
    }
}

private void onLockedAppClose(String close, String open) {
    //showInterstitial();

    setRelockTimer(close);

    if (getPackageName().equals(close) || getPackageName().equals(open)) {
        // Don't interact with own app
        return;
    }

    if (mLockedPackages.containsKey(open)) {
        // The newly opened app needs a lock screen, so don't hide previous
        return;
    }
    LockService.hide(this);
}

private void setRelockTimer(String packageName) {
    boolean locked = mLockedPackages.get(packageName);
    if (!locked) {
        if (mShortExitMillis != 0) {
            Runnable r = new RelockRunnable(packageName);
            mHandler.postDelayed(r, mShortExitMillis);
            mUnlockMap.put(packageName, r);
        } else {
            lockApp(packageName);
        }
    }
}

private void removeRelockTimer(String packageName) {
    // boolean locked = mLockedPackages.get(packageName);
    // if (!locked) {
    if (mUnlockMap.containsKey(packageName)) {
        mHandler.removeCallbacks(mUnlockMap.get(packageName));
        mUnlockMap.remove(packageName);
    }
}

/**
 * This class will re-lock an app
 */
private class RelockRunnable implements Runnable {
    private final String mPackageName;

    public RelockRunnable(String packageName) {
        mPackageName = packageName;
    }

    @Override
    public void run() {
        lockApp(mPackageName);
    }
}

List<RunningTaskInfo> mTestList = new ArrayList<>();


private String getTopPackageName() {


    if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        UsageStatsManager usm = (UsageStatsManager) this.getSystemService(Context.USAGE_STATS_SERVICE);
        long time = System.currentTimeMillis();
        List<UsageStats> appList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,  time-1000*1000, time);
        if (appList != null && appList.size() > 0) {
            SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>();
            for (UsageStats usageStats : appList) {
                mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
            }
            if (mySortedMap != null && !mySortedMap.isEmpty()) {
                currentApp = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
            }
        }
    } else {
        mActivityManager = (ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> tasks = mActivityManager.getRunningAppProcesses();
        currentApp = tasks.get(0).processName;
    }

    return currentApp;

   /* if (Build.VERSION.SDK_INT > 20) {
        return mActivityManager.getRunningAppProcesses().get(0).processName;
       // mClassName = activityManager.getRunningAppProcesses().get(0).getClass().getName();
    } else {
         return  mActivityManager.getRunningTasks(1).get(0).topActivity.getPackageName();
       // mClassName = activityManager.getRunningTasks(1).get(0).topActivity.getClassName();
    }*/

}

public void unlockApp(String packageName) {
    Log.d(TAG, "unlocking app (packageName=" + packageName + ")");
    if (mLockedPackages.containsKey(packageName)) {
        mLockedPackages.put(packageName, false);
    }
}

private void lockAll() {
    for (Map.Entry<String, Boolean> entry : mLockedPackages.entrySet()) {
        entry.setValue(true);
    }
}

void lockApp(String packageName) {
    if (mLockedPackages.containsKey(packageName)) {
        mLockedPackages.put(packageName, true);
    }
}

private void startNotification() {

    // Start foreground anyway
    startForegroundWithNotification();

    mShowNotification = new PrefUtils(this).getBoolean(
            R.string.pref_key_show_notification,
            R.bool.pref_def_show_notification);

}

@SuppressLint("InlinedApi")
private void startForegroundWithNotification() {
    Log.d(TAG, "showNotification");

    boolean hide = new PrefUtils(this).getBoolean(
            R.string.pref_key_hide_notification_icon,
            R.bool.pref_def_hide_notification_icon);
    int priority = hide ? Notification.PRIORITY_MIN
            : Notification.PRIORITY_DEFAULT;
    Intent i = new Intent(this, MainActivity.class);
    PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0);
    String title = getString(R.string.notification_title);
    String content = getString(R.string.notification_state_locked);
    NotificationCompat.Builder nb = new NotificationCompat.Builder(this);
    nb.setSmallIcon(R.drawable.ic_launcher);
    nb.setContentTitle(title);
    nb.setContentText(content);
    nb.setWhen(System.currentTimeMillis());
    nb.setContentIntent(pi);
    nb.setOngoing(true);
    nb.setPriority(priority);

    startForeground(NOTIFICATION_ID, nb.build());
}

public static void start(Context c) {
    startAlarm(c);
}

/**
 * @param c
 * @return The new state for the service, true for running, false for not
 * running
 */
public static boolean toggle(Context c) {
    if (isRunning(c)) {
        stop(c);
        return false;
    } else {
        start(c);
        return true;
    }

}

public static boolean isRunning(Context c) {
    ActivityManager manager = (ActivityManager) c
            .getSystemService(Context.ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager
            .getRunningServices(Integer.MAX_VALUE)) {
        if (AppLockService.class.getName().equals(
                service.service.getClassName())) {
            return true;
        }
    }
    return false;
}

/**
 * Starts the service
 */
private static void startAlarm(Context c) {
    AlarmManager am = (AlarmManager) c.getSystemService(ALARM_SERVICE);
    PendingIntent pi = getRunIntent(c);
    SharedPreferences sp = PrefUtils.prefs(c);
    String defaultPerformance = c.getString(R.string.pref_val_perf_normal);
    String s = sp.getString(c.getString(R.string.pref_key_performance),
            defaultPerformance);
    if (s.length() == 0)
        s = "0";
    long interval = Long.parseLong(s);
    Log.d(TAG, "Scheduling alarm (interval=" + interval + ")");
    long startTime = SystemClock.elapsedRealtime();
    am.setRepeating(AlarmManager.ELAPSED_REALTIME, startTime, interval, pi);
}

private static PendingIntent running_intent;

private static PendingIntent getRunIntent(Context c) {
    if (running_intent == null) {
        Intent i = new Intent(c, AppLockService.class);
        i.setAction(ACTION_START);
        running_intent = PendingIntent.getService(c, REQUEST_CODE, i, 0);
    }
    return running_intent;
}

private static void stopAlarm(Context c) {
    AlarmManager am = (AlarmManager) c.getSystemService(ALARM_SERVICE);
    am.cancel(getRunIntent(c));
}

/**
 * Stop this service, also stopping the alarm
 */
public static void stop(Context c) {
    stopAlarm(c);
    Intent i = new Intent(c, AppLockService.class);
    i.setAction(ACTION_STOP);
    c.startService(i);
}

/**
 * Re-initialize everything.<br>
 * This has only effect if the service was explicitly started using
 * {@link #start(Context)}
 */
public static void restart(Context c) {
    Intent i = new Intent(c, AppLockService.class);
    i.setAction(ACTION_RESTART);
    c.startService(i);
}

/**
 * Forces the service to stop and then start again. This means that if the
 * service was already stopped, it will just start
 */
public static void forceRestart(Context c) {
    Intent i = new Intent(c, AppLockService.class);
    i.setAction(ACTION_RESTART);
    i.putExtra(EXTRA_FORCE_RESTART, true);
    c.startService(i);
}

@Override
public void onDestroy() {
    super.onDestroy();
    Log.d(TAG, "onDestroy: (mAllowRestart=" + mAllowRestart + ")");
    if (mScreenReceiver != null)
        unregisterReceiver(mScreenReceiver);
    if (mShowNotification)
        stopForeground(true);

    if (mAllowRestart) {
        start(this);
        mAllowRestart = false;
        return;
    }

    Log.i(TAG, "onDestroy (mAllowDestroy=" + mAllowDestroy + ")");
    if (!mAllowDestroy) {
        Log.d(TAG, "Destroy not allowed, restarting service");
        start(this);
    } else {
        // Tell MainActivity we're stopping
        Intent i = new Intent(BROADCAST_SERVICE_STOPPED);
        i.addCategory(CATEGORY_STATE_EVENTS);
        sendBroadcast(i);
    }
    mAllowDestroy = false;
}

private void doStopSelf() {
    stopAlarm(this);
    mAllowDestroy = true;
    stopForeground(true);
    stopSelf();
}

private void doRestartSelf() {
    Log.d(TAG, "Setting allowrestart to true");
    mAllowRestart = true;
    stopSelf();
}
}

这是我的 Manifest.xml

 <uses-sdk
    android:minSdkVersion="15"
    android:targetSdkVersion="23" />

<supports-screens
    android:anyDensity="true"
    android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true" />

<uses-feature
    android:name="android.hardware.telephony"
    android:required="false" />
<uses-feature
    android:name="android.hardware.usb.accessory"
    android:required="false" />
<uses-feature
    android:name="android.hardware.usb.host"
    android:required="false" />
<uses-feature
    android:name="android.hardware.location"
    android:required="false" />
<uses-feature
    android:name="android.hardware.wifi"
    android:required="false" />

<!-- permissions -->
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

<application
    android:allowBackup="false"
    android:icon="@drawable/ic_launcher"
    android:label="@string/application_name"
    android:theme="@style/Theme.AppCompat"
    android:largeHeap="true"
    tools:node="replace">
    <activity
        android:name="com.appslocker.locker.ui.MainActivity"
        android:label="@string/application_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <action android:name="android.intent.action.SEARCH" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <service android:name="com.appslocker.locker.lock.AppLockService" />
    <service android:name="com.appslocker.locker.lock.LockService" />

    <receiver android:name="com.appslocker.locker.receivers.BootCompleteReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
            <action android:name="android.app.action.ACTION_DEVICE_ADMIN_DISABLE_REQUESTED" />
            <action android:name="android.app.action.ACTION_DEVICE_ADMIN_DISABLED" />
        </intent-filter>
    </receiver>
    <receiver
        android:name=".DeviceAdmenReciever"
        android:permission="android.permission.BIND_DEVICE_ADMIN">
        <meta-data
            android:name="android.app.device_admin"
            android:resource="@xml/device_admin" />

        <intent-filter>
            <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
            <action android:name="android.app.action.ACTION_DEVICE_ADMIN_DISABLE_REQUESTED" />
            <action android:name="android.app.action.ACTION_DEVICE_ADMIN_DISABLED" />
        </intent-filter>
    </receiver>

    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />

    <service
        android:name=".MyAccessibilityService"
        android:label="@string/accessibility_service_label"
        android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
        <intent-filter>
            <action android:name="android.accessibilityservice.AccessibilityService" />
        </intent-filter>

        <meta-data
            android:name="android.accessibilityservice"
            android:resource="@xml/accessibility_service_config" />
    </service>


</application>
4

1 回答 1

0

您的应用程序无法正常工作,因为在棒棒糖中,当您在设备中安装应用程序时,默认情况下,所有权限都将由 android 提供,但是从 Marshmallow 中,Google 添加了功能,当您安装任何应用程序时,如果它有任何权限,那么它会向用户询问权限,因此您应该在 Google 中搜索“android 中的运行时权限”,您将获得适用于您的应用程序的完美代码。

于 2017-10-18T07:54:26.390 回答