9

appsバックグラウンド ジョブから、特定の時間間隔 (例: 5 分) にユーザーがアクセスしたリストを調べたいですか? これはルート化されていないandroid電話で可能ですか? 可能であれば、アンドロイドについての素晴らしい学習になるので、答えを知りたいと思っています。

4

2 に答える 2

7

アップデート:

Android 5.0 では、getRecentTasks() メソッドの代わりに getAppTasks があります。

コードサンプル:

private void listTasks() throws PackageManager.NameNotFoundException {
  ActivityManager mgr = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
  List<ActivityManager.AppTask>  tasks = mgr.getAppTasks();
  String packagename;
  String label;
  for (ActivityManager.AppTask task: tasks){
    packagename = task.getTaskInfo().baseIntent.getComponent().getPackageName();
    label = getPackageManager().getApplicationLabel(getPackageManager().getApplicationInfo(packagename, PackageManager.GET_META_DATA)).toString();
    Log.v(TAG,packagename + ":" + label);
  }
}

元の回答:

序章

ActivityManager クラスは、そのような情報を返す 2 つのメソッドを提供します。getRecentTasks または getRunningTasks メソッドを選択するのが適切でしょう。返されるタスク リストは目的ではないからです。ただし、目的のリストを決定する途中の参照ポイントとして使用されます。

コードサンプル:

ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<RecentTaskInfo> activitys = activityManager.getRecentTasks(Integer.MAX_VALUE, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
for (int i = 0; i < activitys.size(); i++) {
    RecentTaskInfo activity = activitys.get(i);
    activity.baseIntent.getComponent().getPackageName();
}

フィルタリング:このリストには、システム タスクを含むすべての種類のタスクが含まれます。

コードサンプル:

if (activity.baseIntent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) {
    // This is an application.
    getPackageManager()
        .getApplicationLabel(getPackageManager()
        .getApplicationInfo(activity.baseIntent.getComponent()
        .getPackageName(), PackageManager.GET_META_DATA)); // application name
}

これは、ホームボタンを長押ししたときに表示されるリストと同じです。

抽象的アプローチ: (説明は後ほど)

指定された時間内に目的のリストを決定するため (期間)。最近のタスク リストは、期間の開始時と、間隔と呼ばれる期間内のそれぞれの短い期間の後に要求されます。

最近のアプリ。最初の間隔の後に取得されたリストには、3 種類のアプリが含まれます。私たちの関心のない古いアプリ、新しく起動されたアプリ、再起動されたアプリ。抽象的なアプローチを選択する理由は、再起動されたアプリを検出するためです。

新しく起動されたアプリの検出:

それらはアプリです。最初に取得したリストには表示されませんでした。(期間前)。

このアプローチの理由を例で説明します。

  • あらゆるアプリを検討することをお勧めします。アプリの前に表示されました。後でフェッチされたリストで、再起動されたアプリ。アプリ内からの操作を開始したときから、あなたのアプリ。リストのトップでした。

ここに画像の説明を入力

  • しかし、あなたのアプリ。トップから降りて、インターバル時間内に戻ってくるかもしれません。(Facebook > Twitter > あなたのアプリ)。

ここに画像の説明を入力

  • 後でフェッチされたリストで、別のアプリ。上に乗るかもしれません。あなたのアプリと同じ理由で、それを参考にすることも失敗します。参考にはなりませんでした。

勝利へのアプローチ:

間隔の前に取得されたリストは、間隔の後に取得されたリストの参照になります。再起動されたアプリ。アプリになります。1 番目のサブリスト (fosl) の前に表示されます。

ここに画像の説明を入力

すべてのアプリ。fosl が再起動される前に、What's app だけではありません。と、 簡単に証明できます。fosl を変更せずに一部のアプリを再起動できるように、fosl の上にアプリを再配置する方法はありません (より多くのアプリを含めるために大きくなります)。あなたはそれを行使することができます。

ユーザーが一部のアプリを削除した場合でも、fosl アプローチは機能します。間隔内でリストから手動で。以前の間隔で検出されなかった場合、削除されたアプリのみが検出されません。ただし、リスト内の残りの fosl アプローチには影響しません。ユーザーがすべてのリストをクリアした場合も同じで、クリアしたアプリのみです。検出されず、同じ間隔内で後に起動されたものではありません。

なぜインターバル?これは、ユーザーがアプリを開いて再起動できる期間が長いためです。次に、リストをクリアするか、一部を削除します。

間隔が狭いと、ユーザーが同じ順序でトップ サブリストを再度開くのが非常に難しくなります。これが fosl アプローチの唯一の弱点です。

サンプルコード: (fosl)

public int getIndexOfFirstAppBeforeFOSL(ArrayList<App> recentApps) {
    int i=previousRecentApps.size()-1, j = recentApps.size()-1;
    for (; i>=0 && j>=0 ; i--) {
        App app = previousRecentApps.get(i);
        if (app.equals(recentApps.get(j))) {
            j--;
        } else {
            // this application got re-launched and therefore it changed it place in list.
            // or removed manually by user.
        }
    }

    return j;
}

アプリケーション用のGitHub プロジェクトを作成しました。それをチェックして、もしあればバグを報告してください。

私たちが言及した弱点のために 1 つまたは 2 つのアプリを検出できないと、アプリの収集から得られる調査結果に実際に影響を与えます。多数のユーザーからのローンチ。とにかくあなたは何をしているのなら。それ以外の場合は、アプリ。新しくローンチされたアプリを頻繁に入手できます。そしてそれをユーザーに通知します。

于 2014-12-11T01:00:58.273 に答える