0

我是 Java 和 Android 工作室的新手,这是来自未知来源的源代码。我需要显示应用程序在前台使用的总时间,而不是上次使用的时间,所以有人可以提一下我为实现目标需要进行的必要更改。提前致谢。

DateUtils.java

package com.quirodev.usagestatsmanagersample;

import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class DateUtils {

public static String format(UsageStatsWrapper usageStatsWrapper){

    DateFormat format = SimpleDateFormat.getDateInstance(DateFormat.SHORT);
    return format.format(usageStatsWrapper.getUsageStats().getLastTimeUsed());
}
}

MainActivity.java

package com.quirodev.usagestatsmanagersample;

import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.ProgressBar;
import android.widget.TextView;

import java.util.List;

import static android.view.View.GONE;
import static android.view.View.VISIBLE;

public class MainActivity extends AppCompatActivity implements 
UsageContract.View {

private ProgressBar progressBar;
private TextView permissionMessage;

private UsageContract.Presenter presenter;
private UsageStatAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
    progressBar = (ProgressBar) findViewById(R.id.progress_bar);
    permissionMessage = (TextView) findViewById(R.id.grant_permission_message);

    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    adapter = new UsageStatAdapter();
    recyclerView.setAdapter(adapter);

    permissionMessage.setOnClickListener(v -> openSettings());

    presenter = new UsagePresenter(this, this);
}

private void openSettings() {
    startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));
}

@Override
protected void onResume() {
    super.onResume();
    showProgressBar(true);
    presenter.retrieveUsageStats();
}

@Override
public void onUsageStatsRetrieved(List<UsageStatsWrapper> list) {
    showProgressBar(false);
    permissionMessage.setVisibility(GONE);
    adapter.setList(list);
}

@Override
public void onUserHasNoPermission() {
    showProgressBar(false);
    permissionMessage.setVisibility(VISIBLE);
}

private void showProgressBar(boolean show) {
    if (show) {
        progressBar.setVisibility(VISIBLE);
    } else {
        progressBar.setVisibility(GONE);
    }
}

UsagePresenter.java

package com.quirodev.usagestatsmanagersample;

import android.app.AppOpsManager;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;

import java.util.ArrayList;   
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.OPSTR_GET_USAGE_STATS;
import static android.os.Process.myUid;

public class UsagePresenter implements UsageContract.Presenter {

private static final int flags = PackageManager.GET_META_DATA |
        PackageManager.GET_SHARED_LIBRARY_FILES |
        PackageManager.GET_UNINSTALLED_PACKAGES;

private UsageStatsManager usageStatsManager;
private PackageManager packageManager;
private UsageContract.View view;
private final Context context;

public UsagePresenter(Context context, UsageContract.View view) {
    usageStatsManager = (UsageStatsManager) context.getSystemService("usagestats");
    packageManager = context.getPackageManager();
    this.view = view;
    this.context = context;
}

private long getStartTime() {
    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.YEAR, -1);
    return calendar.getTimeInMillis();
}

@Override
public void retrieveUsageStats() {
    if (!checkForPermission(context)) {
        view.onUserHasNoPermission();
        return;
    }

    List<String> installedApps = getInstalledAppList();
    Map<String, UsageStats> usageStats = usageStatsManager.queryAndAggregateUsageStats(getStartTime(), System.currentTimeMillis());
    List<UsageStats> stats = new ArrayList<>();
    stats.addAll(usageStats.values());

    List<UsageStatsWrapper> finalList = buildUsageStatsWrapper(installedApps, stats);
    view.onUsageStatsRetrieved(finalList);
}

private boolean checkForPermission(Context context) {
    AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
    int mode = appOps.checkOpNoThrow(OPSTR_GET_USAGE_STATS, myUid(), context.getPackageName());
    return mode == MODE_ALLOWED;
}

private List<String> getInstalledAppList(){
    List<ApplicationInfo> infos = packageManager.getInstalledApplications(flags);
    List<String> installedApps = new ArrayList<>();
    for (ApplicationInfo info : infos){
        installedApps.add(info.packageName);
    }
    return installedApps;
}

