개요
사용자가 모바일에서 다른 어떤 앱을 얼마나 자주 사용하는지 모니터하는 서비스
여기서 제공하는 API를 사용하면,
- 최근 실행된 앱이 무엇인지, 사용시간은 각각 얼마인지 알 수 있음 (UsageStatsManager)
- 기간별 앱들의 네트워크 사용량을 알 수 있음 (NetwordStatsManager)
- 앱들의 저장공간을 알 수 있음 (StorageStatsManager)
권한
다른 앱들의 사용기록 정보를 얻기 위한 권한 PACKAGE_USAGE_STATS 필요함 (직접 요청 O)
<?xml version="1.0" encoding="utf-8"?>
<manifest>
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />
</manifest>
1. UsageStatsManager
- 앱 사용기록을 Query 할 수 있는 API를 제공
- 조회하고자 하는 기간을 설정 (ex. 2020.04.01 - 2021.04.01)
- 시간 단위(Interval) 설정 (ex. days, weeks, months, years로 구분된 결과 받을 수 있음)
// 1년 전부터 현재까지 사용한 모든 앱들의 사용기록을 한달 단위로 조회
private fun getAppUsageStats(): MutableList<UsageStats> = run {
val calendar = Calendar.getInstance()
calendar.add(Calendar.YEAR, -1) // 날짜설정(1년 전으로)
val usageStatsManager = requireContext().getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
// 사용기록 조회
usageStatsManager.queryUsageStats(
UsageStatsManager.INTERVAL_MONTHLY, // 한달 단위로
calendar.timeInMillis, // 1년 전부터
System.currentTimeMillis() // 현재까지
)
}
- Query 결과로는 전체 앱들의 사용기록
List<UsageStats>
반환
UsageStats
에는 패키지 이름, 마지막 사용 시간, 전체 실행 시간 등의 정보를 얻을 수 있음
UsageStats |
|
getPackageName |
패키지 이름 |
getLastTimeUsed |
마지막 사용 시간 |
getTotalTimeInForeground |
전체 실행 시간 |
특이사항
- 반환된 앱의 패키지 이름(ex. com.lee.oneweekonebook)을 앱의 이름(ex. 일주일책)으로 변환하여 사용자에게 보여줘야 함
- 삭제한 앱의 사용내역도 가져옴
- 조회결과 겹치는 days, weeks, months, years가 있으므로 한번 더 grouping 필요함
시간단위(Interval)에 따른 결과의 개수
시간단위 |
설명 |
INTERVAL_DAILY |
앱 사용했던 날 중 최근 몇 개만(최대 10개) 가져옴 |
INTERVAL_WEEKLY |
최근 4주의 데이터만 가져옴 |
NTERVAL_MONTHLY |
최근 6달의 데이터만 가져옴 |
INTERVAL_YEARLY |
연도별로 가져옴 |
2. NetworkStatsManager
- 앱 네트워크 사용기록을 Query 할 수 있는 API를 제공
- 조회하고자 하는 기간을 설정 (ex. 2020.04.01 - 2021.04.01)
- 네트워크 상태(와이파이와 모바일 데이터)에 따른 사용 결과를 받을 수 있음
- 전체 또는 특정 앱(uid) 조회
private fun getNetworkUsageStats(uid: Int) {
val calendar = Calendar.getInstance()
calendar.add(Calendar.YEAR, -1) // 날짜설정(1년 전으로)
val networkStatsManager = requireContext().getSystemService(Context.NETWORK_STATS_SERVICE) as NetworkStatsManager
// 해당 앱(uid)에 대한 네트워크 기록 조회
val networkWifiStats: NetworkStats = networkStatsManager.queryDetailsForUid(
NetworkCapabilities.TRANSPORT_WIFI, // Wifi에 사용된 데이터 조회(모바일 데이터 조회 시 - TRANSPORT_CELLULAR)
null,
calendar.timeInMillis, // 1년 전부터
System.currentTimeMillis(), // 현재까지
uid
)
}
- Query 결과인
NetworkStats
는 NetworkStats.Bucket()
을 통해 조회
var totalWifiNetwork = 0L
val bucketWifi = NetworkStats.Bucket()
while (networkWifiStats.hasNextBucket()) {
networkWifiStats.getNextBucket(bucketWifi)
totalWifiNetwork += bucketWifi.rxBytes + bucketWifi.txBytes
}
- NetworkStats.Bucket() 에는 주고 받은 bytes의 개수, 마지막 사용 시간 등의 정보를 얻을 수 있음
NetworkStats.Bucket() |
|
getRxBytes |
받은 bytes의 개수 (TCP와 UDP 사용량 포함) |
getTxBytes |
보낸 bytes의 개수 (TCP와 UDP 사용량 포함) |
getEndTimeStamp |
마지막 사용 시간 |
특이사항
- 와이파이와 모바일 데이터 네트워크 사용량 따로 조회해야함
- 네트워크 사용량 조회 시 전체 혹은 특정 앱(uid)을 조회할 수 있음
- 전체를 조회하면 각 앱에 대한 uid와 함께 네트워크 사용량이 반환되는데, 사용자에게 보여줄 시
packageManager
를 통해 uid를 앱 이름으로 변환해야함
3. StorageStatsManager
- 앱 저장공간을 Query 할 수 있는 API를 제공
- 전체 또는 특정 앱(packageName 이나 uid) 조회
private fun getStorageUsageStats(packageName: String) {
val storageStatsManager = requireContext().getSystemService(Context.STORAGE_STATS_SERVICE) as StorageStatsManager
val storageManager = requireContext().getSystemService(Context.STORAGE_SERVICE) as StorageManager
val storageVolumes = storageManager.storageVolumes
storageVolumes.map {
val uuid = it.uuid?.let { uuid ->
UUID.fromString(uuid)
} ?: StorageManager.UUID_DEFAULT
try {
// 패키지 이름으로 저장공간 조회
val result = storageStatsManager.queryStatsForPackage(uuid, packageName, android.os.Process.myUserHandle())
result.appBytes
result.dataBytes
result.cacheBytes
} catch (e: Exception) {
Logger.d(e.message)
}
}
}
- Query 결과인
StorageStats
앱의 크기, 데이터 사용공간, 캐시 사용공간 등의 정보를 얻을 수 있음
StorageStats |
|
getAppBytes |
앱의 크기 / APK files, optimized compiler output, and unpacked native libraries |
getDataBytes |
데이터 사용공간 / getDataDir(), getCacheDir(), getCodeCacheDir() |
getCacheBytes |
캐시 사용공간 / getCacheDir() and getCodeCacheDir() |
특이사항
- sdkVersion 26 이상부터 StorageStatsManager 사용 가능
- 사용공간 중 데이터만의 크기를 알기 위해서는 데이터 사용공간 에서 캐시의 사용공간을 빼줘야함
참고
API 공식 문서