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

【Android如何实现Android程序在手机锁屏后继续运行】别裁伪体亲风雅,转益多师是汝师。这篇文章主要讲述Android如何实现Android程序在手机锁屏后继续运行相关的知识,希望能为你提供帮助。
目录结构:

contents structure [+]

  1. 如何监听屏幕锁屏
  2. 如何实现手机屏幕在锁屏后继续运行
 
最近笔者在做一个功能,就是实现android程序在锁屏后可以继续运行,笔者在网上查了一些资料,现在整理出来,希望能够对你有所帮助。
1.如何监听屏幕锁屏监听屏幕锁屏可以通过如下方式来实现,直接通过代码来判定,或通过监听器来实现
如何实现Android程序在手机锁屏后继续运行
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锁屏的黑科技呢)。
就是在屏幕锁屏的时候,跳转到另一个界面,该界面只有一个像素点。
代码如下:
Android如何实现Android程序在手机锁屏后继续运行

文章图片

MainActivity.java
Android如何实现Android程序在手机锁屏后继续运行

文章图片
Android如何实现Android程序在手机锁屏后继续运行

文章图片
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.javaSinglePixelActivity.java
Android如何实现Android程序在手机锁屏后继续运行

文章图片
Android如何实现Android程序在手机锁屏后继续运行

文章图片
package org.screenlock.main; import android.app.Activity; import android.os.Bundle; import android.util.Log; 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; Log.i("info", "SinglePixelActivity onCreate"); } @Override protected void onStart() { super.onStart(); Log.i("info", "SinglePixelActivity onStart"); } @Override protected void onResume() { super.onResume(); Log.i("info", "SinglePixelActivity onResume"); } @Override protected void onPause() { super.onPause(); Log.i("info", "SinglePixelActivity onPause"); } @Override protected void onStop() { super.onStop(); Log.i("info", "SinglePixelActivity onStop"); } @Override protected void onRestart() { super.onRestart(); Log.i("info", "SinglePixelActivity onRestart"); } @Override protected void onDestroy() { super.onDestroy(); Log.i("info", "SinglePixelActivity onDestroy"); }}

SinglePixelActivity.javaAndroidManifest.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>

运行上面的程序,可以看到计时器在正常打印东西,说明程序并没有完全停止,还可以看到打印如下的日志:
infoSinglePixelActivity onCreate infoSinglePixelActivity onStart infoSinglePixelActivity onResume infoSinglePixelActivity onPause infoSinglePixelActivity onStop

从日志中可以看出,当锁屏后,这个SinglePixelActivity立即进入了OnStop状态,在Onstop的状态的页面是很有可能被系统回收的。因此可以再配合上WakeLock机制,若WakeLock不合适的话,那么可以尝试播放无声音乐。保持系统不回收该App的资源。
  需要注意,当锁屏后再次打开的跳转逻辑处理也是一个问题,可以参考  Android实现监听返回键,主键(HOME),菜单键
 

    推荐阅读