version:1.8

fix:应用使用记录
add:
This commit is contained in:
2021-12-25 16:46:21 +08:00
parent ed8310da47
commit 3db193a84e
20 changed files with 716 additions and 150 deletions

View File

@@ -51,6 +51,7 @@ import android.os.Process;
import android.os.StrictMode;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.method.TextKeyListener;
import android.util.Log;
import android.util.SparseArray;
@@ -70,6 +71,7 @@ import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.aoleyun.os.DropTarget.DragObject;
import com.aoleyun.os.Statistics.AppInformation;
import com.aoleyun.os.TTUtils.APKUtils;
import com.aoleyun.os.TTUtils.Utils;
import com.aoleyun.os.accessibility.LauncherAccessibilityDelegate;
@@ -104,7 +106,7 @@ import com.aoleyun.os.model.ModelWriter;
import com.aoleyun.os.network.AppPasswdBean;
import com.aoleyun.os.network.BaseResponse;
import com.aoleyun.os.network.HTTPInterface;
import com.aoleyun.os.network.NetWorkManager;
import com.aoleyun.os.network.NetworkManager;
import com.aoleyun.os.network.NewestAppUpdateResult;
import com.aoleyun.os.network.api.AddAppLog;
import com.aoleyun.os.notification.NotificationListener;
@@ -119,6 +121,7 @@ import com.aoleyun.os.testing.TestProtocol;
import com.aoleyun.os.touch.ItemClickHandler;
import com.aoleyun.os.uioverrides.UiFactory;
import com.aoleyun.os.uiuiutils.JGYUtils;
import com.aoleyun.os.uiuiutils.TimeUtils;
import com.aoleyun.os.userevent.nano.LauncherLogProto;
import com.aoleyun.os.userevent.nano.LauncherLogProto.Action;
import com.aoleyun.os.userevent.nano.LauncherLogProto.ContainerType;
@@ -194,6 +197,7 @@ import static com.aoleyun.os.logging.LoggerUtils.newTarget;
import static com.aoleyun.os.states.RotationHelper.REQUEST_NONE;
import static com.aoleyun.os.util.RaceConditionTracker.ENTER;
import static com.aoleyun.os.util.RaceConditionTracker.EXIT;
import static com.aoleyun.os.touch.ItemClickHandler.getInfoFromPackageName;
/**
* Default launcher application.
@@ -588,17 +592,18 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_DATE_CHANGED.equals(intent.getAction())) {
Log.e("fht", "TimeChangedReceiver:" + "data changed");
// Log.e("fht", "TimeChangedReceiver:" + "data changed");
} else if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
Log.e("fht", "TimeChangedReceiver:" + "time changed");
// Log.e("fht", "TimeChangedReceiver:" + "time changed");
} else if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
Log.e("fht", "TimeChangedReceiver:" + "timezone changed");
// Log.e("fht", "TimeChangedReceiver:" + "timezone changed");
} else if (Intent.ACTION_TIME_TICK.equals(intent.getAction())) {
Log.e("fht", "TimeChangedReceiver:" + "time tick");
// Log.e("fht", "TimeChangedReceiver:" + "time tick");
}
}
}
@Override
public void onEnterAnimationComplete() {
super.onEnterAnimationComplete();
@@ -1085,38 +1090,69 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
@Override
protected void onStart() {
Log.e(TAG, "onStart: " + TimeUtils.getInstance().isNormalTime());
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "Launcher.onStart");
}
RaceConditionTracker.onEvent(ON_START_EVT, ENTER);
super.onStart();
removeRecentTask();
String packagename = MyApplication.getInstance().getAppPackageName();
String packagename = TimeUtils.getInstance().getAppPackageName();
Log.e("SendcloseApp", "packagename=" + packagename);
TimeUtils.getInstance().setEndTime(System.currentTimeMillis());
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);
// }
AppInformation app = getInfoFromPackageName(packagename);
if (app != null) {
long time = app.getUsedTimebyDay() / 1000;
Log.e("fht", "返回运行时间: " + DateUtils.formatElapsedTime(time));
Log.e("fht", "返回运行时间: " + time);
NetworkManager.getInstance().getAppUsageRecordControl()
.sendAppUsageRecord(Utils.getSerial(),
app.getLabel(), app.getPackageName(),
TimeUtils.getInstance().getStartTime()/1000,
TimeUtils.getInstance().getEndTime()/1000)
.subscribe(new Observer<BaseResponse>() {
@Override
public void onSubscribe(Disposable d) {
Log.e("onStart", "onSubscribe: ");
}
@Override
public void onNext(BaseResponse baseResponse) {
Log.e("onStart", "onNext: " + baseResponse);
}
@Override
public void onError(Throwable e) {
Log.e("onStart", "onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.e("onStart", "onComplete: ");
}
});
// if (userInfo != null) {
// HTTPInterface.sendTimeLog(handler, userInfo, app.getLabel(), 2, time - MyApplication.getInstance().getRunTime());
// } else {
// Log.e("fht", "userInfo = null");
// }
//设为空值
TimeUtils.getInstance().setAppPackageName("");
} 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) {
@@ -1126,7 +1162,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
RaceConditionTracker.onEvent(ON_START_EVT, EXIT);
}
private static void SendcloseApp(String packageName) {
private void SendcloseApp(String packageName) {
PackageManager pm = MyApplication.getInstance().getPackageManager();
PackageInfo appInfo = null;
try {
@@ -1141,7 +1177,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
} else {
appVersionCode = appInfo.versionCode;
}
AddAppLog appLog = NetWorkManager.getInstance().getapplogControl();
AddAppLog appLog = NetworkManager.getInstance().getapplogControl();
String sn = Utils.getSerial();
appLog.addLog(sn, packageName, appVersionCode, System.currentTimeMillis() / 1000, 2)
.subscribeOn(Schedulers.io())
@@ -1246,8 +1282,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
TraceHelper.endSection("ON_RESUME");
RaceConditionTracker.onEvent(ON_RESUME_EVT, EXIT);
isForeground = true;
MyApplication.getInstance().setAppPackageName(BuildConfig.APPLICATION_ID);
MyApplication.getInstance().setOnClickTime(System.currentTimeMillis());
// TimeUtils.getInstance().setAppPackageName(BuildConfig.APPLICATION_ID);
// TimeUtils.getInstance().setStartTime(System.currentTimeMillis());
HTTPInterface.getAppPasswd();
start.onstar(System.currentTimeMillis());
String always_top_packagename = Settings.System.getString(getContentResolver(), "always_top_packagename");
@@ -1316,7 +1352,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
};
private void checkUpdate() {
NetWorkManager.getInstance().getCheckUpdateObservable()
NetworkManager.getInstance().getCheckUpdateObservable()
.getCheckUpdate(BuildConfig.APPLICATION_ID,
BuildConfig.VERSION_CODE,
JGYUtils.getInstance().checkAppPlatform())

View File

@@ -273,7 +273,7 @@ public class LauncherModel extends BroadcastReceiver
@Override
public void onReceive(Context context, Intent intent) {
if (DEBUG_RECEIVER) Log.d(TAG, "onReceive intent=" + intent);
Log.e("fht","onReceive intent=" + intent);
// Log.e("fht","onReceive intent=" + intent);
final String action = intent.getAction();
if (Intent.ACTION_LOCALE_CHANGED.equals(action)) {

View File

@@ -101,7 +101,7 @@ public class APKUtils {
return isSystemApp;
}
//获取教管易版本号
//获取APP版本号
public static String getAPPVersionName(Context context, String packageName) {
String versionName = "0";

View File

@@ -0,0 +1,103 @@
package com.aoleyun.os.TTUtils;
import android.text.TextUtils;
import android.util.Log;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class CmdUtil {
private static final String TAG = "CmdUtil";
private static final String COMMAND_SH = "sh";
private static final String COMMAND_EXIT = "exit\n";
private static final String COMMAND_LINE_END = "\n";
/**
* 运行命令
*
* @param command 命令
* @return 结果
*/
public static Result execute(String command) {
Log.i(TAG, "execute() command = " + command);
Result result = new Result();
if (TextUtils.isEmpty(command)) {
Log.w(TAG, "WARNING: command should not be null or empty");
return result;
}
Process process = null;
DataOutputStream dos = null;
try {
process = Runtime.getRuntime().exec(COMMAND_SH);
dos = new DataOutputStream(process.getOutputStream());
dos.write(command.trim().getBytes());
dos.writeBytes(COMMAND_LINE_END);
dos.flush();
dos.writeBytes(COMMAND_EXIT);
dos.flush();
result.code = process.waitFor();
result.success = readBuffer(new BufferedReader(new InputStreamReader(process.getInputStream())));
result.error = readBuffer(new BufferedReader(new InputStreamReader(process.getErrorStream())));
Log.i(TAG, "result = " + result);
} catch (IOException ioe) {
ioe.printStackTrace();
Log.e(TAG, ioe.getMessage());
} catch (InterruptedException ie) {
ie.printStackTrace();
Log.e(TAG, ie.getMessage());
} finally {
try {
if (null != dos) {
dos.close();
}
} catch (IOException ioe) {
ioe.printStackTrace();
Log.e(TAG, ioe.getMessage());
}
if (null != process) {
process.destroy();
}
}
return result;
}
private static String readBuffer(BufferedReader bufferedReader) throws IOException {
StringBuilder sb = new StringBuilder();
String s;
while ((s = bufferedReader.readLine()) != null) {
sb.append(s);
}
return sb.toString();
}
/**
* Command执行结果
*/
public static final class Result {
public static final int SUCCESS = 0;
public static final int ERROR = -1;
public int code = ERROR;
public String error;
public String success;
@Override
public String toString() {
return "Result{" +
"code=" + code +
", error='" + error + '\'' +
", success='" + success + '\'' +
'}';
}
}
}

