微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当特定应用在前台运行时如何放置叠加层?

如何解决当特定应用在前台运行时如何放置叠加层?

我正在尝试实现此功能,当特定应用程序在前台运行时,我的应用程序会检测到它,并放置一个叠加视图。执行类似操作的应用示例包括 AppLock、Forest:Stay focus、YourHour 等。

解决了这个问题,创建了一个不断检查当前前台应用程序的服务,但它导致了错误的行为。在某些手机中,它运行良好,在其他手机中,Android 会在一段时间后终止我的服务,或者在删除启动该服务的 Activity 然后关闭/锁定屏幕时,该服务被终止。我已经尝试过 return START_STICKY,但在锁定屏幕后它不起作用。

当目标应用程序打开并出现叠加视图时也有相当长的延迟。

查看当前前台应用的方法

private String currentPackage() {
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        UsageStatsManager usm = (UsageStatsManager) getSystemService(USAGE_STATS_SERVICE);
        long time = System.currentTimeMillis();
        List<UsageStats> appList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,time - 1000 * 1000,time);
        if (appList != null && appList.size() > 0) {
            SortedMap<Long,UsageStats> mySortedMap = new TreeMap<Long,UsageStats>();
            for (UsageStats usageStats : appList) {
                mySortedMap.put(usageStats.getLastTimeUsed(),usageStats);
            }
            if (mySortedMap != null && !mySortedMap.isEmpty()) {
                return mySortedMap.get(
                        mySortedMap.lastKey()).getPackageName();
            }
        }
    }
}

第一次调用服务时,会创建覆盖视图(但隐藏,因为只有主线程可以创建视图),然后会创建一个警报来调用自身并检查目标应用程序是否正在运行并在这种情况显示创建的视图,否则隐藏它

 private Runnable runnable = new Thread() {
    @Override
    public void run() {
        startAlarm(getApplicationContext());
        }
    };


@Override
public int onStartCommand(Intent intent,int flags,int startId) {
    Log.d("Floating Window","ThreadId "  + android.os.Process.getThreadPriority(android.os.Process.myTid()));
    Log.d("Floating Window","Action of intent is:" + intent.getAction());

    if (intent == null || intent.getAction().equalsIgnoreCase(ACTION_CREATE)) {
        addOverlayView();
        new Thread(runnable).start();
        destroy=false;
    }else if(intent.getAction().equalsIgnoreCase(ACTION_DESTROY)){
        destroy=true;
        stopSelf();
    }

    else if (intent.getAction().equalsIgnoreCase(ACTION_CHECK)) {
        checkActiveApps();
        startAlarm(this);
    }
    return START_STICKY;
}

报警

   public static final void startAlarm(Context context) {
    AlarmManager am = (AlarmManager) context.getSystemService(ALARM_SERVICE);
    am.setExact(AlarmManager.ELAPSED_REALTIME,200,getRunIntent(context));
   }

覆盖Destroy方法调用MainActivity,然后再次调用服务重启(不能直接调用服务)

   @Override
    public void onDestroy() {
        if(destroy) {
            Log.d("destroy","destroyed on purpose");
            removeAllViews();
            stop(this);
        }else{
            Intent service_intent = new Intent(getApplicationContext(),MainActivity.class);
            service_intent.setAction("restart");
            this.startActivity(service_intent);

        }
        super.onDestroy();

    }

请注意,我不打算启动新的 Activity,而是在前台运行时在特定应用程序上添加叠加视图 WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY。主要问题是让这个服务检查当前的前台应用程序,无论如何都不会被系统杀死,就像上面提到的应用程序一样。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。