1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

UsageStatsManagerからアプリ使用履歴を取得する.

Last updated at Posted at 2022-11-15

UsageStatsManagerからアプリの使用履歴を取得します.

まえがき

私は,研究でユーザのアプリ使用履歴を取得し,解析を行っています.

目標は,スマートフォン側でアプリ使用履歴を取得し,このデータを蓄積させることです.

UsageStatsManagerは,細かい使用履歴を取ろうとすると,10日分ほどしか取得することができませんでした(頑張ればもっと取れるのかも…).
そこで,一日に一度,バックグラウンドでその日一日分の使用履歴を取得し,アプリ内データにテキストファイルとして保存するようなアプリを作成します.こうすることで,何もしなくても使用履歴データが毎日取得できるわけです.

手順をまとめると

  1. UsageStatsManagerからアプリの使用履歴を取得する.
  2. テキストファイルとしてローカルに保存する.
  3. WorkMangerを使って一日に一度データを取得できるようにする.

と言った具合です.

本記事では,1.のUsageStatsManagerからアプリの資料履歴を取得するという部分についてまとめます.

権限の取得

UsageStatsManagerを取得するには,ユーザからのアクセス許可が必要です.
ここでは,アクティビティが起動した際に,権限の有無を確認し,権限がない場合にそれを催促します.

権限の有無の確認

Android Q以降とその前で確認方法が異なりますので,それに対応できるように実装します.
自分はMainActivity内にチェック用の関数を用意しました.

MainActivity.kt
    private fun checkUsageStatsPermission(): Boolean{

        val appOpsManager = getSystemService(APP_OPS_SERVICE) as AppOpsManager
        val mode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
            //Q以降の場合のチェック
            appOpsManager.unsafeCheckOpNoThrow("android:get_usage_stats", Process.myUid(), packageName)
        }else {
            //Q以前の場合のチェック
            appOpsManager.checkOpNoThrow("android:get_usage_stats", Process.myUid(), packageName)
        }
        return mode == AppOpsManager.MODE_ALLOWED

    }

権限の取得

権限を持っていない場合は,権限をユーザから与えてもらいます.
自分は権限がない場合,権限を付加を促すためのスクリーンを作りました.

インテントを使って,権限付与画面に遷移させます.
Activity(context)が必要になるため,LocalContext.current as Activity を使って@Composable内でActivityを取得します.

PermissionDemandScreen.kt
@Composable
fun PermissionDemandScreen(
    transitionMain: () -> Unit,
    modifier: Modifier = Modifier
) {
    //アクティビティを取得する
    val activity = LocalContext.current as Activity

    Column(
            ...
    ) {
        ...
        Button(
            onClick = {
                requestPermission(activity)
                transitionMain()
                      }
        ) {
            Text(text = "設定を開く")
        }
    }
}


private fun requestPermission(activity: Activity){
    activity.startActivity(Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS))
}

UsageStatsManagerの取得部分を作る

UsageStatsManagerを取得する部分を作ります.
取得したい形式によって,各々変えてもらいたいですが,私はList<UsageStats>を返す関数を作成しています.

UsageStatsManagerを取得するために,引数にはcontext: Contextを設定しています.

getUsageStatsでUsageStatsManagerを取得しています.
カレンダーのインスタンスを作り,cal.add()の部分で取得する期間が指定できます.
Calender.add()について詳しくはこちら

本稿では,30日前までを追加しています.

context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManagerこの部分でUsageStatsManagerを取得します.

return usageStatsManager.queryUsageStats(
            UsageStatsManager.INTERVAL_DAILY,
            cal.timeInMillis,
            System.currentTimeMillis()
        )

こちらの部分で,最終的にList<UsageStats>を返しています.

INTERVAL_DAILYの部分を変えることでクエリの間隔を変えることができます.
cal.timeInMillinsはUsageStatsを取得する開始時間です.
System.currentTimeMillis()はUsageStatsを取得する最終時間です.コードでは現在時刻としています.

↓コード全体

GetUsageStats.kt
private const val TAG = "GetUsageStats"

class GetUsageStats(
    private val context: Context
    ) {

    fun getUsageStats(): List<UsageStats>{
        Log.i(TAG,"Accessed GetUsageStatsClass")
        return sortedUsageStats( getAppUsageStats())
    }

    private fun getAppUsageStats(): MutableList<UsageStats> {
        val cal = Calendar.getInstance()
        cal.add(Calendar.DAY_OF_YEAR, -30)

        // usageStatsManagerのオブジェクトの取得
        val usageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager

        return usageStatsManager.queryUsageStats(
            UsageStatsManager.INTERVAL_DAILY,
            cal.timeInMillis,
            System.currentTimeMillis()
        )
    }

    private fun sortedUsageStats(usageStats: MutableList<UsageStats>): List<UsageStats> {
        usageStats.sortWith(
            compareBy { it.lastTimeUsed }
        )
        return usageStats
    }
}

余談ですが,sortedUsageStatsの部分で使用時間順にソートしています.

どこかで取得する.

MainActivityなどで,GetUsageのインスタンスを作成し,getUsageStats()を呼び出すことでList<UsageStats>が取得できます.

まとまったコードは https://github.com/M0710Fa/AccumulateUsage にあります.

参考

[1] Android Developers, UsageStatsManager, https://developer.android.com/reference/android/app/usage/UsageStatsManager (2022/10/13参照)
[2] codechacha.com, アンドロイド - UsageStatsManagerでアプリ履歴を取得する, https://codechacha.com/ja/android-app-usage-stats/ (2022/10/13参照)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?