View File

@@ -10,9 +10,10 @@ import com.aoleyun.os.TTUtils.ToastUtil;
import com.aoleyun.os.TTUtils.Utils;
import com.aoleyun.os.jpush.TagAliasOperatorHelper;
import com.aoleyun.os.network.HTTPInterface;
import com.aoleyun.os.network.NetWorkManager;
import com.aoleyun.os.network.NetworkManager;
import com.aoleyun.os.network.URLPath;
import com.aoleyun.os.uiuiutils.JGYUtils;
import com.aoleyun.os.uiuiutils.TimeUtils;
import com.arialyy.aria.core.Aria;
import com.tencent.mmkv.MMKV;
@@ -53,8 +54,9 @@ public class MyApplication extends Application {
String rootDir = MMKV.initialize(this);
Log.e(TAG, "onCreate: " + rootDir);
JGYUtils.init(this);
TimeUtils.init(this);
Aria.init(this);
NetWorkManager.init(this);
NetworkManager.init(this);
ToastUtil.init(this);
initJPush();
@@ -69,36 +71,7 @@ public class MyApplication extends Application {
setJpushTags();
}
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;
}
private void initAliasObservable() {
private void initAliasObservable() {
Log.e(TAG, "initAliasObservable: ");
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
@@ -193,7 +166,7 @@ public class MyApplication extends Application {
JPushInterface.setAlias(context, TagAliasOperatorHelper.sequence++, Utils.getSerial());
}
private void initTagObservable() {
private void initTagObservable() {
Log.e(TAG, "initTagObservable: ");
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
@@ -316,7 +289,7 @@ public class MyApplication extends Application {
private String key = "MGM3YmE1YTE2MjJkYmE3OGQ1YmQwMGNjOjFjOTJiODVjZjM0ODhiNTJkNDQyNDJlOA==";
synchronized public void cleanJpushAlias() {
synchronized public void cleanJpushAlias() {
//alias的绑定的设备超过10个但是alias应该是一个设备对应一个在重置设备后jpush的regid会变动所以需要清除
//https://docs.jiguang.cn/jpush/server/push/rest_api_v3_device/#_5
OkHttpClient client = new OkHttpClient();
@@ -340,7 +313,7 @@ public class MyApplication extends Application {
});
}
synchronized public void cleanJpushTag() {
synchronized public void cleanJpushTag() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(URLPath.DELETE_JPUSH_TAG + Utils.getSerial())

View File

@@ -294,7 +294,7 @@ public class IconCache extends BaseIconCache {
if (null != info) {
String name = info.getComponentName().getClassName();
Log.e("fht", "getDeskClockIcon:"+name);
// Log.e("fht", "getDeskClockIcon:"+name);
if (appClassNameList.indexOf(info.getComponentName().getClassName()) == -1) {
icon = BitmapUtils.getRoundedBitmap(mIconProvider.getIcon(info, mIconDpi, flattenDrawable), mContext);
} else {

View File

@@ -5,28 +5,15 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import com.aoleyun.os.base.MyApplication;
import com.aoleyun.os.TTUtils.APKUtils;
import com.aoleyun.os.network.AppPasswdBean;
import com.aoleyun.os.network.BaseResponse;
import com.aoleyun.os.network.HTTPInterface;
import com.aoleyun.os.network.NetWorkManager;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.tencent.mmkv.MMKV;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Iterator;
import java.util.List;
import cn.jpush.android.api.JPushInterface;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
/**
* 自定义接收器
@@ -147,7 +134,7 @@ public class MyReceiver extends BroadcastReceiver {
switch (message) {
case SEND_RUNNING_APP:
sendRunningApp(context);
HTTPInterface.SendRunningApp(context);
break;
case UPDATE_APP_LOCK:
HTTPInterface.getAppPasswd();
@@ -159,35 +146,4 @@ public class MyReceiver extends BroadcastReceiver {
}
private void sendRunningApp(Context context) {
String packageName = MyApplication.getInstance().getAppPackageName();
long time = MyApplication.getInstance().getOnClickTime();
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("app_package", packageName);
jsonObject.addProperty("version_name", APKUtils.getAPPVersionName(context, packageName));
jsonObject.addProperty("start_time", time / 1000);
String jsonString = jsonObject.toString();
NetWorkManager.getInstance().getRunningAppObservable(jsonString)
.subscribe(new Observer<BaseResponse>() {
@Override
public void onSubscribe(Disposable d) {
Log.e(TAG, "onSubscribe: ");
}
@Override
public void onNext(BaseResponse baseResponse) {
Log.e(TAG, "onSubscribe: " + baseResponse);
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: ");
}
});
}
}

View File

@@ -4,8 +4,10 @@ import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import com.aoleyun.os.TTUtils.APKUtils;
import com.aoleyun.os.jpush.TagAliasOperatorHelper;
import com.aoleyun.os.uiuiutils.JGYUtils;
import com.aoleyun.os.uiuiutils.TimeUtils;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
@@ -33,7 +35,7 @@ public class HTTPInterface {
private static final String TAG = HTTPInterface.class.getSimpleName();
public static void getAppPasswd() {
NetWorkManager.getInstance().getAppPasswordObservable()
NetworkManager.getInstance().getAppPasswordObservable()
.subscribe(new Observer<BaseResponse<List<AppPasswdBean>>>() {
@Override
public void onSubscribe(Disposable d) {
@@ -66,7 +68,7 @@ public class HTTPInterface {
}
synchronized public static void setJpushTags(final Context context) {
NetWorkManager.getInstance()
NetworkManager.getInstance()
.getJpushTagsObservable()
.subscribe(new Observer<BaseResponse>() {
@Override
@@ -115,6 +117,38 @@ public class HTTPInterface {
});
}
public static void SendRunningApp(Context context) {
String packageName = TimeUtils.getInstance().getAppPackageName();
long time = TimeUtils.getInstance().getStartTime();
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("app_package", packageName);
jsonObject.addProperty("version_name", APKUtils.getAPPVersionName(context, packageName));
jsonObject.addProperty("run_time", time / 1000);
String jsonString = jsonObject.toString();
NetworkManager.getInstance().getRunningAppObservable(jsonString)
.subscribe(new Observer<BaseResponse>() {
@Override
public void onSubscribe(Disposable d) {
Log.e("SendRunningApp", "onSubscribe: ");
}
@Override
public void onNext(BaseResponse baseResponse) {
Log.e("SendRunningApp", "onSubscribe: " + baseResponse);
}
@Override
public void onError(Throwable e) {
Log.e("SendRunningApp", "onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.e("SendRunningApp", "onComplete: ");
}
});
}
private static void setTag(Context context, Set set) {
TagAliasOperatorHelper.TagAliasBean tagAliasBean = new TagAliasOperatorHelper.TagAliasBean();
tagAliasBean.action = ACTION_SET;

View File

@@ -5,10 +5,12 @@ import android.os.Environment;
import com.aoleyun.os.TTUtils.Utils;
import com.aoleyun.os.network.api.AddAppLog;
import com.aoleyun.os.network.api.AppUsageRecordApi;
import com.aoleyun.os.network.api.CheckUpdate;
import com.aoleyun.os.network.api.GetAppPassword;
import com.aoleyun.os.network.api.GetJpushTagsApi;
import com.aoleyun.os.network.api.RunningApp;
import com.aoleyun.os.network.api.SendScreenshotApi;
import java.io.File;
import java.util.List;
@@ -25,12 +27,12 @@ import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
public class NetWorkManager {
private static NetWorkManager sInstance;
public class NetworkManager {
private static NetworkManager sInstance;
private Context mContext;
private static Retrofit mRetrofit;
private NetWorkManager(Context context) {
private NetworkManager(Context context) {
this.mContext = context;
if (null == mRetrofit) {
mRetrofit = new Retrofit.Builder()
@@ -44,12 +46,12 @@ public class NetWorkManager {
public static void init(Context context) {
if (sInstance == null) {
sInstance = new NetWorkManager(context);
sInstance = new NetworkManager(context);
}
}
public static NetWorkManager getInstance() {
public static NetworkManager getInstance() {
if (sInstance == null) {
throw new IllegalStateException("You must be init NetworkManager first");
}
@@ -80,7 +82,7 @@ public class NetWorkManager {
public Observable<BaseResponse> getRunningAppObservable(String json) {
return mRetrofit.create(RunningApp.class)
.sendAppInfo(Utils.getSerial(), json)
.sendRunningInfo(Utils.getSerial(), json)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
@@ -92,6 +94,14 @@ public class NetWorkManager {
.observeOn(AndroidSchedulers.mainThread());
}
public SendScreenshotApi getScreenshotApi() {
return mRetrofit.create(SendScreenshotApi.class);
}
public AddAppLog getapplogControl() {
return mRetrofit.create(AddAppLog.class);
}
/**
* 获取极光推送的tag
*
@@ -104,8 +114,10 @@ public class NetWorkManager {
.observeOn(AndroidSchedulers.mainThread());
}
public AddAppLog getapplogControl() {
return mRetrofit.create(AddAppLog.class);
public AppUsageRecordApi getAppUsageRecordControl() {
return mRetrofit.create(AppUsageRecordApi.class);
}
public CheckUpdate getCheckUpdateObservable() {

View File

@@ -3,7 +3,7 @@ package com.aoleyun.os.network;
public class URLPath {
public static final String ROOT_URL = "https://led.aoleyun.cn/api/";
public static final String APP_LOG = "app/addAppLog";
public static final String RUN_NEW_APP = "app/runNewApp";
public static final String RUN_NEW_APP = "And/runNewApp";
//更新
public final static String GET_NEWESTAPPUPDATE = "Silent/silent";
//是否有应用密码锁
@@ -14,7 +14,10 @@ public class URLPath {
public final static String GET_APP_PASSWD = "And/getApplicationLock";
//获取设备标签
public static final String GET_DEVICES_TAGS = "Sn/getSnTag";
//发送app使用时长
public static final String SEND_APP_RECORD = "And/appUsageRecord";
//上传截图
public static final String SEND_SCREENSHOT = "Screenshot/addImg";
//删除alias
public static final String DELETE_JPUSH_ALIAS = "https://device.jpush.cn/v3/aliases/";

View File

@@ -0,0 +1,22 @@
package com.aoleyun.os.network.api;
import com.aoleyun.os.network.BaseResponse;
import com.aoleyun.os.network.URLPath;
import io.reactivex.Observable;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;
public interface AppUsageRecordApi {
@FormUrlEncoded
@POST(value = URLPath.SEND_APP_RECORD)
Observable<BaseResponse> sendAppUsageRecord(
@Field("sn") String sn,
@Field("app_name") String app_name,
@Field("app_package") String app_package,
@Field("open_time") long open_time,
@Field("close_time") long close_time
);
}

View File

@@ -11,7 +11,7 @@ import retrofit2.http.POST;
public interface RunningApp {
@FormUrlEncoded
@POST(URLPath.RUN_NEW_APP)
Observable<BaseResponse> sendAppInfo(
Observable<BaseResponse> sendRunningInfo(
@Field("sn") String sn,
@Field("app") String app
);

View File

@@ -0,0 +1,22 @@
package com.aoleyun.os.network.api;
import com.aoleyun.os.network.BaseResponse;
import com.aoleyun.os.network.URLPath;
import java.util.Map;
import io.reactivex.Observable;
import okhttp3.MultipartBody;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.http.QueryMap;
public interface SendScreenshotApi {
@Multipart
@POST(URLPath.SEND_SCREENSHOT)
Observable<BaseResponse> sendScreenshot(
@QueryMap Map<String, String> params,
@Part MultipartBody.Part body
);
}

View File

@@ -1,15 +1,42 @@
package com.aoleyun.os.service;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.os.PowerManager;
import android.text.TextUtils;
import android.util.Log;
import com.aoleyun.os.Launcher;
import com.aoleyun.os.TTUtils.APKUtils;
import com.aoleyun.os.TTUtils.CmdUtil;
import com.aoleyun.os.TTUtils.Utils;
import com.aoleyun.os.network.BaseResponse;
import com.aoleyun.os.network.NetworkManager;
import com.aoleyun.os.uiuiutils.ForegroundAppUtil;
import com.aoleyun.os.uiuiutils.TimeUtils;
import com.arialyy.annotations.Download;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.task.DownloadTask;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
public class MainService extends Service {
private String TAG = MainService.class.getSimpleName();
@@ -24,6 +51,7 @@ public class MainService extends Service {
@Override
public void onCreate() {
Log.e(TAG, "onCreate: ");
registerTimeReceiver();
Aria.download(this).register();
super.onCreate();
}
@@ -33,6 +61,165 @@ public class MainService extends Service {
return START_STICKY;
}
//监听时间和日期变化
public void registerTimeReceiver() {
mTimeChangedReceiver = new TimeChangedReceiver();
IntentFilter filter = new IntentFilter();
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
filter.addAction(Intent.ACTION_DATE_CHANGED);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
filter.addAction(Intent.ACTION_TIME_TICK);
registerReceiver(mTimeChangedReceiver, filter);
}
private TimeChangedReceiver mTimeChangedReceiver;
private class TimeChangedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_DATE_CHANGED.equals(intent.getAction())) {
Log.e(TAG, "TimeChangedReceiver:" + "data changed");
} else if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
Log.e(TAG, "TimeChangedReceiver:" + "time changed");
} else if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
Log.e(TAG, "TimeChangedReceiver:" + "timezone changed");
} else if (Intent.ACTION_TIME_TICK.equals(intent.getAction())) {
Log.e(TAG, "TimeChangedReceiver:" + "time tick");
isScreenshot();
}
}
}
private final static long ONE_HOURS_TIME = 60 * 60;
private final static long TEN_MINUTES_TIME = 60 * 10;
private void isScreenshot() {
//1、检测应用使用情况如果设备长时间运行一个应用超过1小时启动截屏一次。
//2、检测设备在非正常时间使用时使用第三方应用在运行10分钟后启动截屏功能一次
//屏幕未点亮时不用截图
// TODO: 2021/12/20 计算当前app打开时间
String topPackageName = ForegroundAppUtil.getForegroundPackageName(MainService.this);
Log.e(TAG, "isScreenshot: " + topPackageName);
String pkg = TimeUtils.getInstance().getAppPackageName();
if (TextUtils.isEmpty(pkg)) {
return;
}
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
//true为打开false为关闭
boolean screenOn = powerManager.isInteractive();
Log.e(TAG, "isScreenshot: screenOn = " + screenOn);
if (!screenOn) return;
long startTime = TimeUtils.getInstance().getStartTime();
if (TimeUtils.getInstance().isNormalTime()) {//正常时间段
if (System.currentTimeMillis() - startTime >= ONE_HOURS_TIME) {
Log.e(TAG, "isScreenshot: " + "截图");
doscreenshot(System.currentTimeMillis() / 1000);
}
} else {//非正常时间段
if (System.currentTimeMillis() - startTime >= TEN_MINUTES_TIME) {
Log.e(TAG, "isScreenshot: " + "截图");
doscreenshot(System.currentTimeMillis() / 1000);
}
}
}
public void doscreenshot(final long time) {
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
String filepath = getExternalFilesDir("db").getAbsolutePath();
int n = CmdUtil.execute("screencap -p " + filepath + File.separator + time + ".db").code;
e.onNext(n);
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer integer) {
if (integer == 0) {
uplaodImage(time);
} else {
Log.e("doss", "失败");
}
}
@Override
public void onError(Throwable e) {
Log.e("doss", "Throwable=" + e.getMessage());
}
@Override
public void onComplete() {
}
});
}
private void uplaodImage(long time) {
String filepath = getExternalFilesDir("db").getAbsolutePath();
// String filepath = mContext.getFileStreamPath("screenshot").getAbsolutePath();
//放在app内部data下面
File file = new File(filepath + File.separator + time + ".db");
//不要直接使用常用图片格式
if (!file.exists()) {
Log.e("uplaodImage", "File does not exists");
return;
}
//设置图片格式
// RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpg"), file);
//File转RequestBody
MediaType mediaType = MediaType.Companion.parse("image/png");
RequestBody fileBody = RequestBody.Companion.create(file, mediaType);
//设置一个file文件
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), fileBody);
Map<String, String> params = new HashMap<>();
params.put("sn", Utils.getSerial());
params.put("createtime", String.valueOf(time));
NetworkManager.getInstance().getScreenshotApi()
.sendScreenshot(params, body)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<BaseResponse>() {
@Override
public void onSubscribe(Disposable d) {
Log.e("uplaodImage", "onSubscribe: ");
}
@Override
public void onNext(BaseResponse baseResponse) {
Log.e("uplaodImage", "onNext: " + baseResponse.msg);
}
@Override
public void onError(Throwable e) {
Log.e("uplaodImage", "onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.e("uplaodImage", "onComplete: ");
}
});
}
@Override
public void onDestroy() {
super.onDestroy();
if (mTimeChangedReceiver != null) {
unregisterReceiver(mTimeChangedReceiver);
}
}
@Download.onTaskRunning
void taskRunning(DownloadTask task) {
Log.e("aria running", "正在下载:" + task.getState() + "--" + task.getPercent() + "--" + task.getExtendField());

View File

@@ -31,7 +31,6 @@ import android.os.Build;
import android.os.Process;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
@@ -55,7 +54,6 @@ import com.aoleyun.os.PromiseAppInfo;
import com.aoleyun.os.R;
import com.aoleyun.os.Statistics.AppInformation;
import com.aoleyun.os.Statistics.StatisticsInfo;
import com.aoleyun.os.TTUtils.APKUtils;
import com.aoleyun.os.TTUtils.Utils;
import com.aoleyun.os.WorkspaceItemInfo;
import com.aoleyun.os.compat.AppWidgetManagerCompat;
@@ -63,9 +61,11 @@ import com.aoleyun.os.folder.Folder;
import com.aoleyun.os.folder.FolderIcon;
import com.aoleyun.os.network.AppPasswdBean;
import com.aoleyun.os.network.BaseResponse;
import com.aoleyun.os.network.NetWorkManager;
import com.aoleyun.os.network.HTTPInterface;
import com.aoleyun.os.network.NetworkManager;
import com.aoleyun.os.network.api.AddAppLog;
import com.aoleyun.os.testing.TestProtocol;
import com.aoleyun.os.uiuiutils.TimeUtils;
import com.aoleyun.os.util.PackageManagerHelper;
import com.aoleyun.os.views.FloatingIconView;
import com.aoleyun.os.widget.PendingAppWidgetHostView;
@@ -74,10 +74,7 @@ import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.tencent.mmkv.MMKV;
import org.json.JSONArray;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -126,6 +123,7 @@ public class ItemClickHandler {
Object tag = v.getTag();
if (tag instanceof WorkspaceItemInfo) {
//获取本地密码
String ApplicationLock = MMKV.defaultMMKV().decodeString("ApplicationLock");
Log.e("onClick", "onClick: " + ApplicationLock);
Type type = new TypeToken<List<AppPasswdBean>>() {
@@ -152,7 +150,7 @@ public class ItemClickHandler {
if (hashMap.get(packageName).equals(dialog.messageTv.getText().toString())) {
onClickAppShortcut(v, (WorkspaceItemInfo) tag, launcher, sourceContainer);
dialog.dismiss();
}else {
} else {
ToastUtil.showCenter("密码错误");
}
}
@@ -176,29 +174,29 @@ public class ItemClickHandler {
// return;
// }
// onClickAppShortcut(v, (WorkspaceItemInfo) tag, launcher, sourceContainer);
// AppInformation app = null;
// try {
// app = getInfoFromPackageName(packageName);
// } catch (Exception e) {
// Log.e("onClick", e.getMessage());
// }
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);
// TimeUtils.getInstance().setTime(app.getUsedTimebyDay() / 1000);
//
// } else {
// Log.e("fht", "首次运行:" + "包名:" + packageName);
// MyApplication.getInstance().setTime(0);
//
// TimeUtils.getInstance().setTime(0);
// }
// if (!APKUtils.isSystemApp(v.getContext(), packageName) && !Arrays.asList(packages).contains(packageName)) {
//// HTTPInterface.sendTimeLog(handler, userInfo, ((ShortcutInfo) tag).title.toString(), 1, 0);
// SendOpenApp(packageName);
// HTTPInterface.sendTimeLog(handler, userInfo, ((ShortcutInfo) tag).title.toString(), 1, 0);
// SendOpenApp(packageName);
// }
// //写入正在运行的app的包名和时间
// MyApplication.getInstance().setAppPackageName(packageName);
// MyApplication.getInstance().setOnClickTime(System.currentTimeMillis());
//写入正在运行的app的包名和时间
TimeUtils.getInstance().setAppPackageName(packageName);
TimeUtils.getInstance().setStartTime(System.currentTimeMillis());
HTTPInterface.SendRunningApp(MyApplication.getInstance().getApplicationContext());
} else if (tag instanceof FolderInfo) {
if (v instanceof FolderIcon) {
onClickFolderIcon(v);
@@ -269,7 +267,7 @@ public class ItemClickHandler {
} else {
appVersionCode = appInfo.versionCode;
}
AddAppLog appLog = NetWorkManager.getInstance().getapplogControl();
AddAppLog appLog = NetworkManager.getInstance().getapplogControl();
String sn = Utils.getSerial();
appLog.addLog(sn, packageName, appVersionCode, System.currentTimeMillis() / 1000, 1)
.subscribeOn(Schedulers.io())
@@ -277,7 +275,7 @@ public class ItemClickHandler {
.subscribe(new Observer<BaseResponse>() {
@Override
public void onSubscribe(Disposable d) {
Log.e("SendOpenApp", "onSubscribe: ");
}
@Override
@@ -297,7 +295,7 @@ public class ItemClickHandler {
@Override
public void onComplete() {
Log.e("SendOpenApp", "onComplete: ");
}
});
}

View File

@@ -0,0 +1,117 @@
package com.aoleyun.os.uiuiutils;
import android.app.ActivityManager;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import java.util.List;
public class ForegroundAppUtil {
private static final long END_TIME = System.currentTimeMillis();
private static final long TIME_INTERVAL = 7 * 24 * 60 * 60 * 1000L;
private static final long START_TIME = END_TIME - TIME_INTERVAL;
public static final String TOPAPP_KEY = "TOP_ALWAYS_SHOW_APP_NAME";
private static String TAG = ForegroundAppUtil.class.getSimpleName();
public static String getForegroundPackageName(Context context) {
//系统应用可以直接获取
ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> runningTaskInfos = mActivityManager.getRunningTasks(1);
return runningTaskInfos.get(0).topActivity.getPackageName();
}
/**
* 获取栈顶的应用包名
*/
public static String getForegroundActivityName(Context context) {
String currentClassName = "";
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
ActivityManager manager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
currentClassName = manager.getRunningTasks(1).get(0).topActivity.getPackageName();
} else {
UsageStats initStat = getForegroundUsageStats(context, START_TIME, END_TIME);
if (initStat != null) {
currentClassName = initStat.getPackageName();
}
}
return currentClassName;
}
/**
* 判断当前应用是否在前台
*/
public static boolean isForegroundApp(Context context) {
return TextUtils.equals(getForegroundActivityName(context), context.getPackageName());
}
/**
* 获取时间段内,
*/
public static long getTotleForegroundTime(Context context) {
UsageStats usageStats = getCurrentUsageStats(context, START_TIME, END_TIME);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return usageStats != null ? usageStats.getTotalTimeInForeground() : 0;
}
return 0;
}
/**
* 获取记录前台应用的UsageStats对象
*/
private static UsageStats getForegroundUsageStats(Context context, long startTime, long endTime) {
UsageStats usageStatsResult = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
List<UsageStats> usageStatses = getUsageStatsList(context, startTime, endTime);
if (usageStatses == null || usageStatses.isEmpty()) return null;
for (UsageStats usageStats : usageStatses) {
if (usageStatsResult == null || usageStatsResult.getLastTimeUsed() < usageStats.getLastTimeUsed()) {
usageStatsResult = usageStats;
}
}
}
return usageStatsResult;
}
/**
* 获取记录当前应用的UsageStats对象
*/
public static UsageStats getCurrentUsageStats(Context context, long startTime, long endTime) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
List<UsageStats> usageStatses = getUsageStatsList(context, startTime, endTime);
if (usageStatses == null || usageStatses.isEmpty()) return null;
for (UsageStats usageStats : usageStatses) {
if (TextUtils.equals(usageStats.getPackageName(), context.getPackageName())) {
return usageStats;
}
}
}
return null;
}
/**
* 通过UsageStatsManager获取List<UsageStats>集合
*/
public static List<UsageStats> getUsageStatsList(Context context, long startTime, long endTime) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
UsageStatsManager manager = (UsageStatsManager) context.getApplicationContext().getSystemService(Context.USAGE_STATS_SERVICE);
//UsageStatsManager.INTERVAL_WEEKLYUsageStatsManager的参数定义了5个具体查阅源码
List<UsageStats> usageStatses = manager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, startTime, endTime);
if (usageStatses == null || usageStatses.size() == 0) {// 没有权限,获取不到数据
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.getApplicationContext().startActivity(intent);
return null;
}
return usageStatses;
}
return null;
}
}

