在要彈窗的Activity需要進行以下設置,才可以在鎖屏狀態下彈窗
@Override protected void onCreate(Bundle savedInstanceState) { final Window win = getWindow(); win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED //鎖屏狀態下顯示 // | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD //解鎖 | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON //保持屏幕長亮 | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); //打開屏幕 super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
AndroidManifest.xml文件當中,對該activity的聲明需要加上以下屬性:
<activity android:name=".Activity" android:launchMode="singleInstance" android:excludeFromRecents="true" android:taskAffinity="" android:theme="@android:style/Theme.Wallpaper.NoTitleBar"/>
在MainActivity:
public class MainActivity extends Activity { IntentFilter intentFilter; LocalBroadcastManager localBroadcastManager; LocalBroadcastReceiver localBroadcastReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Thread thread =new Thread( new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(5000); Log.i("send", "send ok"); Intent intent = new Intent("com.example.stuart.LOCAL_BROADCAST"); localBroadcastManager.sendBroadcast(intent); } catch (InterruptedException e) { e.printStackTrace(); } } } } ); thread.start();//模擬5秒自動發送廣播 localBroadcastManager =LocalBroadcastManager.getInstance(this); intentFilter =new IntentFilter(); intentFilter.addAction("com.example.stuart.LOCAL_BROADCAST"); localBroadcastReceiver =new LocalBroadcastReceiver(); localBroadcastManager.registerReceiver(localBroadcastReceiver,intentFilter); } public void check_lock(){ // KeyguardManager km = (KeyguardManager) this.getSystemService(Context.KEYGUARD_SERVICE); // if (km.isKeyguardLocked()) { // Intent intent =new Intent("com.example.stuart.LOCAL_BROADCAST"); // intent .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // localBroadcastManager.sendBroadcast(intent); // // } // Thread thread =new Thread( // new Runnable() { // @Override // public void run() { // try { // Thread.sleep(5000); // Intent intent =new Intent("com.example.stuart.LOCAL_BROADCAST"); // localBroadcastManager.sendBroadcast(intent); // } catch (InterruptedException e) { // e.printStackTrace(); // } // // } // } // // // // ); // thread.start(); } class LocalBroadcastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { Log.d("LOG_TAG", intent.getAction()); KeyguardManager km = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE); if (km.isKeyguardLocked()) { Intent alarmIntent = new Intent(context, AlarmActivity.class); alarmIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(alarmIntent); } } }
我們設置的是鎖屏下才彈窗的,非鎖屏下就不適合彈出這個窗口了(你可以試一下,效果會很怪)。一般是注冊一個廣播接收器,在接收到指定廣播之后判斷是否需要彈窗,所以在BroadcastReceiver的接收代碼中需要先判斷是否為鎖屏狀態下:
這里用到的是KeyguardManager類,用來管理鎖屏的,4.1之后該類的API新增了一個isKeyguardLocked()的方法判斷是否鎖屏,但在4.1之前,我們只能用inKeyguardRestrictedInputMode()方法,如果為true,即為鎖屏狀態。需要注意的是,在廣播中啟動Activity的context可能不是Activity對象,所以需要添加NEW_TASK的標志,否則啟動時可能會報錯。
再次亮起屏幕
如果該Activity並未退出,但是被手動按了鎖屏鍵,當前面的廣播接收器再次去啟動它的時候,屏幕並不會被喚起,所以我們需要在activity當中添加喚醒屏幕的代碼,這里用的是電源鎖。可以添加在onNewIntent(Intent intent),因為它會被調用。也可以添加在其他合適的生命周期方法
PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE); if (!pm.isScreenOn()) { PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bright"); wl.acquire(); wl.release(); }
權限
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/> <uses-permission android:name="android.permission.WAKE_LOCK"/>
參考:http://blog.csdn.net/maosidiaoxian/article/details/40587935
http://bbs.csdn.net/topics/390425777