|
|
@@ -0,0 +1,250 @@
|
|
|
+package com.sheep.jiuyan.samllsheep.service;
|
|
|
+
|
|
|
+import android.annotation.SuppressLint;
|
|
|
+import android.app.Notification;
|
|
|
+import android.app.NotificationChannel;
|
|
|
+import android.app.NotificationManager;
|
|
|
+import android.app.PendingIntent;
|
|
|
+import android.app.Service;
|
|
|
+import android.app.usage.UsageStats;
|
|
|
+import android.app.usage.UsageStatsManager;
|
|
|
+import android.content.Context;
|
|
|
+import android.content.Intent;
|
|
|
+import android.graphics.Bitmap;
|
|
|
+import android.graphics.Color;
|
|
|
+import android.os.Build;
|
|
|
+import android.os.IBinder;
|
|
|
+import android.support.annotation.Nullable;
|
|
|
+import android.text.TextUtils;
|
|
|
+import android.widget.RemoteViews;
|
|
|
+
|
|
|
+import com.sheep.gamegroup.greendao.DDProviderHelper;
|
|
|
+import com.sheep.gamegroup.greendao.download.ScreenShotRecord;
|
|
|
+import com.sheep.gamegroup.util.ListUtil;
|
|
|
+import com.sheep.gamegroup.util.LogUtil;
|
|
|
+import com.sheep.gamegroup.util.RunningTaskUtil;
|
|
|
+import com.sheep.gamegroup.util.ScreenShotListenManager;
|
|
|
+import com.sheep.gamegroup.view.activity.SplashAct;
|
|
|
+import com.sheep.jiuyan.samllsheep.R;
|
|
|
+import com.sheep.jiuyan.samllsheep.utils.FileUtil;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Locale;
|
|
|
+import java.util.TreeMap;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+import go.kfzssafe.Kfzssafe;
|
|
|
+import rx.Observable;
|
|
|
+import rx.android.schedulers.AndroidSchedulers;
|
|
|
+import rx.functions.Action1;
|
|
|
+import rx.schedulers.Schedulers;
|
|
|
+
|
|
|
+import static com.sheep.jiuyan.samllsheep.service.AutoCheckService.EXTRA_KEY_USER_ID;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Created by realicing on 2018/9/20.
|
|
|
+ * realicing@sina.com
|
|
|
+ * 监听截图---8.0启用
|
|
|
+ */
|
|
|
+public class ListenerShotNewService extends Service {
|
|
|
+
|
|
|
+ private RunningTaskUtil runningTaskUtil;
|
|
|
+
|
|
|
+ @Nullable
|
|
|
+ @Override
|
|
|
+ public IBinder onBind(Intent intent) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ //登录的用户id
|
|
|
+ private String userId;
|
|
|
+ @Override
|
|
|
+ public int onStartCommand(Intent intent, int flags, int startId) {
|
|
|
+ if (intent != null) {
|
|
|
+ userId = intent.getStringExtra(EXTRA_KEY_USER_ID);
|
|
|
+ }
|
|
|
+ if(runningTaskUtil == null) {
|
|
|
+ //初始化获取当前应用的工具类
|
|
|
+ runningTaskUtil = new RunningTaskUtil(getApplicationContext());
|
|
|
+ }
|
|
|
+ if(manager == null) {
|
|
|
+ //开启监听
|
|
|
+ manager = ScreenShotListenManager.newInstance(getApplicationContext());
|
|
|
+ manager.setListener(
|
|
|
+ new ScreenShotListenManager.OnScreenShotListener() {
|
|
|
+ public void onShot(String imagePath) {
|
|
|
+ addPng(imagePath);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+ manager.startListen();
|
|
|
+ }
|
|
|
+
|
|
|
+ Notification.Builder notificationBuilder = new Notification.Builder(getApplicationContext());
|
|
|
+
|
|
|
+ String CHANNEL_ONE_ID = getPackageName()+".ListenerShotService";
|
|
|
+ String CHANNEL_ONE_NAME = "smallSheep";
|
|
|
+ NotificationChannel notificationChannel;
|
|
|
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
|
|
+ notificationChannel = new NotificationChannel(CHANNEL_ONE_ID,
|
|
|
+ CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_HIGH);
|
|
|
+ notificationChannel.enableLights(true);
|
|
|
+ notificationChannel.setLightColor(Color.RED);
|
|
|
+ notificationChannel.setShowBadge(true);
|
|
|
+ notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
|
|
|
+ NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
|
|
+ if(manager != null)
|
|
|
+ manager.createNotificationChannel(notificationChannel);
|
|
|
+ notificationBuilder.setChannelId(CHANNEL_ONE_ID);
|
|
|
+ }
|
|
|
+ //点击通知栏跳转到相应的应用里面
|
|
|
+ Intent notificationIntent = new Intent(this, SplashAct.class);
|
|
|
+ notificationIntent.setAction(Intent.ACTION_MAIN);
|
|
|
+ notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
|
|
+
|
|
|
+ PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0,
|
|
|
+ notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
|
|
+ Notification notification = notificationBuilder.setSmallIcon(R.mipmap.remenyx)
|
|
|
+ .setWhen(System.currentTimeMillis())
|
|
|
+ .setTicker("小绵羊")
|
|
|
+ .setContentTitle("小绵羊正在运行")
|
|
|
+ .setContentText("点击回到小绵羊")
|
|
|
+ .setOngoing(true)
|
|
|
+ .setPriority(Notification.PRIORITY_MAX)
|
|
|
+ .setContentIntent(pendingIntent)
|
|
|
+ .setAutoCancel(false)
|
|
|
+ .build();
|
|
|
+ notification.flags |= Notification.FLAG_NO_CLEAR;
|
|
|
+ //这里的id不能是0
|
|
|
+ startForeground(113922, notification);
|
|
|
+ return super.onStartCommand(intent, flags, startId);
|
|
|
+ }
|
|
|
+ private ScreenShotListenManager manager;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onDestroy() {
|
|
|
+ super.onDestroy();
|
|
|
+ if (manager != null)
|
|
|
+ manager.stopListen();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取前台运行的程序的包名
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @SuppressLint("NewApi")
|
|
|
+ public String getPackageNameInForeground1(Context context) {
|
|
|
+ String topPackageName = runningTaskUtil.getTopRunningTasks();
|
|
|
+ if (TextUtils.isEmpty(topPackageName)) {
|
|
|
+ return getProcessPackageNameInForeground(context);
|
|
|
+ }
|
|
|
+ return topPackageName;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取前台运行的程序的包名
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @SuppressLint("NewApi")
|
|
|
+ public static String getPackageNameInForeground(Context context) {
|
|
|
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
|
|
|
+ UsageStatsManager mUsageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);//usagestats
|
|
|
+ long time = System.currentTimeMillis();
|
|
|
+ if (mUsageStatsManager != null) {
|
|
|
+ List<UsageStats> usageStatsList = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, time - 5000L, time);
|
|
|
+
|
|
|
+ if (!ListUtil.isEmpty(usageStatsList)) {
|
|
|
+ TreeMap<Long, UsageStats> mySortedMap = new TreeMap<>();
|
|
|
+ for (UsageStats item : usageStatsList) {
|
|
|
+ mySortedMap.put(item.getLastTimeUsed(), item);
|
|
|
+ }
|
|
|
+
|
|
|
+ UsageStats usageStats = mySortedMap.get(mySortedMap.lastKey());
|
|
|
+
|
|
|
+ return usageStats.getPackageName();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return getProcessPackageNameInForeground(context);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String getProcessPackageNameInForeground(Context context) {
|
|
|
+ android.app.ActivityManager manager = (android.app.ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
|
|
+ List<android.app.ActivityManager.RunningAppProcessInfo> processList = manager == null ? null : manager.getRunningAppProcesses();
|
|
|
+ if (!ListUtil.isEmpty(processList)) {
|
|
|
+ for (android.app.ActivityManager.RunningAppProcessInfo item : processList) {
|
|
|
+ if (item != null && item.importance == android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
|
|
|
+ return item.processName;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void addPng(final String imagePath) {
|
|
|
+ final String packageName = getPackageNameInForeground1(getApplicationContext());
|
|
|
+ if (TextUtils.isEmpty(packageName)) {
|
|
|
+ LogUtil.println("ScreenShotListenManager", "无法获取到当前运行的应用的包名");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ LogUtil.println("ScreenShotListenManager", packageName);
|
|
|
+ if (IS_RECORD_PATH) {//使用记录的方式来获取用户的截图
|
|
|
+ ScreenShotRecord screenShotRecord = new ScreenShotRecord();
|
|
|
+ screenShotRecord.setCreateTime(System.currentTimeMillis());
|
|
|
+ screenShotRecord.setPackageName(packageName);
|
|
|
+ screenShotRecord.setPath(imagePath);
|
|
|
+ screenShotRecord.setUserId(userId);
|
|
|
+ DDProviderHelper.getInstance().addScreenShotRecord(getApplicationContext(), screenShotRecord);
|
|
|
+ } else {
|
|
|
+ delayCopyImage(imagePath, packageName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public static final boolean IS_RECORD_PATH = true;//是否直接记录截图文件路径,而不是复制截图到私有目录
|
|
|
+ private void delayCopyImage(final String imagePath, final String packageName) {
|
|
|
+ Observable.just(1).delay(1, TimeUnit.SECONDS)
|
|
|
+ .subscribeOn(Schedulers.io())
|
|
|
+ .observeOn(AndroidSchedulers.mainThread())
|
|
|
+ .subscribe(new Action1<Integer>() {
|
|
|
+ @Override
|
|
|
+ public void call(Integer integer) {
|
|
|
+ try {
|
|
|
+ File toDir = getScreenShotsDir(getApplicationContext(), packageName);
|
|
|
+ if (Kfzssafe.isPng(imagePath)) {
|
|
|
+ FileUtil.copyFileToDir(new File(imagePath), toDir);
|
|
|
+ } else {
|
|
|
+ String toFilePath = String.format(Locale.CHINA, "%s%s%s_%d.png", toDir.getAbsolutePath(), File.separator, packageName, System.currentTimeMillis());
|
|
|
+ FileUtil.convertImage(imagePath, toFilePath, Bitmap.CompressFormat.PNG);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ LogUtil.println("ScreenShotListenManager", "复制截屏图片失败", e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 截图目录
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static File getScreenShotsDir(Context context) {
|
|
|
+ return context.getDir("ScreenShots", Context.MODE_PRIVATE);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 指定程序的截图目录
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static File getScreenShotsDir(Context context, String packageName) {
|
|
|
+ File dir = new File(getScreenShotsDir(context), packageName);
|
|
|
+ if (!dir.exists())
|
|
|
+ dir.mkdirs();
|
|
|
+ return dir;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|