【问题标题】:Method returns same package name for all Google apps方法为所有 Google 应用返回相同的包名称
【发布时间】:2018-06-27 04:02:07
【问题描述】:

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

到目前为止我做了什么。

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 "";
    }

我正在关注this SO Answer,以获取 Lollipop 上方设备中的最高运行活动。我为此创建了后台服务。

我面临的问题:

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

在后台运行服务时。我正在为所有谷歌应用程序(地图,环聊)获得顶级包名称com.google.android.gsf。所以我很难识别特定的应用程序。

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

2. 正如一些 SO 帖子中提到的,getLollipopFGAppPackageName() 只能在调试时使用,不能用于实际实现。因此,如果我不使用它,那么在棒棒糖上方的设备中实现这种功能(锁定应用程序)的正确方法可能是什么。

任何帮助或指导都会很棒。谢谢

【问题讨论】:

    标签: android android-studio android-activity service


    【解决方案1】:

    我查看了您的代码,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();
    
                            });
    

    普通排序:

    Collections.sort(queryUsageStats, (usageStats1, usageStats2)
                            -> compareTo(usageStats2.getLastTimeUsed(), usageStats1.getLastTimeUsed()));
    
    Toast.makeText(ctx, queryUsageStats.get(0).getPackageName(), Toast.LENGTH_SHORT).show();
    

    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);
    


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

    1. 卸载应用程序:即使您的应用程序已通过设备管理员启用 用户,他们可以去设备管理员,禁用您的应用程序,卸载 它,或者更糟糕的是重新安装应用程序锁,为其设置新密码。如果 你不知道如何再次卸载它,你会被f_cked :3

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

    我以前写过一个应用锁,这些案例打破了我的梦想:),如果它可以解决你的问题,请将此答案标记为已接受。
    希望你能做出更好的锁应用功能,足够可靠,性能好。 :)

    【讨论】:

    • 感谢您的回答,但您的一些方法是 RxJava 的。因此,如果您将示例替换为 android native 。会很有帮助的
    • 这只是 getLastTimeUsed 的简单排序 desc :),如果您仍然需要我会更新我的答案,但也许稍后,现在我有点忙 :)
    • 在您方便时
    猜你喜欢
    • 2018-05-12
    • 2013-02-28
    • 1970-01-01
    • 1970-01-01
    • 2016-02-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-15
    相关资源
    最近更新 更多