Android使用記錄訪問(wèn)權(quán)限詳解
使用記錄訪問(wèn)權(quán)限
什么是使用記錄訪問(wèn)權(quán)限呢?這是在Android5.0(Api level 21)新添加的,通過(guò)該權(quán)限我們可以查看設(shè)備上其它應(yīng)用使用情況的統(tǒng)計(jì)信息等。
如何使用該權(quán)限呢?
首先在manifest中添加:
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
由于該權(quán)限默認(rèn)只授予系統(tǒng)應(yīng)用,所以添加了ignore屬性。
然后通過(guò)如下代碼進(jìn)而手動(dòng)打開(kāi)權(quán)限:
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS); startActivityForResult(intent);
當(dāng)然只要我們?cè)趍anifest中進(jìn)行了權(quán)限配置,也可以通過(guò)設(shè)置->安全->有權(quán)查看使用情況的應(yīng)用來(lái)打開(kāi)權(quán)限:
到此我們的應(yīng)用就擁有了該權(quán)限。那么有了這個(gè)權(quán)限到底能做什么呢?繼續(xù)往下看......
前段時(shí)間和同事聊到了一個(gè)叫我要當(dāng)學(xué)霸的app,里邊有個(gè)學(xué)習(xí)監(jiān)督的功能,就需要使用記錄訪問(wèn)權(quán)限,當(dāng)打開(kāi)權(quán)限后,除了自己和桌面外,其它app都不能正常使用,點(diǎn)擊其它app時(shí)會(huì)直接退到后臺(tái)并彈出一個(gè)提示頁(yè)面。不妨我們來(lái)模擬下這個(gè)功能。
在這之前我們首先看一個(gè)類(lèi)UsageStatsManager:
public final class UsageStatsManager { public static final int INTERVAL_BEST = 4; //根據(jù)提供的開(kāi)始、結(jié)束時(shí)間決定時(shí)間間隔 public static final int INTERVAL_DAILY = 0; //以天為時(shí)間間隔(最長(zhǎng)7天) public static final int INTERVAL_MONTHLY = 2; //以月為時(shí)間間隔(最長(zhǎng)6個(gè)月) public static final int INTERVAL_WEEKLY = 1; //以周為時(shí)間間隔(最長(zhǎng)4個(gè)星期) public static final int INTERVAL_YEARLY = 3; //以年為時(shí)間間隔(最長(zhǎng)2年) UsageStatsManager() { throw new RuntimeException("Stub!"); } public List<UsageStats> queryUsageStats(int intervalType, long beginTime, long endTime) { throw new RuntimeException("Stub!"); } public List<ConfigurationStats> queryConfigurations(int intervalType, long beginTime, long endTime) { throw new RuntimeException("Stub!"); } public UsageEvents queryEvents(long beginTime, long endTime) { throw new RuntimeException("Stub!"); } public Map<String, UsageStats> queryAndAggregateUsageStats(long beginTime, long endTime) { throw new RuntimeException("Stub!"); } public boolean isAppInactive(String packageName) { throw new RuntimeException("Stub!"); } }
可以看到該類(lèi)提供了五種時(shí)間間隔類(lèi)型,這里我們比較關(guān)注queryUsageStats()
方法,通過(guò)該方法我們可以得到一段時(shí)間內(nèi) 其它應(yīng)用的使用情況。
我們實(shí)現(xiàn)思路是這樣的,通過(guò)UsageStatsManager類(lèi)獲得2秒內(nèi)手機(jī)app的使用數(shù)據(jù),找到時(shí)間最近的一個(gè),如果不是我們自己的app或桌面則模擬home鍵點(diǎn)擊,同時(shí)彈出一個(gè)提示頁(yè)面,具體的代碼如下:
private void getTopApp() { UsageStatsManager mUsageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE);//usagestats long time = System.currentTimeMillis(); List<UsageStats> usageStatsList = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, time - 2000, time); if (usageStatsList != null && !usageStatsList.isEmpty()) { SortedMap<Long, UsageStats> usageStatsMap = new TreeMap<>(); for (UsageStats usageStats : usageStatsList) { usageStatsMap.put(usageStats.getLastTimeUsed(), usageStats); } if (!usageStatsMap.isEmpty()) { String topPackageName = usageStatsMap.get(usageStatsMap.lastKey()).getPackageName(); if (getLauncherPackageName(mContext).equals(topPackageName) || "com.othershe.test".equals(topPackageName)) { return; } Log.e("TopPackage Name", topPackageName); //模擬home鍵點(diǎn)擊 Intent intent = new Intent(Intent.ACTION_MAIN); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addCategory(Intent.CATEGORY_HOME); startActivity(intent); //啟動(dòng)提示頁(yè)面 Intent intent1 = new Intent(mContext, TipActivity.class); intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent1); } } }
因?yàn)闀r(shí)間周期是2秒,所以這里我們采用INTERVAL_BEST作為時(shí)間間隔。其中的UsageStats對(duì)象對(duì)應(yīng)一個(gè)查詢到的app數(shù)據(jù),主要包含以下信息:
getTopApp()
是我們的核心方法,當(dāng)然我們需要開(kāi)啟一個(gè)服務(wù),然后在服務(wù)中每隔500毫秒執(zhí)行一次上邊的方法,這樣就能起到不斷檢測(cè)的作用:
@Override public int onStartCommand(Intent intent, int flags, int startId) { mTimer = new Timer(); TimerTask task = new TimerTask() { @Override public void run() { getTopApp(); } }; mTimer.schedule(task, 1000, 500); return super.onStartCommand(intent, flags, startId); }
打開(kāi)權(quán)限、啟動(dòng)服務(wù),可以看到實(shí)際的運(yùn)行效果如下,基本符合我們的預(yù)期。
類(lèi)似的道理,我們也可以判斷摸個(gè)app是否在前臺(tái)運(yùn)行。
上邊我們使用了INTERVAL_BEST 時(shí)間間隔類(lèi)型,還可以使用其它4中,例如使用INTERVAL_YEARLY:
private void getHistoryApps() { Calendar calendar = Calendar.getInstance(); long endTime = calendar.getTimeInMillis(); calendar.add(Calendar.YEAR, -1); long startTime = calendar.getTimeInMillis(); UsageStatsManager mUsageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE); List<UsageStats> usageStatsList = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY, startTime, endTime); if (usageStatsList != null && !usageStatsList.isEmpty()) { HashSet<String> set = new HashSet<>(); for (UsageStats usageStats : usageStatsList) { set.add(usageStats.getPackageName()); } if (!set.isEmpty()) { Log.e("size", set.size() + ""); } } }
上邊的代碼我們最終獲得了過(guò)去一年手機(jī)上使用過(guò)的app的包名集合(其中包括系統(tǒng)級(jí)別的):
拿到這些包名可以做什么呢?
其實(shí)對(duì)于網(wǎng)賺類(lèi)型的應(yīng)用有這樣一種業(yè)務(wù)場(chǎng)景,就是用戶通過(guò)下載app來(lái)做任務(wù)進(jìn)而賺取收益,但是如果當(dāng)前設(shè)備通過(guò)其它網(wǎng)賺應(yīng)用已經(jīng)下載過(guò)某個(gè)app,然后卸載了,再通過(guò)你的網(wǎng)賺應(yīng)用下載。如果你不知道用戶之前安裝過(guò)該app,就需要給用戶結(jié)算相應(yīng)的收益,但是你的上游渠道是不會(huì)給你結(jié)算的,因?yàn)檫@屬于同一設(shè)備上的重復(fù)下載,這樣對(duì)公司而言就是虧損的。
有了歷史包名信息,我們就可以判斷用戶在一定的時(shí)間周期內(nèi)是否安裝過(guò)對(duì)應(yīng)的app,進(jìn)而采取相應(yīng)的策略,這樣可以在一定程度降低損失。當(dāng)然有個(gè)前提,你要友好的引導(dǎo)用戶開(kāi)啟權(quán)限。
總結(jié)
先到這里吧,以上就是這篇文章的全部?jī)?nèi)容了,更多的用法還有待進(jìn)一步探究。希望這篇文章對(duì)各位Android開(kāi)發(fā)者們能帶來(lái)一定的幫助,謝謝大家對(duì)腳本之家能帶來(lái)一定的幫助。
相關(guān)文章
Android編程實(shí)現(xiàn)設(shè)置按鈕背景透明與半透明及圖片背景透明的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)設(shè)置按鈕背景透明與半透明及圖片背景透明的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Button及ImageButton的背景屬性設(shè)置技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-12-12Android控件之ProgressBar用法實(shí)例分析
這篇文章主要介紹了Android控件之ProgressBar用法,以一個(gè)完整實(shí)例形式較為詳細(xì)的分析了ProgressBar控件操作進(jìn)度顯示的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09Android View轉(zhuǎn)換為Bitmap實(shí)現(xiàn)應(yīng)用內(nèi)截屏功能
這篇文章主要介紹了Android View轉(zhuǎn)換為Bitmap實(shí)現(xiàn)應(yīng)用內(nèi)截屏功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-09-09在Ubuntu下搭建Android開(kāi)發(fā)環(huán)境
對(duì)一個(gè)程序猿來(lái)說(shuō),裝好系統(tǒng)之后的第一件事,一定是搭建開(kāi)發(fā)環(huán)境,已經(jīng)安裝各種開(kāi)發(fā)工具,以便之后能方便順利地進(jìn)行程序的開(kāi)發(fā)。簡(jiǎn)單的介紹下在Ubuntu環(huán)境下搭建Android開(kāi)發(fā)環(huán)境,雖然基本上和在Windows下沒(méi)有太大差別,但有些細(xì)節(jié)上還是很值得注意的。2014-07-07Android 實(shí)現(xiàn)搶購(gòu)倒計(jì)時(shí)功能的示例
這篇文章主要介紹了Android 實(shí)現(xiàn)搶購(gòu)倒計(jì)時(shí)功能的示例,幫助大家更好的理解和學(xué)習(xí)使用Android開(kāi)發(fā),感興趣的朋友可以了解下2021-03-03詳解android與百度echarts項(xiàng)目整合方法
在本篇文章里我們給大家分享了關(guān)于android與百度echarts項(xiàng)目整合方法和具體步驟,需要的朋友們跟著學(xué)習(xí)下。2019-03-03Android Activity 入門(mén)簡(jiǎn)介
Activity 是一個(gè)應(yīng)用組件,用戶可與其提供的屏幕進(jìn)行交互,以執(zhí)行撥打電話、拍攝照片、發(fā)送電子郵件或查看地圖等操作,這篇文章主要介紹了Android Activity入門(mén)基礎(chǔ)知識(shí),需要的朋友可以參考下2024-04-04解析如何在android中增加gsensor驅(qū)動(dòng)(MMA7660)
本篇文章是對(duì)在android中增加gsensor驅(qū)動(dòng)(MMA7660)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06Android studio保存logcat日志到本地的操作
這篇文章主要介紹了Android studio保存logcat日志到本地的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04