update:2021.01.27

fix:
add:增加应用信息上传
This commit is contained in:
2021-01-27 16:15:40 +08:00
parent 6d162f2152
commit ed60c37dba
16 changed files with 942 additions and 55 deletions

View File

@@ -30,6 +30,7 @@ import static com.android.uiuios.dragndrop.DragLayer.ALPHA_INDEX_LAUNCHER_LOAD;
import static com.android.uiuios.logging.LoggerUtils.newContainerTarget;
import static com.android.uiuios.logging.LoggerUtils.newTarget;
import static com.android.uiuios.states.RotationHelper.REQUEST_NONE;
import static com.android.uiuios.touch.ItemClickHandler.getInfoFromPackageName;
import static com.android.uiuios.util.RaceConditionTracker.ENTER;
import static com.android.uiuios.util.RaceConditionTracker.EXIT;
@@ -52,6 +53,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
@@ -66,6 +68,7 @@ import android.os.Parcelable;
import android.os.Process;
import android.os.StrictMode;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.method.TextKeyListener;
import android.util.Log;
import android.util.SparseArray;
@@ -82,6 +85,9 @@ import android.view.animation.OvershootInterpolator;
import android.widget.Toast;
import com.android.uiuios.DropTarget.DragObject;
import com.android.uiuios.Statistics.AppInformation;
import com.android.uiuios.TTUtils.APKUtils;
import com.android.uiuios.TTUtils.Utils;
import com.android.uiuios.accessibility.LauncherAccessibilityDelegate;
import com.android.uiuios.allapps.AllAppsContainerView;
import com.android.uiuios.allapps.AllAppsStore;
@@ -108,6 +114,9 @@ import com.android.uiuios.logging.UserEventDispatcher;
import com.android.uiuios.logging.UserEventDispatcher.UserEventDelegate;
import com.android.uiuios.model.AppLaunchTracker;
import com.android.uiuios.model.ModelWriter;
import com.android.uiuios.network.BaseResponse;
import com.android.uiuios.network.NetWorkManager;
import com.android.uiuios.network.api.addAppLog;
import com.android.uiuios.notification.NotificationListener;
import com.android.uiuios.pageindicators.PageIndicatorDots;
import com.android.uiuios.popup.PopupContainerWithArrow;
@@ -155,6 +164,7 @@ import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@@ -163,6 +173,11 @@ import java.util.function.Predicate;
import androidx.annotation.Nullable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
/**
* Default launcher application.
*/
@@ -216,7 +231,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
// How long to wait before the new-shortcut animation automatically pans the workspace
private static final int NEW_APPS_PAGE_MOVE_DELAY = 500;
private static final int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;
@Thunk static final int NEW_APPS_ANIMATION_DELAY = 500;
@Thunk
static final int NEW_APPS_ANIMATION_DELAY = 500;
private static final int APPS_VIEW_ALPHA_CHANNEL_INDEX = 1;
private static final int SCRIM_VIEW_ALPHA_CHANNEL_INDEX = 0;
@@ -224,9 +240,11 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
private LauncherAppTransitionManager mAppTransitionManager;
private Configuration mOldConfig;
@Thunk Workspace mWorkspace;
@Thunk
Workspace mWorkspace;
private View mLauncherView;
@Thunk DragLayer mDragLayer;
@Thunk
DragLayer mDragLayer;
private DragController mDragController;
private AppWidgetManagerCompat mAppWidgetManager;
@@ -234,23 +252,27 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
private final int[] mTmpAddItemCellCoordinates = new int[2];
@Thunk Hotseat mHotseat;
@Thunk
Hotseat mHotseat;
private PageIndicatorDots mPageIndicatorDots;
private DropTargetBar mDropTargetBar;
// Main container view for the all apps screen.
@Thunk AllAppsContainerView mAppsView;
@Thunk
AllAppsContainerView mAppsView;
AllAppsTransitionController mAllAppsController;
// Scrim view for the all apps and overview state.
@Thunk ScrimView mScrimView;
@Thunk
ScrimView mScrimView;
// UI and state for the overview panel
private View mOverviewPanel;
@Thunk boolean mWorkspaceLoading = true;
@Thunk
boolean mWorkspaceLoading = true;
private ArrayList<OnResumeCallback> mOnResumeCallbacks = new ArrayList<>();
@@ -406,7 +428,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
RaceConditionTracker.onEvent(ON_CREATE_EVT, EXIT);
mStateManager.addStateListener(new LauncherStateManager.StateListener() {
@Override
public void onStateTransitionStart(LauncherState toState) {}
public void onStateTransitionStart(LauncherState toState) {
}
@Override
public void onStateTransitionComplete(LauncherState finalState) {
@@ -495,19 +518,18 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
registerReceiver(mTimeChangedReceiver, filter);
}
private class TimeChangedReceiver extends BroadcastReceiver {
private static class TimeChangedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_DATE_CHANGED)) {
if (Intent.ACTION_DATE_CHANGED.equals(intent.getAction())) {
Log.e("fht", "TimeChangedReceiver:" + "data changed");
} else if (intent.getAction().equals(Intent.ACTION_TIME_CHANGED)) {
} else if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
Log.e("fht", "TimeChangedReceiver:" + "time changed");
} else if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) {
} else if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
Log.e("fht", "TimeChangedReceiver:" + "timezone changed");
} else if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) {
} else if (Intent.ACTION_TIME_TICK.equals(intent.getAction())) {
Log.e("fht", "TimeChangedReceiver:" + "time tick");
}
}
}
@@ -894,7 +916,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
int[] grantResults) {
PendingRequestArgs pendingArgs = mPendingRequestArgs;
if (requestCode == REQUEST_PERMISSION_CALL_PHONE && pendingArgs != null
&& pendingArgs.getRequestCode() == REQUEST_PERMISSION_CALL_PHONE) {
@@ -940,7 +962,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
}
}
@Thunk void completeTwoStageWidgetDrop(
@Thunk
void completeTwoStageWidgetDrop(
final int resultCode, final int appWidgetId, final PendingRequestArgs requestArgs) {
CellLayout cellLayout = mWorkspace.getScreenWithId(requestArgs.screenId);
Runnable onCompleteRunnable = null;
@@ -1002,6 +1025,35 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
}
RaceConditionTracker.onEvent(ON_START_EVT, ENTER);
super.onStart();
String packagename = MyApplication.getInstance().getAppPackageName();
Log.e("SendcloseApp", "packagename=" + packagename);
if (packagename != null && packagename.length() > 0) {
SendcloseApp(packagename);
// if (!APKUtils.isSystemApp(this, packagename) && !Arrays.asList(ItemClickHandler.packages).contains(packagename)) {
// try {
// AppInformation app = getInfoFromPackageName(packagename);
// if (app != null) {
// long time = app.getUsedTimebyDay() / 1000;
// Log.e("fht", "返回运行时间: " + DateUtils.formatElapsedTime(time));
// Log.e("fht", "返回运行时间: " + time);
//
//// if (userInfo != null) {
//// HTTPInterface.sendTimeLog(handler, userInfo, app.getLabel(), 2, time - MyApplication.getInstance().getRunTime());
//// } else {
//// Log.e("fht", "userInfo = null");
//// }
// } else {
// Log.e("fht", "app = null" + packagename);
// }
// } catch (Exception e) {
// Log.e("fht", e.getMessage());
// }
// }
// } else {
// Log.e("packagename", "packagename is null");
}
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onStart();
}
@@ -1009,6 +1061,57 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
RaceConditionTracker.onEvent(ON_START_EVT, EXIT);
}
private static void SendcloseApp(String packageName) {
PackageManager pm = MyApplication.getInstance().getPackageManager();
PackageInfo appInfo = null;
try {
appInfo = pm.getPackageInfo(packageName, 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
if (null != appInfo) {
long appVersionCode;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
appVersionCode = appInfo.getLongVersionCode();
} else {
appVersionCode = appInfo.versionCode;
}
addAppLog appLog = NetWorkManager.getapplogControl();
String sn = Utils.getSerial();
appLog.addLog(sn, packageName, appVersionCode, System.currentTimeMillis() / 1000, 2)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<BaseResponse>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(BaseResponse baseResponse) {
int code = baseResponse.code;
if (code == 200) {
Log.e("SendcloseApp", "onNext:" + code + baseResponse.data);
} else {
Log.e("SendcloseApp", "onNext:" + code + baseResponse.msg);
}
}
@Override
public void onError(Throwable e) {
Log.e("SendcloseApp", "onError: " + e.getMessage());
}
@Override
public void onComplete() {
}
});
}
}
private void handleDeferredResume() {
if (hasBeenResumed() && !mStateManager.getState().disableInteraction) {
getUserEventDispatcher().logActionCommand(Action.Command.RESUME,
@@ -1122,6 +1225,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
/**
* Called when the launcher is ready to use the overlay
*
* @param callbacks A set of callbacks provided by Launcher in relation to the overlay
*/
void setOverlayCallbacks(LauncherOverlayCallbacks callbacks);
@@ -1186,7 +1290,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
mWorkspace.initParentViews(mDragLayer);
mOverviewPanel = findViewById(R.id.overview_panel);
mHotseat = findViewById(R.id.hotseat);
mPageIndicatorDots=findViewById(R.id.page_indicator);
mPageIndicatorDots = findViewById(R.id.page_indicator);
mLauncherView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
@@ -1231,8 +1335,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
* Creates a view representing a shortcut inflated from the specified resource.
*
* @param parent The group the shortcut belongs to.
* @param info The data structure describing the shortcut.
*
* @param info The data structure describing the shortcut.
* @return A View inflated from layoutResId.
*/
public View createShortcut(ViewGroup parent, WorkspaceItemInfo info) {
@@ -1250,7 +1353,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
* @param data The intent describing the shortcut.
*/
private void completeAddShortcut(Intent data, int container, int screenId, int cellX,
int cellY, PendingRequestArgs args) {
int cellY, PendingRequestArgs args) {
if (args.getRequestCode() != REQUEST_CREATE_SHORTCUT
|| args.getPendingIntent().getComponent() == null) {
return;
@@ -1334,8 +1437,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
*
* @param appWidgetId The app widget id
*/
@Thunk void completeAddAppWidget(int appWidgetId, ItemInfo itemInfo,
AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) {
@Thunk
void completeAddAppWidget(int appWidgetId, ItemInfo itemInfo,
AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) {
if (appWidgetInfo == null) {
appWidgetInfo = mAppWidgetManager.getLauncherAppWidgetInfo(appWidgetId);
@@ -1428,7 +1532,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
return mHotseat;
}
public PageIndicatorDots getIndicatorDots(){
public PageIndicatorDots getIndicatorDots() {
return mPageIndicatorDots;
}
@@ -1456,7 +1560,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
return mSharedPrefs;
}
public int getOrientation() { return mOldConfig.orientation; }
public int getOrientation() {
return mOldConfig.orientation;
}
@Override
protected void onNewIntent(Intent intent) {
@@ -1616,7 +1722,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
@Override
public void startIntentSenderForResult(IntentSender intent, int requestCode,
Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {
Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {
if (requestCode != -1) {
mPendingActivityRequestCode = requestCode;
}
@@ -1637,7 +1743,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
*/
@Override
public void startSearch(String initialQuery, boolean selectInitialQuery,
Bundle appSearchData, boolean globalSearch) {
Bundle appSearchData, boolean globalSearch) {
if (appSearchData == null) {
appSearchData = new Bundle();
appSearchData.putString("source", "launcher-search");
@@ -1670,7 +1776,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
}
void addAppWidgetFromDropImpl(int appWidgetId, ItemInfo info, AppWidgetHostView boundWidget,
WidgetAddFlowHandler addFlowHandler) {
WidgetAddFlowHandler addFlowHandler) {
if (LOGD) {
Log.d(TAG, "Adding widget from drop");
}
@@ -1678,7 +1784,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
}
void addAppWidgetImpl(int appWidgetId, ItemInfo info,
AppWidgetHostView boundWidget, WidgetAddFlowHandler addFlowHandler, int delay) {
AppWidgetHostView boundWidget, WidgetAddFlowHandler addFlowHandler, int delay) {
if (!addFlowHandler.startConfigActivity(this, appWidgetId, info, REQUEST_CREATE_APPWIDGET)) {
// If the configuration flow was not started, add the widget
@@ -1695,7 +1801,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
}
public void addPendingItem(PendingAddItemInfo info, int container, int screenId,
int[] cell, int spanX, int spanY) {
int[] cell, int spanX, int spanY) {
info.container = container;
info.screenId = screenId;
if (cell != null) {
@@ -1715,7 +1821,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
break;
default:
throw new IllegalStateException("Unknown item type: " + info.itemType);
}
}
}
/**
@@ -1771,7 +1877,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
}
FolderIcon addFolder(CellLayout layout, int container, final int screenId, int cellX,
int cellY) {
int cellY) {
final FolderInfo folderInfo = new FolderInfo();
folderInfo.title = getText(R.string.folder_name);
@@ -1790,8 +1896,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
/**
* Unbinds the view for the specified item, and removes the item and all its children.
*
* @param v the view being removed.
* @param itemInfo the {@link ItemInfo} for this view.
* @param v the view being removed.
* @param itemInfo the {@link ItemInfo} for this view.
* @param deleteFromDb whether or not to delete this item from the db.
*/
public boolean removeItem(View v, final ItemInfo itemInfo, boolean deleteFromDb) {
@@ -1828,7 +1934,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
return (event.getKeyCode() == KeyEvent.KEYCODE_HOME) || super.dispatchKeyEvent(event);
@@ -1892,7 +1997,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
@Override
public int getCurrentState() {
if(mStateManager.getState() == LauncherState.ALL_APPS) {
if (mStateManager.getState() == LauncherState.ALL_APPS) {
return StatsLogUtils.LAUNCHER_STATE_ALLAPPS;
} else if (mStateManager.getState() == OVERVIEW) {
return StatsLogUtils.LAUNCHER_STATE_OVERVIEW;
@@ -1919,7 +2024,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
}
public boolean startActivitySafely(View v, Intent intent, ItemInfo item,
@Nullable String sourceContainer) {
@Nullable String sourceContainer) {
if (TestProtocol.sDebugTracing) {
android.util.Log.d(TestProtocol.NO_START_TAG,
"startActivitySafely outer");
@@ -2020,7 +2125,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
/**
* Refreshes the shortcuts shown on the workspace.
*
* <p>
* Implementation of the method from LauncherModel.Callbacks.
*/
public void startBinding() {
@@ -2089,7 +2194,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
@Override
public void bindAppsAdded(IntArray newScreens, ArrayList<ItemInfo> addNotAnimated,
ArrayList<ItemInfo> addAnimated) {
ArrayList<ItemInfo> addAnimated) {
// Add the new screens
if (newScreens != null) {
bindAddScreens(newScreens);
@@ -2110,7 +2215,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
/**
* Bind the items start-end from the list.
*
* <p>
* Implementation of the method from LauncherModel.Callbacks.
*/
@Override
@@ -2157,7 +2262,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
throw new RuntimeException("Invalid Item Type");
}
/*
/*
* Remove colliding items.
*/
if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
@@ -2408,7 +2513,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
/**
* Callback saying that there aren't any more items to bind.
*
* <p>
* Implementation of the method from LauncherModel.Callbacks.
*/
public void finishBindingItems(int pageBoundFirst) {
@@ -2449,7 +2554,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
/**
* Add the icons for all apps.
*
* <p>
* Implementation of the method from LauncherModel.Callbacks.
*/
public void bindAllApplications(ArrayList<AppInfo> apps) {
@@ -2467,7 +2572,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
/**
* A package was updated.
*
* <p>
* Implementation of the method from LauncherModel.Callbacks.
*/
@Override
@@ -2500,7 +2605,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
/**
* Update the state of a package, typically related to install state.
*
* <p>
* Implementation of the method from LauncherModel.Callbacks.
*/
@Override
@@ -2639,8 +2744,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
if (focusedView instanceof BubbleTextView
&& focusedView.getTag() instanceof ItemInfo
&& mAccessibilityDelegate.performAction(focusedView,
(ItemInfo) focusedView.getTag(),
LauncherAccessibilityDelegate.DEEP_SHORTCUTS)) {
(ItemInfo) focusedView.getTag(),
LauncherAccessibilityDelegate.DEEP_SHORTCUTS)) {
PopupContainerWithArrow.getOpen(this).requestFocus();
return true;
}

View File

@@ -0,0 +1,47 @@
package com.android.uiuios;
import android.app.Application;
import android.content.Context;
public class MyApplication extends Application {
private static MyApplication app;
public static MyApplication getInstance() {
return app;
}
@Override
public void onCreate() {
super.onCreate();
app = this;
}
private String appPackageName;
private long runTime = 0;
private long onClickTime = 0;
public void setOnClickTime(long time) {
this.onClickTime = time;
}
public long getOnClickTime() {
return onClickTime;
}
public void setAppPackageName(String name) {
this.appPackageName = name;
}
public String getAppPackageName() {
return appPackageName;
}
public void setTime(long time) {
this.runTime = time;
}
public long getRunTime() {
return runTime;
}
}

View File

@@ -0,0 +1,127 @@
package com.android.uiuios.Statistics;
import android.app.usage.UsageStats;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.SystemClock;
public class AppInformation {
private UsageStats usageStats;
private String packageName;
private String label;
private Drawable Icon;
private long UsedTimebyDay; //milliseconds
private Context context;
private int times;
public AppInformation(UsageStats usageStats, Context context) {
this.usageStats = usageStats;
this.context = context;
try {
GenerateInfo();
} catch (PackageManager.NameNotFoundException | IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
}
private void GenerateInfo() throws PackageManager.NameNotFoundException, NoSuchFieldException, IllegalAccessException {
PackageManager packageManager = context.getPackageManager();
this.packageName = usageStats.getPackageName();
if (this.packageName != null && !this.packageName.equals("")) {
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(this.packageName, 0);
this.label = (String) packageManager.getApplicationLabel(applicationInfo);
this.UsedTimebyDay = usageStats.getTotalTimeInForeground();
this.times = (Integer) usageStats.getClass().getDeclaredField("mLaunchCount").get(usageStats);
if (this.UsedTimebyDay > 0) {
this.Icon = applicationInfo.loadIcon(packageManager);
}
}
}
public UsageStats getUsageStats() {
return usageStats;
}
public int getTimes() {
return times;
}
public void setTimes(int times) {
this.times = times;
}
public void setUsedTimebyDay(long usedTimebyDay) {
this.UsedTimebyDay = usedTimebyDay;
}
public Drawable getIcon() {
return Icon;
}
public long getUsedTimebyDay() {
return UsedTimebyDay;
}
public String getLabel() {
return label;
}
public String getPackageName() {
return packageName;
}
private long timeStampMoveToForeground = -1;
private long timeStampMoveToBackGround = -1;
public void setTimeStampMoveToForeground(long timeStampMoveToForeground) {
// if (timeStampMoveToForeground > bootTime()){
// timesPlusPlus();
// }
this.timeStampMoveToForeground = timeStampMoveToForeground;
}
public void timesPlusPlus(){
times++;
}
public void setTimeStampMoveToBackGround(long timeStampMoveToBackGround) {
this.timeStampMoveToBackGround = timeStampMoveToBackGround;
}
public long getTimeStampMoveToBackGround() {
return timeStampMoveToBackGround;
}
public long getTimeStampMoveToForeground() {
return timeStampMoveToForeground;
}
public void calculateRunningTime() {
if (timeStampMoveToForeground < 0 || timeStampMoveToBackGround < 0) {
return;
}
if (timeStampMoveToBackGround > timeStampMoveToForeground) {
UsedTimebyDay += (timeStampMoveToBackGround - timeStampMoveToForeground);
timeStampMoveToForeground = -1;
timeStampMoveToBackGround = -1;
}
}
// 返回开机时间,单位微妙
public static long bootTime() {
return System.currentTimeMillis() - SystemClock.elapsedRealtime();
}
}

View File

@@ -0,0 +1,274 @@
package com.android.uiuios.Statistics;
import android.annotation.TargetApi;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.os.Build;
import androidx.annotation.RequiresApi;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import static com.android.uiuios.Statistics.AppInformation.bootTime;
public class StatisticsInfo {
final public static int DAY = 0;
final public static int WEEK = 1;
final public static int MONTH = 2;
final public static int YEAR = 3;
private ArrayList<AppInformation> ShowList;
private ArrayList<AppInformation> AppInfoList;
private List<UsageStats> result;
private long totalTime;
private int totalTimes;
private int style;
public StatisticsInfo(Context context) {
try {
this.style = 0;
setUsageStatsList(context);
setShowList();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
//将次数和时间为0的应用信息过滤掉
private void setShowList() {
this.ShowList = new ArrayList<>();
totalTime = 0;
for (int i = 0; i < AppInfoList.size(); i++) {
if (AppInfoList.get(i).getUsedTimebyDay() > 0) { //&& AppInfoList.get(i).getTimes() > 0) {
this.ShowList.add(AppInfoList.get(i));
totalTime += AppInfoList.get(i).getUsedTimebyDay();
totalTimes += AppInfoList.get(i).getTimes();
}
}
//将显示列表中的应用按显示顺序排序
for (int i = 0; i < this.ShowList.size() - 1; i++) {
for (int j = 0; j < this.ShowList.size() - i - 1; j++) {
if (this.ShowList.get(j).getUsedTimebyDay() < this.ShowList.get(j + 1).getUsedTimebyDay()) {
AppInformation temp = this.ShowList.get(j);
this.ShowList.set(j, this.ShowList.get(j + 1));
this.ShowList.set(j + 1, temp);
}
}
}
}
//统计当天的应用使用时间
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void setUsageStatsList(Context context) throws NoSuchFieldException {
UsageStatsManager m = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
this.AppInfoList = new ArrayList<>();
if (m != null) {
Calendar calendar = Calendar.getInstance();
long now = calendar.getTimeInMillis();
long begintime = getBeginTime();
if (style == DAY) {
this.result = m.queryUsageStats(UsageStatsManager.INTERVAL_BEST, begintime, now);
AppInfoList = getAccurateDailyStatsList(context, result, m, begintime, now);
} else {
if (style == WEEK)
this.result = m.queryUsageStats(UsageStatsManager.INTERVAL_WEEKLY, begintime, now);
else if (style == MONTH)
this.result = m.queryUsageStats(UsageStatsManager.INTERVAL_MONTHLY, begintime, now);
else if (style == YEAR)
this.result = m.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY, begintime, now);
else {
this.result = m.queryUsageStats(UsageStatsManager.INTERVAL_BEST, begintime, now);
}
List<UsageStats> Mergeresult = MergeList(this.result);
for (UsageStats usageStats : Mergeresult) {
this.AppInfoList.add(new AppInformation(usageStats, context));
}
calculateLaunchTimesAfterBootOn(context, AppInfoList);
}
}
}
/**
* 根据UsageEvents来对当天的操作次数和开机后运行时间来进行精确计算
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private ArrayList<AppInformation> getAccurateDailyStatsList(Context context, List<UsageStats> result, UsageStatsManager m, long begintime, long now) {
//针对每个packageName建立一个 使用信息
HashMap<String, AppInformation> mapData = new HashMap<>();
//得到包名
for (UsageStats stats : result) {
if (stats.getLastTimeUsed() > begintime && stats.getTotalTimeInForeground() > 0) {
if (mapData.get(stats.getPackageName()) == null) {
AppInformation information = new AppInformation(stats, context);
//重置总运行时间 开机操作次数
information.setTimes(0);
information.setUsedTimebyDay(0);
mapData.put(stats.getPackageName(), information);
}
}
}
//这个是相对比较精确的
long bootTime = bootTime();
UsageEvents events = m.queryEvents(bootTime, now);
UsageEvents.Event e = new UsageEvents.Event();
while (events.hasNextEvent()) {
events.getNextEvent(e);
String packageName = e.getPackageName();
AppInformation information = mapData.get(packageName);
if (information == null) {
continue;
}
//这里在同时计算开机后的操作次数和运行时间,所以如果获取到的时间戳是昨天的话就得过滤掉 continue
if (e.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
information.timesPlusPlus();
if (e.getTimeStamp() < begintime){
continue;
}
information.setTimeStampMoveToForeground(e.getTimeStamp());
} else if (e.getEventType() == UsageEvents.Event.MOVE_TO_BACKGROUND) {
if (e.getTimeStamp() < begintime){
continue;
}
information.setTimeStampMoveToBackGround(e.getTimeStamp());
//当前应用是在昨天进入的前台0点后转入了后台所以会先得到MOVE_TO_BACKGROUND 的timeStamp
if (information.getTimeStampMoveToForeground() < 0) {
//从今天开始计算即可
information.setTimeStampMoveToForeground(begintime);
}
}
information.calculateRunningTime();
}
//再计算一次当前应用的运行时间因为当前应用最后得不到MOVE_TO_BACKGROUND 的timeStamp
AppInformation information = mapData.get(context.getPackageName());
information.setTimeStampMoveToBackGround(now);
information.calculateRunningTime();
return new ArrayList<>(mapData.values());
}
/**
* 根据UsageEvents 精确计算APP开机的启动(activity打开的)次数
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void calculateLaunchTimesAfterBootOn(Context context, List<AppInformation> AppInfoList) {
UsageStatsManager m = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
if (m == null || AppInfoList == null || AppInfoList.size() < 1) {
return;
}
//针对每个packageName建立一个 使用信息
HashMap<String, AppInformation> mapData = new HashMap<>();
UsageEvents events = m.queryEvents(bootTime(), System.currentTimeMillis());
for (AppInformation information : AppInfoList) {
mapData.put(information.getPackageName(), information);
information.setTimes(0);
}
UsageEvents.Event e = new UsageEvents.Event();
while (events.hasNextEvent()) {
events.getNextEvent(e);
String packageName = e.getPackageName();
AppInformation information = mapData.get(packageName);
if (information == null) {
continue;
}
if (e.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
information.timesPlusPlus();
}
}
}
private long getBeginTime() {
Calendar calendar = Calendar.getInstance();
long begintime;
if (style == WEEK) {
//int weekDay = calendar.get(Calendar.DAY_OF_WEEK);
calendar.add(Calendar.DATE, -7);
begintime = calendar.getTimeInMillis();
} else if (style == MONTH) {
//int mounthDay = calendar.get(Calendar.DAY_OF_MONTH);
calendar.add(Calendar.DATE, -30);
begintime = calendar.getTimeInMillis();
} else if (style == YEAR) {
calendar.add(Calendar.YEAR, -1);
begintime = calendar.getTimeInMillis();
} else {
//剩下的输入均显示当天的数据
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
calendar.add(Calendar.SECOND, -1 * second);
calendar.add(Calendar.MINUTE, -1 * minute);
calendar.add(Calendar.HOUR, -1 * hour);
begintime = calendar.getTimeInMillis();
}
return begintime;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private List<UsageStats> MergeList(List<UsageStats> result) {
List<UsageStats> Mergeresult = new ArrayList<>();
long begintime;
begintime = getBeginTime();
for (int i = 0; i < result.size(); i++) {
if (result.get(i).getLastTimeUsed() > begintime) {
int num = FoundUsageStats(Mergeresult, result.get(i));
if (num >= 0) {
UsageStats u = Mergeresult.get(num);
u.add(result.get(i));
Mergeresult.set(num, u);
} else Mergeresult.add(result.get(i));
}
}
return Mergeresult;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private int FoundUsageStats(List<UsageStats> Mergeresult, UsageStats usageStats) {
for (int i = 0; i < Mergeresult.size(); i++) {
if (Mergeresult.get(i).getPackageName().equals(usageStats.getPackageName())) {
return i;
}
}
return -1;
}
public long getTotalTime() {
return totalTime;
}
public int getTotalTimes() {
return totalTimes;
}
public ArrayList<AppInformation> getShowList() {
return ShowList;
}
}

View File

@@ -0,0 +1,31 @@
package com.android.uiuios.TTUtils;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.Log;
public class APKUtils {
//判断是否为系统应用
public static boolean isSystemApp(Context context, String pkgName) {
boolean isSystemApp = false;
PackageInfo pi = null;
try {
PackageManager pm = context.getPackageManager();
pi = pm.getPackageInfo(pkgName, 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
Log.e("isSystemApp", e.getMessage(), e);
}
// 是系统中已安装的应用
if (pi != null) {
boolean isSysApp = (pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1;
boolean isSysUpd = (pi.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 1;
isSystemApp = isSysApp || isSysUpd;
}
return isSystemApp;
}
}

View File

@@ -0,0 +1,34 @@
package com.android.uiuios.TTUtils;
import android.annotation.SuppressLint;
import android.os.Build;
import android.util.Log;
import java.lang.reflect.Method;
public class Utils {
/**
* 获取设备序列号
*
* @return
*/
@SuppressLint({"MissingPermission", "NewApi"})
public static String getSerial() {
String serial = "unknow";
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {//9.0+
serial = Build.getSerial();
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {//8.0+
serial = Build.SERIAL;
} else {//8.0-
Class<?> c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("get", String.class);
serial = (String) get.invoke(c, "ro.serialno");
}
} catch (Exception e) {
e.printStackTrace();
Log.e("e", "读取设备序列号异常:" + e.toString());
}
return serial;
}
}

View File

@@ -0,0 +1,25 @@
package com.android.uiuios.network;
import androidx.annotation.NonNull;
import java.io.Serializable;
public class BaseResponse<T> implements Serializable {
private static final long serialVersionUID = 5468533687801294972L;
public int code;
public String msg;
public T data;
@NonNull
@Override
public String toString() {
return "{\n" +//
"\tcode=" + code + "\n" +//
"\tmsg='" + msg + "\'\n" +//
"\tdata=" + data + "\n" +//
'}';
}
}

View File

@@ -0,0 +1,55 @@
package com.android.uiuios.network;
import android.os.Environment;
import com.android.uiuios.network.api.addAppLog;
import java.io.File;
import java.util.concurrent.TimeUnit;
import okhttp3.Cache;
import okhttp3.OkHttpClient;
import retrofit2.CallAdapter;
import retrofit2.Converter;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
public class NetWorkManager {
private static final String ROOT_URL = URLPath.ROOT_URL;
private static final long cacheSize = 1024 * 1024 * 20;// 缓存文件最大限制大小20M
private static String cacheDirectory = Environment.getExternalStorageDirectory() + "/okttpcaches"; // 设置缓存文件路径
private static Cache cache = new Cache(new File(cacheDirectory), cacheSize); //
private static final OkHttpClient client;
static {
//如果无法生存缓存文件目录,检测权限使用已经加上,检测手机是否把文件读写权限禁止了
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(8, TimeUnit.SECONDS); // 设置连接超时时间
builder.writeTimeout(8, TimeUnit.SECONDS);// 设置写入超时时间
builder.readTimeout(8, TimeUnit.SECONDS);// 设置读取数据超时时间
builder.retryOnConnectionFailure(true);// 设置进行连接失败重试
builder.cache(cache);// 设置缓存
client = builder.build();
}
private static CallAdapter.Factory rxJavaCallAdapterFactory = RxJava2CallAdapterFactory.create();
private static Converter.Factory gsonConverterFactory = GsonConverterFactory.create();
private static addAppLog applogControl;
public static addAppLog getapplogControl() {
if (null == applogControl) {
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.baseUrl(ROOT_URL)
.addConverterFactory(gsonConverterFactory)
.addCallAdapterFactory(rxJavaCallAdapterFactory)
.build();
applogControl = retrofit.create(addAppLog.class);
}
return applogControl;
}
}

View File

@@ -0,0 +1,6 @@
package com.android.uiuios.network;
public class URLPath {
public static final String ROOT_URL = "http://homework.uiuios.com/android/app/";
public static final String APP_LOG = ROOT_URL+"addAppLog";
}

View File

@@ -0,0 +1,21 @@
package com.android.uiuios.network.api;
import com.android.uiuios.network.BaseResponse;
import com.android.uiuios.network.URLPath;
import io.reactivex.Observable;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;
public interface addAppLog {
@FormUrlEncoded
@POST(URLPath.APP_LOG)
Observable<BaseResponse> addLog(
@Field("sn") String sn,
@Field("packageName") String packageName,
@Field("versionCode") long versionCode,
@Field("createTime") long createTime,
@Field("type") long type
);
}

View File

@@ -25,9 +25,15 @@ import static com.android.uiuios.Launcher.REQUEST_RECONFIGURE_APPWIDGET;
import static com.android.uiuios.model.AppLaunchTracker.CONTAINER_ALL_APPS;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Process;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
@@ -41,18 +47,34 @@ import com.android.uiuios.ItemInfo;
import com.android.uiuios.Launcher;
import com.android.uiuios.LauncherAppWidgetInfo;
import com.android.uiuios.LauncherAppWidgetProviderInfo;
import com.android.uiuios.MyApplication;
import com.android.uiuios.PromiseAppInfo;
import com.android.uiuios.R;
import com.android.uiuios.Statistics.AppInformation;
import com.android.uiuios.Statistics.StatisticsInfo;
import com.android.uiuios.TTUtils.APKUtils;
import com.android.uiuios.TTUtils.Utils;
import com.android.uiuios.WorkspaceItemInfo;
import com.android.uiuios.compat.AppWidgetManagerCompat;
import com.android.uiuios.folder.Folder;
import com.android.uiuios.folder.FolderIcon;
import com.android.uiuios.network.BaseResponse;
import com.android.uiuios.network.NetWorkManager;
import com.android.uiuios.network.api.addAppLog;
import com.android.uiuios.testing.TestProtocol;
import com.android.uiuios.util.PackageManagerHelper;
import com.android.uiuios.views.FloatingIconView;
import com.android.uiuios.widget.PendingAppWidgetHostView;
import com.android.uiuios.widget.WidgetAddFlowHandler;
import java.util.Arrays;
import java.util.List;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
/**
* Class for handling clicks on workspace and all-apps items
*/
@@ -94,6 +116,31 @@ public class ItemClickHandler {
Object tag = v.getTag();
if (tag instanceof WorkspaceItemInfo) {
onClickAppShortcut(v, (WorkspaceItemInfo) tag, launcher, sourceContainer);
String packageName = ((WorkspaceItemInfo) tag).getTargetComponent().getPackageName();
Context context = MyApplication.getInstance().getApplicationContext();
AppInformation app = null;
try {
app = getInfoFromPackageName(packageName);
} catch (Exception e) {
Log.e("onClick", e.getMessage());
}
if (app != null) {
Log.e("fht", "运行时间: " + DateUtils.formatElapsedTime(app.getUsedTimebyDay() / 1000));
Log.e("fht", "运行时间: " + app.getUsedTimebyDay() / 1000);
MyApplication.getInstance().setTime(app.getUsedTimebyDay() / 1000);
} else {
Log.e("fht", "首次运行:" + "包名:" + packageName);
MyApplication.getInstance().setTime(0);
}
if (!APKUtils.isSystemApp(context, packageName) && !Arrays.asList(packages).contains(packageName)) {
// HTTPInterface.sendTimeLog(handler, userInfo, ((ShortcutInfo) tag).title.toString(), 1, 0);
SendOpenApp(packageName);
}
MyApplication.getInstance().setAppPackageName(packageName);
MyApplication.getInstance().setOnClickTime(System.currentTimeMillis());
} else if (tag instanceof FolderInfo) {
if (v instanceof FolderIcon) {
onClickFolderIcon(v);
@@ -104,7 +151,7 @@ public class ItemClickHandler {
"onClick 4");
}
startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher,
sourceContainer == null ? CONTAINER_ALL_APPS: sourceContainer);
sourceContainer == null ? CONTAINER_ALL_APPS : sourceContainer);
} else if (tag instanceof LauncherAppWidgetInfo) {
if (v instanceof PendingAppWidgetHostView) {
onClickPendingWidget((PendingAppWidgetHostView) v, launcher);
@@ -112,6 +159,82 @@ public class ItemClickHandler {
}
}
public static String[] packages = {
"com.appstore.uiui",
"com.uiuios.updatetools",
"com.info.sn",
"com.android.uiuios",
"com.easyold.uiuios",
"com.jiaoguanyi.store"
};
public static AppInformation getInfoFromPackageName(String packageName) {
List<AppInformation> list;
AppInformation app = null;
StatisticsInfo statisticsInfo = new StatisticsInfo(MyApplication.getInstance().getApplicationContext());
list = statisticsInfo.getShowList();
for (AppInformation appInformation : list) {
String name = appInformation.getPackageName();
if (appInformation.getPackageName().equals(packageName)) {
return appInformation;
}
}
return app;
}
private static void SendOpenApp(String packageName) {
PackageManager pm = MyApplication.getInstance().getPackageManager();
PackageInfo appInfo = null;
try {
appInfo = pm.getPackageInfo(packageName, 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
if (null != appInfo) {
long appVersionCode;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
appVersionCode = appInfo.getLongVersionCode();
} else {
appVersionCode = appInfo.versionCode;
}
addAppLog appLog = NetWorkManager.getapplogControl();
String sn = Utils.getSerial();
appLog.addLog(sn, packageName, appVersionCode, System.currentTimeMillis()/1000, 1)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<BaseResponse>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(BaseResponse baseResponse) {
int code = baseResponse.code;
if (code == 200) {
Log.e("SendOpenApp", "onNext:" + code + baseResponse.data);
} else {
Log.e("SendOpenApp", "onNext:" + code + baseResponse.msg);
}
}
@Override
public void onError(Throwable e) {
Log.e("SendOpenApp", "onError: " + e.getMessage());
}
@Override
public void onComplete() {
}
});
}
}
/**
* Event handler for a folder icon click.
*
@@ -160,7 +283,7 @@ public class ItemClickHandler {
}
private static void onClickPendingAppItem(View v, Launcher launcher, String packageName,
boolean downloadStarted) {
boolean downloadStarted) {
if (downloadStarted) {
// If the download has started, simply direct to the market app.
startMarketIntentForPackage(v, launcher, packageName);
@@ -189,7 +312,7 @@ public class ItemClickHandler {
* @param v The view that was clicked. Must be a tagged with a {@link WorkspaceItemInfo}.
*/
public static void onClickAppShortcut(View v, WorkspaceItemInfo shortcut, Launcher launcher,
@Nullable String sourceContainer) {
@Nullable String sourceContainer) {
if (shortcut.isDisabled()) {
final int disabledFlags = shortcut.runtimeStatusFlags
& WorkspaceItemInfo.FLAG_DISABLED_MASK;
@@ -233,7 +356,7 @@ public class ItemClickHandler {
}
private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher,
@Nullable String sourceContainer) {
@Nullable String sourceContainer) {
if (TestProtocol.sDebugTracing) {
android.util.Log.d(TestProtocol.NO_START_TAG,
"startAppShortcutOrInfoActivity");