UsageStatisManager 사용

오래 뒀다(?)IUsageStats는 Lolipop(API21)을 통해 진화되었습니다.
[Android] getRunningTasks를 사용할 수 없는 Lolipop을 통해 응용 프로그램 사용 상황을 가져옵니다.
이 보도를 보고서야 비로소 알아차렸다.
이전의 사용법과 앞으로의 사용법 등 자신이 사용한 것을 기록하다.

IUsageStats란 무엇입니까?


프로그램 설정에 화면이 있어요.


아마이것은 x시스템에서 구현된 것으로 응용 프로그램의 사용 기록을 가져오는 데 사용되는 API입니다.
원래 설정 프로그램에 화면UsageStats이 하나 있는데 그 안에 사용된다.
Activity Manager와 같은 OS 화면 및 어플리케이션 관리의 기본 부분에 설치되어 있기 때문입니다.
상당히 중요하고 편리한 구조입니다.
그러나 실제 접근 가능한 화면이 없어 일반 사용자는 사용할 수 없다.

그런 인상입니다.

실현이 간단하다


구조 설치는 보기에 매우 간단합니다./data/system/usagestats에서 xml 형식입니까?... 을 누르다
Activity ManagerActivityManagerService를 통과할 때의 요점 등을 기록했다.
실제 상황은UsageStatsService.
제대로 따라잡지 못했지만 재가동을 하거나 어느 시간대에 이력이 사라졌죠.

시스템 권한이 없으면 사용할 수 없습니다.


무엇보다 System 권한이 없으면 이 API를 사용할 수 없습니다!
일반적으로 개발자는 AOSP를 직접 구축하고 시스템 권한이 있는 애플리케이션을 만들 때만 API를 사용할 수 있습니다.@hide는 퍼스널 검사에서 system Orsignature이기 때문에 맞춤형 OS, 제조사, 운영자가 사용하는 기능이라고 할 수 있다.
그리고 표준 운영체제에서는 프로그램을 설정하는 화면에서 찾을 수 없습니다.
그래서 이용할 기회와 존재를 의식할 기회가 거의 없다.

취득 방법과 취득한 내용


방법의 집행은 시스템 응용이 필요하다
getSystemService()를 사용하면 참조할 수 있습니다.
다른 System Service와 달리 Manager 클래스가 없으므로 트래픽 처리를 위한 stub?직접 참조가 필요합니다.
Service Manager의 반사 효과는 이 블로그를 참조하십시오.
시스템 서비스의 로컬 인터페이스 가져오기
Test.java
        // ActivityManagerServiceからはこんな風に呼ばれていました。
        mUsageStatsService = IUsageStats.Stub.asInterface(ServiceManager.getService("usagestats"));

        // リフレクションではこう呼んだり。。ServiceLocatorは上記ブログ参照。。
        mUsageStatsService = ServiceLocator.getServiceStub("usagestats",
                "com.android.internal.app.IUsageStats$Stub");

        // 関数のコールもリフレクション。。
        Class<?> clazz = Class.fromName("com.android.internal.app.IUsageStats$Stub");
        Method method = clazz.getDeclaredMethod("getAllPkgUsageStats");
        method.setAccessible(true);
        PkgUsageStats[] result = (PkgUsageStats[]) method.invoke(mUsageStatsService);
getAllPkgUsageStats와 getPkgUsageStats 등을 통해 다음 단계를 얻었습니다.
애플리케이션의 부팅 횟수와 총 부팅 시간(수면 시간 제외), 각 Activity의 부팅 시간은?네.
android.internal.os.PkgUsageStats.java

/**
 * implementation of PkgUsageStats associated with an
 * application package.
 *  @hide
 */
public class PkgUsageStats implements Parcelable {
    public String packageName;
    public int launchCount;
    public long usageTime;
    public Map<String, Long> componentResumeTimes;

    public PkgUsageStats(String pkgName, int count, long time, Map<String, Long> lastResumeTimes) {
        packageName = pkgName;
        launchCount = count;
        usageTime = time;
        componentResumeTimes = new HashMap<String, Long>(lastResumeTimes);
    }

    // Parcelableの実装があります。。
}

