package com.forfan.bigbang.util;
import android.app.ActivityManager;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import com.forfan.bigbang.BigBangApp;
import com.forfan.bigbang.R;
import com.forfan.bigbang.view.Dialog;
import com.forfan.bigbang.view.DialogFragment;
import com.forfan.bigbang.view.SimpleDialog;
import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.List;
import java.util.NavigableSet;
import java.util.TreeMap;
/**
* Created by penglu on 2016/8/14.
*/
public class RunningTaskUtil {
private static final String TAG="RunningTaskUtil";
public static final int TWENTYSECOND = 1000 * 20;
public static final int THIRTYSECOND = 1000 * 60 * 60 * 3;
private ActivityManager activityManager;
private UsageStatsManager mUsageStatsManager;
private Field mLastEventField;
public RunningTaskUtil(Context context){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
mUsageStatsManager = (UsageStatsManager)context.getApplicationContext().getSystemService(Context.USAGE_STATS_SERVICE);
}
activityManager = (ActivityManager)context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
}
public ComponentName getTopActivtyFromLolipopOnwards(){
//用两次取当前应用的办法来提高正确性
return getTopActivtyFromLolipopOnwards(true);
}
public ComponentName getTopActivtyFromLolipopOnwards(boolean isFirst){
ComponentName runningTopActivity=null;
String topPackageName =null;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
long time = System.currentTimeMillis();
// We get usage stats for the last 10 seconds
List<UsageStats> stats ;
// long start=System.currentTimeMillis();
if (isFirst){
stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - TWENTYSECOND, time);
}else {
stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - THIRTYSECOND, time);
}
// LogUtil.e(TAG,"isFirst="+isFirst+",queryUsageStats cost:"+ (System.currentTimeMillis()-start));
// Sort the stats by the last time used
if(stats != null) {
TreeMap<Long,UsageStats> mySortedMap = new TreeMap<Long,UsageStats>();
// start=System.currentTimeMillis();
for (UsageStats usageStats : stats) {
mySortedMap.put(usageStats.getLastTimeUsed(),usageStats);
}
// LogUtil.e(TAG,"isFirst="+isFirst+",mySortedMap cost:"+ (System.currentTimeMillis()-start));
if(mySortedMap != null && !mySortedMap.isEmpty()) {
NavigableSet<Long> keySet=mySortedMap.navigableKeySet();
Iterator iterator=keySet.descendingIterator();
while(iterator.hasNext()){
UsageStats usageStats = mySortedMap.get(iterator.next());
if (mLastEventField==null) {
try {
mLastEventField = UsageStats.class.getField("mLastEvent");
} catch (NoSuchFieldException e) {
break;
}
}
if (mLastEventField!=null) {
int lastEvent = 0;
try {
lastEvent = mLastEventField.getInt(usageStats);
} catch (IllegalAccessException e) {
break;
}
if (lastEvent==1){
topPackageName=usageStats.getPackageName();
break;
}
}else {
break;
}
}
if (topPackageName==null){
topPackageName = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
if ("com.android.systemui".equals(topPackageName)){
Long currentKey = null;
String tempPackage = topPackageName;
currentKey = (Long) ((TreeMap) mySortedMap).floorKey(mySortedMap.lastKey()-1);
if (currentKey!=null) {
tempPackage = mySortedMap.get(currentKey).getPackageName();
}
if (tempPackage!=null){
if (BigBangApp.getInstance().getPackageName().equals(tempPackage)){
currentKey = (Long) ((TreeMap) mySortedMap).floorKey(currentKey-1);
if (currentKey!=null) {
tempPackage = mySortedMap.get(currentKey).getPackageName();
}
}
}
if (tempPackage!=null){
topPackageName=tempPackage;
}
}
}
runningTopActivity=new ComponentName(topPackageName,"");
LogUtil.d(TAG,topPackageName);
}else {
LogUtil.d(TAG,"mySortedMap.isEmpty");
if (isFirst){
runningTopActivity = getTopActivtyFromLolipopOnwards(false);
}else {
runningTopActivity=getTopRunningTasks();
}
}
}
if (runningTopActivity.getPackageName().equals(BigBangApp.getInstance().getPackageName())){
runningTopActivity = getTopRunningTasks();
}
}else {
runningTopActivity = getTopRunningTasks();
}
return runningTopActivity;
}
public ComponentName getTopRunningTasks(){
ComponentName runningTopActivity = activityManager.getRunningTasks(1).get(0).topActivity;
LogUtil.d(TAG,"runningTopActivity="+runningTopActivity.getClassName());
return runningTopActivity;
}
public boolean needToSet(){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
long time = System.currentTimeMillis();
// We get usage stats for the last 10 seconds
List<UsageStats> stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000*60, time);
if (stats.size()==0){
return true;
}else {
return false;
}
}else {
return false;
}
}
public interface SettingRequestListener{
void onPositive();
void onNegative();
}
public void showSettingRequestDialog(final View view, final boolean needSet, final Context context, final SettingRequestListener settingRequestListener){
Dialog.Builder builder = new SimpleDialog.Builder( R.style.SimpleDialogLight ){
boolean isSet=false;
@Override
protected void onBuildDone(final Dialog dialog) {
dialog.layoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
@Override
public void onPositiveActionClicked(DialogFragment fragment) {
if (needSet) {
try {
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
context.startActivity(intent);
}catch (Throwable e){
SnackBarUtil.show(view,R.string.open_setting_failed_diy);
}
}
isSet = true;
super.onPositiveActionClicked(fragment);
}
@Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
if (isSet){
if (settingRequestListener!=null) {
settingRequestListener.onPositive();
}
}else {
if (settingRequestListener!=null) {
settingRequestListener.onNegative();
}
}
}
@Override
public void onNegativeActionClicked(DialogFragment fragment) {
isSet=false;
super.onNegativeActionClicked(fragment);
}
};
((SimpleDialog.Builder)builder)
.message(context.getString(R.string.request_usage_setting_msg))
.positiveAction(context.getString(R.string.goto_setting))
.negativeAction(context.getString(R.string.cancel));
DialogFragment fragment = DialogFragment.newInstance(builder);
fragment.show(((AppCompatActivity)context).getSupportFragmentManager(), null);
}
}