View File

@@ -0,0 +1,101 @@
package com.aoleyun.os.uiuiutils;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.Log;
import com.aoleyun.os.TTUtils.APKUtils;
import com.aoleyun.os.network.BaseResponse;
import com.aoleyun.os.network.NetworkManager;
import com.google.gson.JsonObject;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
public class TimeUtils {
@SuppressLint("StaticFieldLeak")
private static TimeUtils sInstance;
private Context mContext;
private SimpleDateFormat ruleSDF = new SimpleDateFormat("HH:mm:ss");
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private String TAG = TimeUtils.class.getSimpleName();
private TimeUtils(Context context) {
this.mContext = context;
}
public static void init(Context context) {
if (sInstance == null) {
sInstance = new TimeUtils(context);
}
}
public static TimeUtils getInstance() {
if (sInstance == null) {
throw new IllegalStateException("You must be init TimeUtils first");
}
return sInstance;
}
private static String normalStartTime = "8:00:00";
private static String unusualStartTime = "22:00:00";
private String appPackageName;
private long endTime = 0;
private long startTime = 0;
public void setAppPackageName(String name) {
this.appPackageName = name;
}
public String getAppPackageName() {
return appPackageName;
}
public void setStartTime(long time) {
this.startTime = time;
}
public long getStartTime() {
return startTime;
}
public void setEndTime(long time) {
this.endTime = time;
}
public long getEndTime() {
return endTime;
}
private static final long DAY_TIME = 1000 * 60 * 60 * 24;
public boolean isNormalTime() {
long nowTime = System.currentTimeMillis();
String nowTimeString = ruleSDF.format(new Date(nowTime)); // 时间戳转换日期
try {
Date startDate = ruleSDF.parse(normalStartTime);
Date endDate = ruleSDF.parse(unusualStartTime);
Date now = ruleSDF.parse(nowTimeString);
Log.e(TAG, "isScreenshot: startDate = " + startDate);
Log.e(TAG, "isScreenshot: endDate = " + endDate);
Log.e(TAG, "isScreenshot: now = " + now);
if (startDate.getTime() <= now.getTime() && now.getTime() <= endDate.getTime()) {
return true;
} else if (endDate.getTime() < now.getTime() && now.getTime() <= startDate.getTime() + DAY_TIME) {
return false;
}
} catch (ParseException e) {
e.printStackTrace();
Log.e(TAG, "isScreenshot: " + e.getMessage());
}
return false;
}
}