UsageStatisManager가 공개되었습니다.


오랜만에 IUsage Stats를 검색해 보니 예전com.android.internal.app 이하였다
Usage와 관련된 반이 없어졌어요.
대신 새로운android.app.usage 포장이 나왔다.정말 대단한 승진이군!
UsageStatsManager | Android Developers
여기서부터는 처음 보도와 같다.
신규 android.permission.PACKAGE_USAGE_STATSAndroidManifest.xml로 이것을 요구합니다
코뿔소
설정 프로그램セキュリティ→使用履歴にアクセスできるアプリ에서 허가를 받으면 받을 수 있습니다.

UsageStatsManager


자세한 내용은 References를 보시면 알 수 있습니다.
이전에 설치한 것이 아니라 일부 DB로 관리한 것 같습니다.
모든 가져오는 방법으로 start와stop의 시간 스탬프를 지정합니다.
합계는 intervalType으로 일 단위 또는 주 단위를 지정할 수 있습니다.

UsageEvents.Event


UsageEvents.Event | Android Developers
UsageEvents.시작MOVE_TO_FOREGROUND과 끝MOVE_TO_BACKGROUND을 이벤트 단위로 저장합니다.
그 외에 CONFIGURATION_CHANGE도 있다.
UsageEvents 이벤트 목록을 저장합니다.
// クラス名
getClassName()
// パッケージ名
getPackageName()
// イベントのタイムスタンプ
getTimeStamp()
// イベントのタイプ. MOVE_TO_FOREGROUND/MOVE_TO_BACKGROUND/CONFIGURATION_CHANGE/NONE
getEventType()
// Configuration. イベントタイプがCONFIGURATION_CHANGEのときのみ返す
getConfiguration()
ComponentName (클래스 이름과 패키지 이름) 과 시간 스탬프를 얻을 수 있습니다.
사소한 응용 변환 운동 등UsageStatsManager.queryEvents에서 이벤트 리스트를 얻는 것이 좋을 것 같다.

ConfigurationStats


ConfigurationStats | Android Developers
Configuration Station은 아마도 Event의 Type이 CONZIGURATION일 것입니다.CHANGE를 집계한 것 같습니다.
언제 행사가 일어났는지 그다지 조사하지 않다.
// 集計期間の開始時刻
getFirstTimeStamp()
// 集計期間の終了時刻
getLastTimeStamp()
// 最後に実行された時刻
getLastTimeActive()
// 期間内に実行された回数
getActivationCount()
// 期間内に実行された合計時間
getTotalTimeActive()
// Configuration
getConfiguration()
UsageStatsManager.queryConfigurations 지정된 단위로 누적된 목록을 얻을 수 있습니다.

UsageStats


UsageStats | Android Developers
UsageStats는 이전 PkgUsageStats의 대체품으로 기본적으로 UsageEvents의 합계이다.
// 集計期間の開始時刻
getFirstTimeStamp()
// 集計期間の終了時刻
getLastTimeStamp()
// 最後に実行された時刻
getLastTimeUsed()
// 期間内に全面で実行された合計時間
getTotalTimeInForeground()
// パッケージ名
getPackageName()
UsageStatsManager.queryUsageStats 지정된 단위로 누적된 목록을 얻을 수 있습니다.
또한 UsageStatsManager. queryAndAggregateUsageStats에서 INTERVALBEST 단위와 애플리케이션 패키지 이름을 합한 지도를 얻을 수 있다.
INTERVAL_BEST는 취득 시 지정된 기간에 따라 자동으로 판별할 수 있다고 생각합니다.
맵을 만들 때 중복되지 않도록 패키지 하나가 한 번만 나오는 인터페이스로 동적으로 변경됩니다.

주의점


Permission을 획득하는 게 제일 주의할 것 같아요.
자신이 사용한 후 겪는 주의사항을 기록해 두세요.

UsageStats.getLastTime Stamp 은 때때로 뭉칠 수 있다


자신이 시도할 때queryUsageStation이 Interval을 지정하는 기간보다 조금 길었을 때UsageStats.getLastTimeStamp가 반올림한 값을 돌려주기도 한다.

