Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android服务:检测设备空闲X分钟的时间_Java_Android_Idle Timer - Fatal编程技术网

Java Android服务:检测设备空闲X分钟的时间

Java Android服务:检测设备空闲X分钟的时间,java,android,idle-timer,Java,Android,Idle Timer,我需要知道,当我的应用程序当前处于后台时,android设备何时处于空闲状态一段时间(如果处于空闲状态,请将我的应用程序带到前台)。我能想到的唯一两种方法是: 以某种方式检测应用程序外的用户交互,如果X分钟内没有任何输入,请将我的应用程序放在最前面 或: 当设备进入睡眠模式时,将我的应用程序放在最前面 我不知道如何实现这两个目标,但2对我来说似乎是最可行的选择。这方面的代码是什么?我能够完成1。通过使用“透明”视图,该视图位于所有视图之上,用于检查用户触摸 实现所需效果的步骤: 1) 创建一个服

我需要知道,当我的应用程序当前处于后台时,android设备何时处于空闲状态一段时间(如果处于空闲状态,请将我的应用程序带到前台)。我能想到的唯一两种方法是:

  • 以某种方式检测应用程序外的用户交互,如果X分钟内没有任何输入,请将我的应用程序放在最前面

    或:


  • 当设备进入睡眠模式时,将我的应用程序放在最前面


  • 我不知道如何实现这两个目标,但2对我来说似乎是最可行的选择。这方面的代码是什么?

    我能够完成1。通过使用“透明”视图,该视图位于所有视图之上,用于检查用户触摸

    实现所需效果的步骤:

    1) 创建一个服务,该服务在其onCreate方法中创建透明视图并将其附加到视图堆栈
    2) onStart命令调用initTimer()方法
    3) 在服务上实现View.OnTouchListener
    4) 重写onTouch方法
    5) 收到onTouch事件-调用initTimer()
    6) 在服务的onDestroy上-从视图堆栈中删除透明视图
    7) 当调用主活动的onPause时启动服务
    8) 当应用程序打开时停止服务

    代码如下:

    private Handler mHandler;
    private Runnable mRunnable;
    private final int mTimerDelay = 60000;//inactivity delay in milliseconds
    private LinearLayout mTouchLayout;//the transparent view
    
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    
    @Override
    public void onCreate() {
        super.onCreate();
    
        mTouchLayout = new LinearLayout(this);
    
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT);
        mTouchLayout.setLayoutParams(lp);
    
        // set on touch listener
        mTouchLayout.setOnTouchListener(this);
    
        // fetch window manager object
        WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        // set layout parameter of window manager
    
        WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
                        WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
                        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT
        );
    
        mParams.gravity = Gravity.LEFT | Gravity.TOP;
        windowManager.addView(mTouchLayout, mParams);
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        initTimer();
    
        return START_NOT_STICKY;
    }
    
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        Log.d("IdleDetectorService", "Touch detected. Resetting timer");
        initTimer();
        return false;
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        mHandler.removeCallbacks(mRunnable);
        WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        if (windowManager != null && mTouchLayout != null) {
            windowManager.removeView(mTouchLayout);
        }
    }
    
    /**
     * (Re)sets the timer to send the inactivity broadcast
     */
    private void initTimer() {
        // Start timer and timer task
        if (mRunnable == null) {
    
            mRunnable = new Runnable() {
                @Override
                public void run() {
                    Log.d("IdleDetectorService", "Inactivity detected. Sending broadcast to start the app");
    
                    try {
                        boolean isInForeground = new ForegroundCheckTask().execute(getApplicationContext()).get();
    
                        if (!isInForeground) {
                            Intent launchIntent = getApplication()
                                    .getPackageManager()
                                    .getLaunchIntentForPackage("<your-package-name>");
                            if (launchIntent != null) {
                                LogUtil.d("IdleDetectorService", "App started");
                                getApplication().startActivity(launchIntent);
                            }
                        }
    
                        stopSelf();
                    } catch (Exception e) {
                    }
                }
            };
        }
    
        if (mHandler == null) {
            mHandler = new Handler();
        }
    
        mHandler.removeCallbacks(mRunnable);
        mHandler.postDelayed(mRunnable, mTimerDelay);
    }
    
    private class ForegroundCheckTask extends AsyncTask<Context, Void, Boolean> {
    
        @Override
        protected Boolean doInBackground(Context... params) {
            final Context context = params[0];
            return isAppOnForeground(context);
        }
    
        private boolean isAppOnForeground(Context context) {
            ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            List<ActivityManager.RunningAppProcessInfo> appProcesses = null;
    
            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
                appProcesses = activityManager.getRunningAppProcesses();
            } else {
                //for devices with Android 5+ use alternative methods
                appProcesses = AndroidProcesses.getRunningAppProcessInfo(getApplication());
            }
    
            if (appProcesses == null) {
                return false;
            }
    
            final String packageName = context.getPackageName();
    
            for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
                if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND &&
                        appProcess.processName.equals(packageName)) {
                    return true;
                }
            }
    
            return false;
        }
    }
    
    私有处理器mHandler;
    私人可运行的mRunnable;
    私人最终int mTimerDelay=60000//不活动延迟(毫秒)
    私人线路布局mTouchLayout//透明视图
    @凌驾
    公共IBinder onBind(意向){
    返回null;
    }
    @凌驾
    public void onCreate(){
    super.onCreate();
    mTouchLayout=新的线性布局(本);
    LinearLayout.LayoutParams lp=新的LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_父项,
    LinearLayout.LayoutParams.MATCH_PARENT);
    mTouchLayout.setLayoutParams(lp);
    //触摸式监听
    mTouchLayout.setOnTouchListener(this);
    //获取窗口管理器对象
    WindowManager WindowManager=(WindowManager)getSystemService(窗口服务);
    //设置窗口管理器的布局参数
    WindowManager.LayoutParams mParams=新建WindowManager.LayoutParams(
    WindowManager.LayoutParams.WRAP_内容,
    WindowManager.LayoutParams.WRAP_内容,
    WindowManager.LayoutParams.TYPE\u系统错误,
    WindowManager.LayoutParams.FLAG\u不可触摸|
    WindowManager.LayoutParams.FLAG\u WATCH\u OUTSIDE\u TOUCH|
    WindowManager.LayoutParams.FLAG_不可聚焦,PixelFormat.半透明
    );
    mParams.gravity=gravity.LEFT | gravity.TOP;
    windowManager.addView(mTouchLayout,mParams);
    }
    @凌驾
    公共int onStartCommand(Intent Intent、int标志、int startId){
    initTimer();
    返回开始时间不粘;
    }
    @凌驾
    公共布尔onTouch(视图、运动事件、运动事件){
    Log.d(“IdleDetectorService”,“检测到触摸。重置计时器”);
    initTimer();
    返回false;
    }
    @凌驾
    公共空间{
    super.ondestory();
    mHandler.removeCallbacks(mRunnable);
    WindowManager WindowManager=(WindowManager)getSystemService(窗口服务);
    if(windowManager!=null&&mTouchLayout!=null){
    windowManager.removeView(mTouchLayout);
    }
    }
    /**
    *(Re)设置计时器以发送非活动广播
    */
    私有void initTimer(){
    //启动计时器和计时器任务
    如果(mRunnable==null){
    mRunnable=newrunnable(){
    @凌驾
    公开募捐{
    Log.d(“IdleDetectorService”,“检测到不活动。正在发送广播以启动应用程序”);
    试一试{
    布尔值ISINFORGROUND=new ForegroundCheckTask().execute(getApplicationContext()).get();
    如果(!IsInfo重新研磨){
    Intent launchIntent=getApplication()
    .getPackageManager()
    .getLaunchIntentForPackage(“”);
    if(launchIntent!=null){
    LogUtil.d(“IdleDetectorService”,“应用程序已启动”);
    getApplication().startActivity(launchIntent);
    }
    }
    stopSelf();
    }捕获(例外e){
    }
    }
    };
    }
    if(mHandler==null){
    mHandler=新处理程序();
    }
    mHandler.removeCallbacks(mRunnable);
    mHandler.postDelayed(mRunnable,mTimerDelay);
    }
    私有类ForegroundCheckTask扩展了AsyncTask{
    @凌驾
    受保护的布尔doInBackground(上下文…参数){
    最终上下文=参数[0];
    返回isAppOnForeground(上下文);
    }
    专用布尔值isAppOnForeground(上下文){
    ActivityManager ActivityManager=(ActivityManager)context.getSystemService(context.ACTIVITY_服务);
    列表appprocesss=null;
    
    if(Build.VERSION.SDK_INT)我以前也见过类似的讨论,例如这里:@Scalar,用于检测应用程序内的空闲时间。当设备进入睡眠模式时,什么都没有(至少在普通软件中是这样)正在运行。@ChrisStratton我意识到了这一点,这正是我的问题。但是,也许有一种方法可以覆盖某种“屏幕关闭”事件,使其打开我的应用程序(或类似的内容)?但他们实际上是在屏幕关闭,这可能发生在实际睡眠之前。谢谢!这对我来说适用于以下内容:
    val mParams=WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_父项、WindowManager.LayoutParams.MATCH_父项、WindowManager.LayoutParams.TYPE_应用程序_覆盖、WindowManager.LayoutParams.FLAG_不可触摸或WindowManager.LayoutParams.FLAG_监视_外部触摸或