26

バックグラウンド

私のアプリでは、最近起動された時間でアプリ リストを並べ替えることができます。

問題

Android "L" の時点で、関数getRecentTasksは、ドキュメントに記載されているように、現在のアプリが起動したアプリのリストを返すだけです:

アプリで ActivityManager.getRecentTasks() を使用している場合...

今後のリリースでの新しい同時ドキュメントおよびアクティビティ タスク機能の導入により (以下の [最近使用した画面での同時ドキュメントおよびアクティビティ] を参照)、ActivityManager.getRecentTasks() メソッドは、ユーザーのプライバシーを改善するために非推奨になりました。下位互換性のために、このメソッドは、呼び出し元のアプリケーション自体のタスクと、場合によってはその他の非機密タスク (ホームなど) を含む、データの小さなサブセットを返します。アプリがこのメソッドを使用して独自のタスクを取得している場合は、代わりに android.app.ActivityManager.getAppTasks() を使用してその情報を取得します。

ADT を使用してこの関数のドキュメントを表示する場合も同じことが書かれています (現在インターネットでは利用できません)。

このメソッドは非推奨です。L の時点で、このメソッドはサードパーティのアプリケーションでは使用できなくなりました。ドキュメント中心の最近の機能の導入により、呼び出し元に個人情報が漏洩する可能性があるためです。下位互換性のために、データの小さなサブセットを返します。少なくとも呼び出し元自身のタスク (ただし、その情報を取得するためにサポートされている正しい方法については getAppTasks() を参照してください)。敏感にならないでください。

ユーザーがどのアプリを持っているかを簡単に確認でき、許可がなくても簡単に確認できるため、なぜこの行為が行われたのかわかりません。

これは私が追加したこの機能の大きな制限なので、これを克服する方法があることを願っています.

私が試したこと

今のところ、最近起動されたアプリについてのヒューリスティックな方法のみを使用しました。代わりに、実行中のプロセスのリストを取得します。

プロセスの重要度の値とおそらく「importanceReasonComponent」を使用することもできますが、これはすべてヒューリスティックと推測にすぎません...

質問

この制限を克服する方法はありますか? 私が考えていない回避策はありますか?

多分それはルートで可能ですか?またはビジーボックス?

4

4 に答える 4

38

現在実行中のトップ (フォアグラウンド) パッケージ名を取得するには、Android Lollipop で Usage Stats API を使用する必要があります。

ただし、ユーザーは各アプリケーションの設定で使用状況データへのアクセスを承認する必要があることに注意してください。したがって、次のコマンドで設定アクションを起動して、ユーザーに直接設定を求める必要があります。

Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);

最上位のパッケージ名を取得するには:

String topPackageName ;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
    UsageStatsManager mUsageStatsManager = (UsageStatsManager)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*10, time);                                    
    // Sort the stats by the last time used
    if(stats != null) {
        SortedMap<Long,UsageStats> mySortedMap = new TreeMap<Long,UsageStats>();
        for (UsageStats usageStats : stats) {
            mySortedMap.put(usageStats.getLastTimeUsed(),usageStats);
        }                    
        if(!mySortedMap.isEmpty()) {
            topPackageName =  mySortedMap.get(mySortedMap.lastKey()).getPackageName();                                   
        }                                       
    }
}
于 2014-11-12T11:07:03.080 に答える
9

UsageStats を使用して現在のフォアグラウンド パッケージを取得すると、ユーザーが通知ドロワーを開いたとき、またはロックされた画面で間違った情報が取得されます。(Android Lollipop と Marshmallow の両方でテスト済み)

現在のフォアグラウンド パッケージを決定するには、UsageStatsManager.queryEvents() を使用し、MOVE_TO_FOREGROUND イベント タイプで最新のイベントを探す必要があります。

于 2016-04-29T14:53:51.403 に答える
2

@ user3742392の回答は良いですが、TreeMapを使用して最後に使用した時間を見つけるのは少しやり過ぎです(特に、実行中のトップアプリを定期的にチェックしたい場合)。

代わりに単純なループを使用して TreeMap を使用せずに編集した回答を次に示します。

String topPackageName;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    UsageStatsManager mUsageStatsManager = (UsageStatsManager) getSystemService("usagestats");
    long currentTime = System.currentTimeMillis();
    // get usage stats for the last 10 seconds
    List<UsageStats> stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, currentTime - 1000 * 10, currentTime);
    // search for app with most recent last used time
    if (stats != null) {
        long lastUsedAppTime = 0;
        for (UsageStats usageStats : stats) {
            if (usageStats.getLastTimeUsed() > lastUsedAppTime) {
                topPackageName = usageStats.getPackageName();
                lastUsedAppTime = usageStats.getLastTimeUsed();
            }
        }
    }
}
于 2015-11-06T14:27:52.133 に答える
1

Lollipop はこのメソッドを廃止しました。ただし、アプリの使用状況を表示できる新しい API があります。セキュリティ上の問題により、このメソッドは非推奨になりました。:\

UsageStatsManager には、時間間隔の間のアクティビティを確認するための便利なメソッドがいくつかあります。これがあなたのニーズに十分であることを願っています!

https://developer.android.com/reference/android/app/usage/package-summary.html

于 2014-10-27T01:09:12.693 に答える