【Android】如何实现Android程序在手机锁屏后继续运行

最近笔者在做一个功能,就是实现Android程序在锁屏后可以继续运行,笔者在网上查了一些资料,现在整理出来,希望能够对你有所帮助。

1.如何监听屏幕锁屏

监听屏幕锁屏可以通过如下方式来实现,直接通过代码来判定,或通过监听器来实现

1)通过代码来判定屏幕的锁屏状态

可以通过PowerManager的isScreenOn方法,代码如下:

PowerManager pm = (PowerManager)
context.getSystemService(Context.POWER_SERVICE);
//如果为true,则表示屏幕“亮”了,否则屏幕“暗”了。
boolean isScreenOn = pm.isScreenOn();

这里需要解释一下:
屏幕“亮”,表示有两种状态:a、未锁屏 b、目前正处于解锁状态 。这两种状态屏幕都是亮的;
屏幕“暗”,表示目前屏幕是黑的 。

通过KeyguardManager的inKeyguardRestrictedInputMode方法,也可以实现判断屏幕的锁屏状态

KeyguardManager mKeyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
boolean flag = mKeyguardManager.inKeyguardRestrictedInputMode();

对flag进行一下说明,经过试验,总结为:
如果flag为true,表示有两种状态:a、屏幕是黑的 b、目前正处于锁屏状态 。
如果flag为false,表示目前未锁屏

当然也可以通过反射的方式来调用上面的两种方法:

    Method mReflectScreenState;
try {
    mReflectScreenState = PowerManager.class.getMethod(isScreenOn, new Class[] {});
    PowerManager pm = (PowerManager)           context.getSystemService(Activity.POWER_SERVICE);
   boolean isScreenOn= (Boolean) mReflectScreenState.invoke(pm);
} catch (Exception e) {
    e.printStackTrace()

2)通过监听器来判定屏幕的锁屏状态

当安卓系统锁屏或者屏幕亮起,或是屏幕解锁的时候,系统内部都会发送相应的广播,我们只需要对广播进行监听就可以了

注册广播的伪代码如下:

    ScreenBroadcastReceiver mScreenReceiver;
    class ScreenBroadcastReceiver extends BroadcastReceiver {
        String action = null;
        @Override
        public void onReceive(Context context, Intent intent) {
            action = intent.getAction();
            if (Intent.ACTION_SCREEN_ON.equals(action)) {
                // 开屏
            } else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
                // 锁屏
            } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
                // 解锁
            }
        }
    }
    private void startScreenBroadcastReceiver() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        filter.addAction(Intent.ACTION_USER_PRESENT);
        context.registerReceiver(mScreenReceiver, filter);
    }

2.如何实现手机屏幕在锁屏后继续运行

在上面我们知道了如何监听屏幕的状态,接下要实现如何在屏幕关闭后程序不停止运行。关于这个功能,笔者在网上搜索了一些资料,Android的WakeLock机制就是其中一种,使用Android的service也可以。但是经过笔者的测试发现效果都不太理想,对于Android版本的兼容性不强,笔者的Android4.4可以支持,但是Android6.0经过测试发现却不支持。

下面笔者介绍一种万能方法,在这里感谢知乎给我提出的意见(听说是QQ锁屏的黑科技呢)。

就是在屏幕锁屏的时候,跳转到另一个界面,该界面只有一个像素点。

代码如下:

MainActivity.java

package org.screenlock.main;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import com.example.screenlocktest.R;

import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.app.Activity;
import android.app.KeyguardManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.PixelFormat;
import android.text.format.Time;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
    Context context = null;
    Intent mintent=null;
    static Activity mactivity=null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.context = this;
        mintent=new Intent(this,SinglePixelActivity.class);

        startScreenBroadcastReceiver(new ScreenBroadcastReceiver());

        Timer timer=new Timer();
        TimerTask timerTask=new TimerTask() {
            @Override
            public void run() {
                Log.i("info", new Date().toString());
            }
        };
        timer.schedule(timerTask, 0,10* 1000);//每10秒钟运行一次,用于观察程序是否在运行
    }
    /**
     * 注册屏幕广播
     */
    private void startScreenBroadcastReceiver(ScreenBroadcastReceiver mScreenReceiver) {
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        filter.addAction(Intent.ACTION_USER_PRESENT);
        context.registerReceiver(mScreenReceiver, filter);
    }

    private class ScreenBroadcastReceiver extends BroadcastReceiver {
        private String action = null;
        @Override
        public void onReceive(Context context, Intent intent) {
            action = intent.getAction();
            if (Intent.ACTION_SCREEN_ON.equals(action)) {
                // 开屏
                Log.i("info", "开屏");
                finishScreenActivity();
            } else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
                // 锁屏
                Log.i("info", "锁屏");
                startScreenActivity();
            } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
                // 解锁
                Log.i("info", "解屏");
            }
        }
    }
    /**
     * 关闭屏幕锁屏界面
     */
    private void finishScreenActivity(){
        if(mactivity!=null){
            mactivity.finish();
        }
    }
    /**
     * 跳转到屏幕锁屏界面
     */
    private void startScreenActivity(){
        startActivity(mintent);
    }
}

MainActivity.java

SinglePixelActivity.java

package org.screenlock.main;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;

public class SinglePixelActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Window window= getWindow();
        WindowManager.LayoutParams params=new WindowManager.LayoutParams();
        params.x=0;
        params.y=0;
        params.width=1;
        params.height=1;
        window.setAttributes(params);
        MainActivity.mactivity=this;
    }
}

SinglePixelActivity.java

AndroidManifest.xml中需要添加如下:

        <activity
            android:name="org.screenlock.main.SinglePixelActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