private List<UsageStatsWrapper> buildUsageStatsWrapper(List<String> packageNames, List<UsageStats> usageStatses) {
    List<UsageStatsWrapper> list = new ArrayList<>();
    for (String name : packageNames) {
        boolean added = false;
        for (UsageStats stat : usageStatses) {
            if (name.equals(stat.getPackageName())) {
                added = true;
                list.add(fromUsageStat(stat));
            }
        }
        if (!added) {
            list.add(fromUsageStat(name));
        }
    }
    Collections.sort(list);
    return list;
}

private UsageStatsWrapper fromUsageStat(String packageName) throws IllegalArgumentException {
    try {
        ApplicationInfo ai = packageManager.getApplicationInfo(packageName, 0);
        return new UsageStatsWrapper(null, packageManager.getApplicationIcon(ai), packageManager.getApplicationLabel(ai).toString());

    } catch (PackageManager.NameNotFoundException e) {
        throw new IllegalArgumentException(e);
    }
}

private UsageStatsWrapper fromUsageStat(UsageStats usageStats) throws IllegalArgumentException {
    try {
        ApplicationInfo ai = packageManager.getApplicationInfo(usageStats.getPackageName(), 0);
        return new UsageStatsWrapper(usageStats, packageManager.getApplicationIcon(ai), packageManager.getApplicationLabel(ai).toString());

    } catch (PackageManager.NameNotFoundException e) {
        throw new IllegalArgumentException(e);
    }
}
}

UsageStatAdapter.java

package com.quirodev.usagestatsmanagersample;

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList; 
import java.util.List;

public class UsageStatAdapter extends RecyclerView.Adapter<UsageStatVH> {

private List<UsageStatsWrapper> list;

public UsageStatAdapter(){
    list = new ArrayList<>();
}

@Override
public UsageStatVH onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.usage_stat_item, parent, false);
    return new UsageStatVH(view);
}

@Override
public void onBindViewHolder(UsageStatVH holder, int position) {
    holder.bindTo(list.get(position));
}

@Override
public int getItemCount() {
    return list.size();
}

public void setList(List<UsageStatsWrapper> list) {
    this.list = list;
    notifyDataSetChanged();
}
}

UsageStatsWrapper.java

package com.quirodev.usagestatsmanagersample;

import android.app.usage.UsageStats;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;

public final class UsageStatsWrapper implements Comparable<UsageStatsWrapper> {

private final UsageStats usageStats;
private final Drawable appIcon;
private final String appName;

public UsageStatsWrapper(UsageStats usageStats, Drawable appIcon, String appName) {
    this.usageStats = usageStats;
    this.appIcon = appIcon;
    this.appName = appName;
}

public UsageStats getUsageStats() {
    return usageStats;
}

public Drawable getAppIcon() {
    return appIcon;
}

public String getAppName() {
    return appName;
}

@Override
public int compareTo(@NonNull UsageStatsWrapper usageStatsWrapper) {
    if (usageStats == null && usageStatsWrapper.getUsageStats() != null) {
        return 1;
    } else if (usageStatsWrapper.getUsageStats() == null && usageStats != null) {
        return -1;
    } else if (usageStatsWrapper.getUsageStats() == null && usageStats == null) {
        return 0;
    } else {
        return Long.compare(usageStatsWrapper.getUsageStats().getLastTimeUsed(),
                usageStats.getLastTimeUsed());
    }
}
}

UsageStatVH.java

  package com.quirodev.usagestatsmanagersample;

  import android.support.v7.widget.RecyclerView;
  import android.view.View;
  import android.widget.ImageView;
  import android.widget.TextView;

  public class UsageStatVH extends RecyclerView.ViewHolder {

private ImageView appIcon;
private TextView appName;
private TextView lastTimeUsed;

public UsageStatVH(View itemView) {
    super(itemView);

    appIcon = (ImageView) itemView.findViewById(R.id.icon);
    appName = (TextView) itemView.findViewById(R.id.title);
    lastTimeUsed = (TextView) itemView.findViewById(R.id.last_used);
}

public void bindTo(UsageStatsWrapper usageStatsWrapper) {
    appIcon.setImageDrawable(usageStatsWrapper.getAppIcon());
    appName.setText(usageStatsWrapper.getAppName());
    if (usageStatsWrapper.getUsageStats() == null){
        lastTimeUsed.setText(R.string.last_time_used_never);
    }else if (usageStatsWrapper.getUsageStats().getLastTimeUsed() == 0L){
        lastTimeUsed.setText(R.string.last_time_used_never);
    } else{
        lastTimeUsed.setText(App.getApp().getString(R.string.last_time_used,
                DateUtils.format(usageStatsWrapper)));
    }
}
}

