我必须为 Android 开发一个应用程序储物柜,用户可以在其中阻止应用程序,而其他用户在没有访问密钥的情况下无法访问这些应用程序。
我已经安装了一个应用程序,但我不知道如何锁定这个应用程序。
请给我一些建议。
我必须为 Android 开发一个应用程序储物柜,用户可以在其中阻止应用程序,而其他用户在没有访问密钥的情况下无法访问这些应用程序。
我已经安装了一个应用程序,但我不知道如何锁定这个应用程序。
请给我一些建议。
这不是堆栈溢出的工作方式。甚至不尝试任何事情都无法提出完整的解决方案。
对于您的应用程序的最基本版本,您需要执行三个功能。
获取设备上所有已安装应用程序的列表,并在带有复选框的 ListView 中显示它们。如果用户检查任何应用程序,请将应用程序添加到不同的列表中,例如 BlockedAppsList(这将是用户想要阻止的应用程序列表)。您可以使用以下代码安装所有应用程序:
final PackageManager pm = getPackageManager();
//get a list of installed apps.
List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo packageInfo : packages) {
Log.d(TAG, "Installed package :" + packageInfo.packageName);
Log.d(TAG, "Source dir : " + packageInfo.sourceDir);
Log.d(TAG, "Launch Activity :" + pm.getLaunchIntentForPackage(packageInfo.packageName));
}
检查哪个是当前打开的应用程序。您可以使用以下代码进行检查:
ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List l = am.getRecentTasks(1, ActivityManager.RECENT_WITH_EXCLUDED);
Iterator i = l.iterator();
PackageManager pm = this.getPackageManager();
while (i.hasNext()) {
ActivityManager.RunningAppProcessInfo info = (ActivityManager.RunningAppProcessInfo)(i.next());
try {
CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(
info.processName, PackageManager.GET_META_DATA));
Log.w("LABEL", c.toString());
} catch (Exception e) {
// Name Not FOund Exception
}
}
现在检查当前应用程序是否存在于 BlockedAppsList 中,如果存在,您可以显示任何带有阻止消息的屏幕。
祝你好运!
假设您将锁定应用程序的包名称存储在名为:
锁
你想调用一个名为的活动
密码活动
当用户启动锁定的应用程序时,您可以实现如下轮询机制:
public class CheckAppLaunchThread extends Thread {
private Context context;
private Handler handler;
private ActivityManager actMan;
private int timer = 100;
public static final String TAG = "App Thread";
public static String lastUnlocked;
// private String lastUnlocked;
public CheckAppLaunchThread(Handler mainHandler, Context context) {
this.context = context;
this.handler = mainHandler;
actMan = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
this.setPriority(MAX_PRIORITY);
}
@Override
public void run() {
context.startService(new Intent(context, AppLockService.class));
Looper.prepare();
String prevTasks;
String recentTasks = "";
prevTasks = recentTasks;
Log.d("Thread", "Inside Thread");
while (true) {
try {
String topPackageName = "";
if(Build.VERSION.SDK_INT >= 21) {
UsageStatsManager mUsageStatsManager = (UsageStatsManager) context.getSystemService("usagestats");
long time = System.currentTimeMillis();
// We get usage stats for the last 10 seconds
List<UsageStats> stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000*5, time);
if(stats != null) {
SortedMap<Long,UsageStats> mySortedMap = new TreeMap<Long,UsageStats>();
for (UsageStats usageStats : stats) {
mySortedMap.put(usageStats.getLastTimeUsed(),usageStats);
}
if(mySortedMap != null && !mySortedMap.isEmpty()) {
topPackageName = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
}
}
}
else {
topPackageName = actMan.getRunningAppProcesses().get(0).processName;
}
recentTasks = topPackageName;
Thread.sleep(timer);
if (recentTasks.length()==0 || recentTasks.equals(
prevTasks)) {
} else {
if (isAppLocked(recentTasks)) {
Log.d(TAG, "Locked " + recentTasks);
handler.post(new RequestPassword(context, recentTasks));
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
prevTasks = recentTasks;
}
}
class ToastRunnable implements Runnable {
String message;
public ToastRunnable(String text) {
message = text;
}
@Override
public void run() {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
}
class RequestPassword implements Runnable {
private Context mContext;
private String pkgName;
public RequestPassword(Context mContext, String pkgName) {
this.mContext = mContext;
this.pkgName = pkgName;
}
@Override
public void run() {
Intent passwordAct = new Intent(context, PasswordActivity.class);
passwordAct.putExtra("PACKAGE_NAME", pkgName);
passwordAct.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_SINGLE_TOP);
this.mContext.startActivity(passwordAct);
}
}
private boolean isAppLocked(String packageName) {
if (packageName.equals(PasswordActivity.lastUnlocked)) {
return false;
}
PasswordActivity.lastUnlocked = null;
DatabaseHelper dbHelper = new DatabaseHelper(context);
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM locks WHERE package_name=\'"
+ packageName + "\'", null);
boolean isLocked = false;
if (cursor.moveToNext()) {
isLocked = true;
}
cursor.close();
db.close();
dbHelper.close();
return isLocked;
}
}
现在您必须从您的服务中调用上述代码,如下所示:
@Override
public void onCreate() {
handler = new Handler(getMainLooper());
context = getApplicationContext();
launchChecker = new CheckAppLaunchThread(handler, context);
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
while (true) {
if (!launchChecker.isAlive())
launchChecker.start();
return START_STICKY;
}
}
警告:自Oreo以来,谷歌限制了后台服务,你必须想办法让你的服务始终保持活跃。(这不是这个问题的范围)关于这个的线索,考虑调度一个 JobService 和一个广播接收器,当 android 杀死它时会重新调度你的服务。