Android 方法为所有Google应用程序返回相同的包名

Android 方法为所有Google应用程序返回相同的包名,android,android-studio,android-activity,service,Android,Android Studio,Android Activity,Service,我正在开发一个锁定应用程序,当用户打开任何应用程序时。我的应用程序将触发,如果它与我的阻止列表匹配,那么我将向用户显示锁屏 我到目前为止所做的一切 public static String getTopAppName(Context context) { ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

我正在开发一个锁定应用程序,当用户打开任何应用程序时。我的应用程序将触发,如果它与我的阻止列表匹配,那么我将向用户显示锁屏

我到目前为止所做的一切

public static String getTopAppName(Context context) {
            ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            String strName = "";
            try {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    strName = getLollipopFGAppPackageName(context);
    
    
                } else {
                    strName = mActivityManager.getRunningTasks(1).get(0).topActivity.getClassName();
                }}
        }

private static String getLollipopFGAppPackageName(Context ctx) {

        try {
            UsageStatsManager usageStatsManager = (UsageStatsManager) ctx.getSystemService("usagestats");
            long milliSecs = 60 * 1000;
            Date date = new Date();
            List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, date.getTime() - milliSecs, date.getTime());
            if (queryUsageStats.size() > 0) {
                Log.i("LPU", "queryUsageStats size: " + queryUsageStats.size());
            }
            long recentTime = 0;
            String recentPkg = "";
            for (int i = 0; i < queryUsageStats.size(); i++) {
                UsageStats stats = queryUsageStats.get(i);

                if (i == 0 && !"org.pervacio.pvadiag".equals(stats.getPackageName())) {
                    Log.i("LPU", "PackageName: " + stats.getPackageName() + " " + stats.getLastTimeStamp());
                }
                if (stats.getLastTimeStamp() > recentTime) {
                    recentTime = stats.getLastTimeStamp();
                    recentPkg = stats.getPackageName();
                }
            }
            return recentPkg;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
公共静态字符串getTopAppName(上下文){
ActivityManager mActivityManager=(ActivityManager)context.getSystemService(context.ACTIVITY_服务);
字符串strName=“”;
试一试{
if(Build.VERSION.SDK\u INT>=Build.VERSION\u code.LOLLIPOP){
strName=GetLollipofGappPackageName(上下文);
}否则{
strName=mActivityManager.getRunningTasks(1).get(0).topActivity.getClassName();
}}
}
私有静态字符串getLollipofGappPackageName(上下文ctx){
试一试{
UsageStatsManager UsageStatsManager=(UsageStatsManager)ctx.getSystemService(“usagestats”);
长毫秒=60*1000;
日期=新日期();
列出queryUsageStats=usagestastsmanager.queryUsageStats(usagestastsmanager.INTERVAL_DAILY,date.getTime()-millises,date.getTime());
if(queryUsageStats.size()>0){
Log.i(“LPU”,“queryUsageStats大小:”+queryUsageStats.size());
}
长最近时间=0;
字符串recentPkg=“”;
对于(int i=0;irecentTime){
recentTime=stats.getLastTimeStamp();
recentPkg=stats.getPackageName();
}
}
返回最近的包装;
}捕获(例外e){
e、 printStackTrace();
}
返回“”;
}
我下面是为了在棒棒糖上面的设备中获得顶级跑步活动。我已经为此创建了后台服务

我面临的问题:

1。当用户从我的应用程序中阻止任何应用程序时,我将获得该应用程序的软件包名称。例如(com.google.android.talk、com.google.android.apps.maps、com.android.chrome)

在后台运行服务时。我获得了所有谷歌应用程序(地图、闲逛)的顶级软件包名
com.google.android.gsf
。所以我很难识别特定的应用程序

我认为问题出在
getLollipopFGAppPackageName()
中,但我不知道是什么

2.如一些SO帖子所述,
getLollipopFGAppPackageName()
只能在调试时使用,不能用于实际实现。所以如果我不使用这个,那么在棒棒糖上面的设备中实现这种功能(锁应用程序)的正确方法是什么呢


任何帮助或指导都会很好。谢谢我查看了你的代码,queryUsageStats()方法返回的数组与活动堆栈的顺序不同,此列表的第一项不是最新打开的应用程序。您必须通过getLastTimeUsed手动重新排序此列表

按rxJava排序:

 List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, currentTime - milliSecs, currentTime);
                rx.Observable.from(queryUsageStats)
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .toSortedList((usageStats1, usageStats2) -> compareTo(usageStats2.getLastTimeUsed(), usageStats1.getLastTimeUsed()))
                        .subscribe(usageStats -> {
                            Toast.makeText(ctx, usageStats.get(0).getPackageName(), Toast.LENGTH_SHORT).show();

                        });


不要忘记:

// Declare USAGE_STATS permisssion in manifest

    <uses-permission
    android:name="android.permission.PACKAGE_USAGE_STATS"
    tools:ignore="ProtectedPermissions" />

//TODO: Check if user has already enabled Device Administrator, don't start this intent.
    Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
    startActivity(intent);
//在清单中声明用法\u统计权限
//TODO:检查用户是否已启用设备管理员,不要启动此意图。
意向意向=新意向(设置、操作、使用、访问、设置);
星触觉(意向);

更多信息:一个可以锁定其他应用程序的应用程序并不是100%可靠的,一些应用程序在Google Play上的下载量也不是100%。
通常,应用程序锁定的目标是当你想与其他用户(你的女朋友、男朋友、孩子等)共享你的设备,并且仍然保留你想要的某些特定应用程序的隐私时。
但也有一些情况可以打破应用程序锁定:

  • 卸载应用程序:即使您的应用程序已由设备管理员启用 用户,他们可以转到设备管理员,禁用您的应用程序,卸载 它,或者更糟糕的是,重新安装应用程序锁,为它设置新密码。如果 如果你不知道如何再次卸载它,你将被检查:3

  • 在该模式下打开超省电模式超耐力模式(至少在三星和索尼设备上如此) 只有一些最低限度的应用程序可以显示和运行(消息、电话) 调用…,所有应用程序锁在这种情况下完全无效 共享用户可以轻松阅读您的隐私短信。

  • 我以前写过一个应用程序锁,这些案例打破了我的梦想:),请将此答案标记为已接受,如果它可以解决您的问题。

    我希望你能制作一个更好的锁应用程序功能,足够可靠,性能良好。:)

    谢谢您的回答,但您的一些方法是RxJava。因此,如果您用android native替换您的示例。这将是非常有用的它只是简单的排序描述由getLastTimeUsed:),如果你仍然需要我会更新我的答案,但可能以后,现在我有点忙:)在你方便的时候
    private int compareTo(long a, long b) {
            return a == b ? 0 : (a > b ? 1 : -1);
        }
    
    // Declare USAGE_STATS permisssion in manifest
    
        <uses-permission
        android:name="android.permission.PACKAGE_USAGE_STATS"
        tools:ignore="ProtectedPermissions" />
    
    //TODO: Check if user has already enabled Device Administrator, don't start this intent.
        Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
        startActivity(intent);