截图 示例图像

4

2 回答 2

1

这是我在我的应用程序中使用的逻辑,给出了正确的结果。此逻辑适用于运行 Android OS 版本 lollipop 及更高版本的设备。

List<ApplicationUsageInformation> result = new ArrayList();
    boolean flag = false;
    UsageStatsManager usageStatsMgr = (UsageStatsManager)this.context.getSystemService("usagestats");
    if(usageStatsMgr == null) {
        return Collections.emptyList();
    } else {
        UsageEvents events = usageStatsMgr.queryEvents(beginTime, endTime);

        ApplicationUsageInformation applicationUsageInformation; // Java class that holds info
        for(Event event = new Event(); events.getNextEvent(event); event = new Event()) {
            flag = true;
            if(event.getEventType() == 1) {
                applicationUsageInformation = new ApplicationUsageInformation();
                Log.d(this.TAG, "MOVE_TO_FOREGROUND : " + event.getPackageName() + " - " + event.getTimeStamp());
                this.currentForegroundApp = event.getPackageName();
                this.currentForegroundAppTS = event.getTimeStamp();
                applicationUsageInformation.setPackageName(event.getPackageName());
                applicationUsageInformation.setDuration(event.getTimeStamp());
                applicationUsageInformation.setAction("foreground");
                result.add(applicationUsageInformation);
            } else if(event.getEventType() == 2) {
                Log.d(this.TAG, "MOVE_TO_BACKGROUND : " + event.getPackageName() + " - " + event.getTimeStamp());
                applicationUsageInformation = result.size() == 0?null:(ApplicationUsageInformation)result.get(result.size() - 1);
                if(applicationUsageInformation == null) {
                    if(this.currentForegroundApp != null && event.getPackageName().equals(this.currentForegroundApp)) {
                        applicationUsageInformation = new ApplicationUsageInformation();
                        applicationUsageInformation.setPackageName(this.currentForegroundApp);
                        applicationUsageInformation.setAction("foreground");
                        applicationUsageInformation.setDuration(event.getTimeStamp() - this.currentForegroundAppTS >= endTime - beginTime?event.getTimeStamp() - beginTime:event.getTimeStamp() - this.currentForegroundAppTS);
                        result.add(applicationUsageInformation);
                    }
                } else {
                    long startTime = applicationUsageInformation.getDuration();
                    applicationUsageInformation.setDuration(event.getTimeStamp() - startTime);
                    if(result.size() == 0) {
                        result.add(applicationUsageInformation);
                    } else {
                        result.set(result.size() - 1, applicationUsageInformation);
                    }
                }
            }
        }

        if(!flag && this.currentForegroundApp != null) {
            applicationUsageInformation = new ApplicationUsageInformation();
            applicationUsageInformation.setPackageName(this.currentForegroundApp);
            applicationUsageInformation.setAction("foreground");
            if(endTime - this.currentForegroundAppTS >= endTime - beginTime) {
                applicationUsageInformation.setDuration(endTime - beginTime);
            } else {
                applicationUsageInformation.setDuration(endTime - this.currentForegroundAppTS);
            }

            result.add(applicationUsageInformation);
        }
于 2018-07-23T11:00:08.053 回答
0

您可以利用Android Lifecycle。举个例子:在你onCreate()第一次到达的活动中,你可以初始化一个日历变量。每一次onPause()你都会添加经过的时间,每一次onResume()你都会重新开始跟踪时间。

如何准确地跟踪时间取决于您,这取决于您期望的结果。您还可以单独跟踪每个活动的时间。

简单示例(为了更简单,我不会使用Calendar):

在您Main使用两个静力学:

public static long now;
public static long duration;

在您onCreate的 Main 中,初始化它们:

now = System.currentTimeMillies();
duration = 0;

onPause您添加时间:

duration += System.currentTimeMillies() - now;
now = System.currentTimeMillies();

用于duration显示持续时间,并在需要更新持续时间的任何地方重复使用上面的代码。

于 2018-07-20T14:23:13.487 回答