// 期間が1日なのに、intervalTypeを年単位にしてしまった
int intervalType = UsageStatsManager.INTERVAL_YEARLY;
long start = System.currentTimeMillis() - 24 * 60 * 60 * 1000;
long end = System.currentTimeMillis();

// ついてませんが、@Nullableです
List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats(intervalType, start, end);

:
usageStatsList.get(0).getLastTimeStamp();
// 1430907218507
// firstTimeStampは大丈夫
usageStatsList.get(0).getFirstTimeStamp();
// 2295981492
// 変に丸められてる?
usageStatsList.get(1).getLastTimeStamp();
// 1430907218507
usageStatsList.get(1).getFirstTimeStamp();
// 999981492
// 変に丸められてる?
usageStatsList.get(2).getLastTimeStamp();
// 1430907218507
usageStatsList.get(2).getFirstTimeStamp();
// 1433218181823
// 大丈夫なときもある
:

정수나 통계에 대해 잘 모르기 때문에 일반적인 일일 수도 있지만 주의를 기울이는 것이 좋다.

UsageStats.getFirstTimeStamp이 JST라면 9시 기준입니다.


UsageStats를 가져오면 지정된 기간 전에 응용 프로그램 활동이 시작되면 잘라내어 집계됩니다.
합계 최소 INTERVAL데이리입니다.
그때부터 머리를 자르기 시작한 시간은 9시 JST였습니다.
즉, GMT(또는 UTC)에 표시됩니다.
차트나 테이블에 같은 대상 단위를 표시할 수 없으면 UsageEvents입니다.자신이 이벤트 합계를 따는 게 좋을 것 같은데...

PkgUsageStats와 같은 launchCount 등은 없습니다.


이전 비공개 API PkgUsageStats와 UsageStats는 모두 지원됩니다.
하지만 전부가 아니야..
// パッケージ名
PkgUsageStats.packageName -> UsageStats.getPackageName()
// 期間内の合計利用時間
PkgUsageStats.usageTime -> UsageStats.getTotalTimeInForeground()
// 期間内の起動回数
PkgUsageStats.launchCount -> なし
// 期間内のActivityごとの起動回数
PkgUsageStats.componentResumeTimes -> なし
launchCount 등을 사용해야 하는 경우 Usage Events 등을 집계해야 합니다.

최신 역사 기록을 얻는 것은 보장되지 않는다.


UsageStatsManager.query Events 참조에는 주석이 있습니다.
text
NOTE: The last few minutes of the event log will be truncated to prevent abuse by applications.
// 注:イベントログの最後の数分間は、アプリケーションによって濫用を防ぐために切り捨てられます。
듣건대
아프잖아.
앞에서 보듯이 Activity Manager 는getRecentTasks 대신 사용하는 것을 추천하지 않습니다.
ActivityManager.getappTasks를 사용하라고 적혀 있습니다.
(자세히 조사하지 않았다.)
대략적인 통계를 작성하려면 UsageStatisManager를 사용합니다.

총결산

  • 준비된 총 API가 이상해서 UsageStatis Manager입니다.query Events를 사용하는 게 좋은 장면도 있고
  • 권한 필요
  • 응용 프로그램의 최신 역사 기록을 가져올 수 없습니다.(getRecentTask의 대안이 아님)
  • 주로 통계 방법에 관하여 각양각색의 주의점이 있다.
    시작 중인 작업을 가져오지 못하면 불편합니다
    지금까지 기간을 지정하지 않았거나 원래부터 사용할 수 없는 API
    이런 API가 있다면 재미있는 앱도 만들 수 있을 것 같다.
    앱 가동 이력 등 개인정보를 보내고 싶은 앱도 판별이 쉬워진다.
    그리고 아직 미완성 API이기 때문에 앞으로도 개선될 것입니다.

    M 에서 응용 설정에서 볼 수 있습니까?


    "Android M에서""적용""섹션이 업데이트되어 더욱 기능적"
    이 글을 보고 데이터 사용량의 측정이 응용 상태를 나타냈다
    이쪽 API와 TrafficStats를 같이 사용할지도 몰라요.

    좋은 웹페이지 즐겨찾기