原文地址:https://www.cnblogs.com/HDK2016/p/8463846.html

时间: 2024-11-10 22:41:55

【Android】如何实现Android程序在手机锁屏后继续运行的相关文章

手机锁屏js倒计时停止问题解决办法探索

如图,有这么个需求,测试人员在测试过程中提了一个bug,手机锁屏再唤醒倒计时时间没有更新,仍从锁屏的时间继续,于是开始寻找解决之法 经了解得知,锁屏时候,浏览器的一切活动会停止运行,那么js也无法幸免,这时候就想到有没有能监听浏览器活动停止的方法呢?一查,果然有 visibilitychange 具体可参看https://www.css88.com/archives/6103, 重要的就是给window加一个visibilitychange监听,在里面判断document.tVisibility

WEB认证苹果手机锁屏后出现断开WI-Fi的现象和解决

苹果当手机使用WEB认证时,手机锁屏解锁后,WIFI将断开,用户将离线.是什么导致这个问题? 现象分析: 苹果当手机连接到WEB认证的WIFI时,苹果手机会发送WIFI连接检测请求,无线控制器在拦截检测请求后重定向到认证页面.这个过程苹果会认为这个WIFI是一个受监管的WIFI. 从苹果手机端,用户在连接WIFI后会自动弹出认证页面进行WEB认证.用户锁定苹果电话后,苹果系统将自动检测WIFI流量,因为锁定屏幕上没有流量,加上苹果认为这是一个受监管的WIFI,因此它将自动断开与WIFI的连接.

实现:编辑短信,按power键锁屏后,再点亮屏幕,进入的还是编辑短信界面,按返回键才会进入解锁界面。

描述:在编辑短信界面按电源键锁屏后,重新按电源键点亮屏幕,并没有进入到锁屏界面而是在编辑短信界面,此时短信界面悬浮与锁屏界面之上,这时按返回键关闭编辑短信界面,回到锁屏界面,是如何实现的呢,只需要在需要实现该功能的界面(Activity)中的onCreate()方法中setContentView()方法之前添加以下代码: // set this flag so this activity will stay in front of the keyguard int flags = WindowM

如何让linux程序在ssh shell关闭后继续运行?

我们经常会碰到一种情况,用ssh远程登录到linux服务器后,启动一个脚本跑任务,如果这个任务耗时比较久,就得等着,如果此时由于网络原因,ssh连接断了,再重新登录服务器,原来的任务就没了,得重新运行一次.有没有办法让任务切到后台,ssh退出后还能继续运行呢? 当然有-,而且很简单: 1. 在ssh shell中运行脚本,比如我运行一个批量下载脚本: python download-app-annie.py 2. 按下ctrl-z中断脚本运行,此时系统提示: ^Z [1]+  Stopped  

【Android N 7.1.1】 处于锁屏界面时可以转屏

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java 锁屏时能否旋转的开关:mKeyguardScreenRotation .当设置为true时,重启手机,然后打开设置内"自动旋转"的开关,再锁屏,然后旋转手机,即可看到锁屏可以转屏了.

Android 7.0 以上保留数据去除锁屏密码的方法

在很多情况下,由于我们的疏忽,导致忘记了锁屏密码.也没有开启 USB 调试,内置存储中还有要保留的数据.我们需要在不清除数据的情况下删除锁屏密码.接下来我们就介绍该如何做. 注意事项 首先要注意,这个方法不能用于已经绑定了 data 加密的设备.例如 Motorola,设置了输入锁屏密码才能启动设备,这种方法就不再适用了.原因是这种类型的设备,使用了锁屏密码加密了 data 分区,导致无法修改 data 分区. 适用 Android Android 7.0+ 已测试机型 Moto Z Andro

Android 通话:后台通话过程中锁屏解锁,发现听筒内存在锁屏提示音

[系统版本]:T0316 [ HW ]:p1 [测试前提]:1.卡1插入移动4G卡 [测试步骤]:1.呼入或呼出一通来电,接听: 2.按home返回后台,锁屏解锁查看. [测试结果]:1.后台通话过程中锁屏解锁,发现听筒内存在锁屏提示音 [预期结果]:1.通话过程中不应存在锁屏提示音 [概 率]:必现 solution: 修改文件:./frameworks/av/services/audiopolicy/AudioPolicyManager.cpp status_t AudioPolicyMan

酷派手机锁屏壁纸提取

前些年从网上买了个酷派手机(Coolpad 5890)做备用机,女朋友看到后,喜欢上了这个手机的锁屏壁纸(确实挺好看的),非要我找给她,作为一个在大学期间就玩过Android手机的IT男来说,这简直是一个绝佳的表现机会.就是下面这个锁屏图片: 根据以前折腾Android手机的经验,像这种系统自带的图片一般在/system/app下的某个系统自带的程序里面,可是任我翻遍了所有这个文件夹下的系统自带程序的图片后(印象中有几万个小图),仍然没找到.也尝试过以图搜图的方式从网上找,可是搜出来的要么是手机

Android4.0+锁屏程序开发——设置锁屏页面篇

[如何开发一个锁屏应用] 想要开发一个锁屏应用,似乎很难,其实并没有想象中那么难. 从本质上来说,锁屏界面也只是一个Activity而已,只是这个界面比较特殊,在我们点亮屏幕的时候,这个界面就会出现. 而且在此界面中,我们可以用一些行为来退出,比如点击按钮等. 还有一个特征是在这个界面的时候,我们通常是不能使用底部的三个按钮的 关于如果屏蔽底部的三个按钮,我已经在另一篇博客Android4.0+锁屏程序开发——按键屏蔽篇进行了总结,有需要的朋友可以参看. 这篇博客我们主要讨论如何让一个Activ