大家好,欢迎来到IT知识分享网。
package com.zwxuf.appusagestats; import android.app.Activity; import android.app.AppOpsManager; import android.app.Service; import android.app.usage.UsageEvents; import android.app.usage.UsageStats; import android.app.usage.UsageStatsManager; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Build; import android.os.Process; import android.provider.Settings; import android.util.Log; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.SortedMap; import androidx.annotation.RestrictTo; import androidx.core.app.ActivityCompat; / * 应用统计类 */ public class AppUsageHelper { private static final String TAG = "AppUsageHelper"; private static final int ACTIVITY_STOPPED = 23; / * 是否获取权限 * * @param context * @return */ public static boolean isStatsEnabled(Context context) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { return true; } AppOpsManager aom = (AppOpsManager) context.getSystemService(Service.APP_OPS_SERVICE); int mode = aom.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, Process.myUid(), context.getPackageName()); return mode == AppOpsManager.MODE_ALLOWED; } / * 获取权限 * * @param context * @param requestCode */ public static void requestStats(Activity context, int requestCode) { Intent intent = new Intent(); intent.setAction(Settings.ACTION_USAGE_ACCESS_SETTINGS); intent.setData(Uri.parse("package:" + context.getPackageName())); try { context.startActivityForResult(intent, requestCode); } catch (Exception e) { intent.setData(null); context.startActivityForResult(intent, requestCode); } } / * 获取所有应用使用时长 * * @param context * @param beginTime * @param endTime * @return */ public static Map<String, Long> getStatsInfo(Context context, long beginTime, long endTime) { if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP_MR1) { return null; } UsageStatsManager usm = (UsageStatsManager) context.getSystemService(Service.USAGE_STATS_SERVICE); UsageEvents events = usm.queryEvents(beginTime, endTime); if (events == null) { return null; } //生成事件列表 Map<String, List<UsageEvents.Event>> eventMap = new HashMap<>(); while (events.hasNextEvent()) { UsageEvents.Event event = new UsageEvents.Event(); events.getNextEvent(event); String packageName = event.getPackageName(); List<UsageEvents.Event> eventList = eventMap.get(packageName); if (eventList == null) { eventList = new ArrayList<>(); eventMap.put(packageName, eventList); } eventList.add(event); } //计算应用时长 LinkedHashMap<String, Long> statsMap = new LinkedHashMap<>(); for (Map.Entry<String, List<UsageEvents.Event>> entry : eventMap.entrySet()) { long totalTime = calcAppUsageTime(entry.getValue()); //计算 if (totalTime > 0) statsMap.put(entry.getKey(), totalTime); } //删除自己 statsMap.remove(context.getPackageName()); //按时间排序 List<Map.Entry<String, Long>> entryList = new ArrayList<>(statsMap.entrySet()); Collections.sort(entryList, new Comparator<Map.Entry<String, Long>>() { @Override public int compare(Map.Entry<String, Long> o1, Map.Entry<String, Long> o2) { return (int) (o2.getValue() - o1.getValue()); } }); statsMap.clear(); for (Map.Entry<String, Long> entry : entryList) { //Log.i(TAG, entry.getKey() + ", " + entry.getValue()); statsMap.put(entry.getKey(), entry.getValue()); } return statsMap; } / * 获取单个应用使用时长 * @param context * @param packageName * @param beginTime * @param endTime * @return */ public static long getStatsInfo(Context context, String packageName, long beginTime, long endTime) { if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP_MR1) { return -1; } UsageStatsManager usm = (UsageStatsManager) context.getSystemService(Service.USAGE_STATS_SERVICE); UsageEvents events = usm.queryEvents(beginTime, endTime); if (events == null) { return -1; } //生成事件列表 List<UsageEvents.Event> eventList = new ArrayList<>(); while (events.hasNextEvent()) { UsageEvents.Event event = new UsageEvents.Event(); events.getNextEvent(event); if (packageName.equals(event.getPackageName())) { eventList.add(event); } } //计算应用时长 return calcAppUsageTime(eventList); } / * 计算应用使用时长 * @param eventList * @return */ private static long calcAppUsageTime(List<UsageEvents.Event> eventList) { Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); long startTimeOfDay = calendar.getTimeInMillis(); //今天0点 Set<String> componentList = new HashSet<>(); long resumeTime = 0; long totalTime = 0; boolean isFirstToBack = true; for (UsageEvents.Event event : eventList) { int eventType = event.getEventType(); String className = event.getClassName(); switch (eventType) { case UsageEvents.Event.MOVE_TO_FOREGROUND: if (resumeTime == 0) resumeTime = event.getTimeStamp(); componentList.add(className); isFirstToBack = false; break; case UsageEvents.Event.MOVE_TO_BACKGROUND: case ACTIVITY_STOPPED: componentList.remove(className); if (componentList.isEmpty()) { if (resumeTime != 0) { long usageTime = event.getTimeStamp() - resumeTime; totalTime += usageTime; resumeTime = 0; } else { if (eventType == UsageEvents.Event.MOVE_TO_BACKGROUND) { if (isFirstToBack) { long usageTime = event.getTimeStamp() - startTimeOfDay; totalTime += usageTime; isFirstToBack = false; } } } } break; } } return totalTime; } / * 获取当天的应用使用时长 * * @param context * @return */ public static Map<String, Long> getStatsInfoOfToday(Context context) { long now = System.currentTimeMillis(); Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(now); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); return getStatsInfo(context, calendar.getTimeInMillis(), now); } / * 获取指定日期应用时长 * * @param context * @param date 日期字串 * @return */ public static Map<String, Long> getStatsInfoOfDate(Context context, String date) { try { Date mDate = new SimpleDateFormat("yyyy-M-d", Locale.CHINESE).parse(date); Log.i(TAG, "" + mDate.getYear()); Calendar calendar = Calendar.getInstance(); calendar.setTime(mDate); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); long beginTime = calendar.getTimeInMillis(); calendar.add(Calendar.DATE, 1); long endTime = calendar.getTimeInMillis(); long now = System.currentTimeMillis(); return getStatsInfo(context, beginTime, endTime > now ? now : endTime); } catch (ParseException e) { e.printStackTrace(); return null; } } public static String getTimeLengthName(long ms) { if (ms <= 0) { return ""; } long secondTotal = ms / 1000; secondTotal = secondTotal == 0 ? 1 : secondTotal; long minuteTotal = secondTotal / 60; long hour = secondTotal / 3600; long minute = secondTotal % 3600 / 60; long second = secondTotal % 3600 % 60; StringBuilder sb = new StringBuilder(); if (hour != 0) { sb.append(hour).append("小时"); } if (minute != 0) { sb.append(minute).append(second == 0 ? "分钟" : "分"); } if (second != 0) { sb.append(second).append("秒"); } return sb.toString(); } }
public class MainActivity extends AppCompatActivity implements View.OnClickListener,Runnable { private static final String TAG = "MainActivity"; private static final int REQUEST_USAGE_STATS = 1000; private Button bn_open_permission; private TextView tv_content; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bn_open_permission = findViewById(R.id.bn_open_permission); tv_content = findViewById(R.id.tv_content); bn_open_permission.setOnClickListener(this); /*if (AppUsageHelper.isStatsEnabled(this)) { refresh(); }*/ } @Override protected void onResume() { super.onResume(); if (AppUsageHelper.isStatsEnabled(this)) { bn_open_permission.setVisibility(View.GONE); tv_content.setVisibility(View.VISIBLE); refresh(); } else { bn_open_permission.setVisibility(View.VISIBLE); tv_content.setVisibility(View.GONE); } } @Override public void onClick(View v) { AppUsageHelper.requestStats(this, REQUEST_USAGE_STATS); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_USAGE_STATS) { if (AppUsageHelper.isStatsEnabled(this)) { refresh(); } else { Toast.makeText(this, "未开启权限", Toast.LENGTH_SHORT).show(); } } } private void refresh() { new Thread(this).start(); } @Override public void run() { synchronized (MainActivity.class){ final Map<String, Long> statsMap = AppUsageHelper.getStatsInfoOfToday(MainActivity.this); runOnUiThread(new Runnable() { @Override public void run() { StringBuilder sb = new StringBuilder(); if (statsMap != null) { PackageManager pm = getPackageManager(); for (Map.Entry<String, Long> entry : statsMap.entrySet()) { String label = ""; try { ApplicationInfo info = pm.getApplicationInfo(entry.getKey(), 0); label = pm.getApplicationLabel(info).toString(); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } sb.append(label) .append("(").append(entry.getKey()).append(")") .append('\n') .append("\t\t").append(AppUsageHelper.getTimeLengthName(entry.getValue())) .append('\n'); } } tv_content.setText(sb); } }); } } }
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" tools:context=".MainActivity"> <Button android:id="@+id/bn_open_permission" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开启权限" /> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp"> <TextView android:id="@+id/tv_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:lineSpacingExtra="2dp" android:textSize="12sp" android:textColor="#" /> </ScrollView> </LinearLayout>
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/151458.html