1. 程式人生 > >BroadcastReceiver之實現鎖屏、解鎖例子

BroadcastReceiver之實現鎖屏、解鎖例子

好久沒有寫android的小例子了,由於前幾天寫了一篇關於Intent.Action的文章(http://blog.csdn.net/ljphhj/article/details/38796739),有朋友私信問我關於ACTION_SCREEN_ON和ACTION_SCREEN_OFF還有ACTION_USER_PRESENT三個Action的用法,由於作為一個總結博文,當時並沒有詳細講,ACTION_SCREEN_ON和ACTION_SCREEN_OFF只能通過動態註冊的方式(程式碼內context.register和unregister),而ACTION_USER_PRESENT則是動態、靜態註冊兩種方式都可以。

下面我們通過這個鎖屏、解鎖相關的BroadcastReceiver來了解一下。


package cn.panghu.activitys;

import com.example.broadcastsappdemo.R;

import android.app.Activity;
import android.app.KeyguardManager;
import android.app.KeyguardManager.KeyguardLock;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.PowerManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class ScreenLockedActivity extends Activity{
	private ScreenBroadcastReceiver screenBroadcastReceiver = null;
	private Context context = null;
	private Button lockedScreenBtn = null;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		context = getApplicationContext();
		setContentView(R.layout.screen_lock_layout);
	}
	
	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		
		//註冊這個廣播
		registerScreenBroadcastReceiver();
	}
	
	private void registerScreenBroadcastReceiver() {
		screenBroadcastReceiver = new ScreenBroadcastReceiver();
		IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction(Intent.ACTION_SCREEN_OFF);//當螢幕鎖屏的時候觸發
		intentFilter.addAction(Intent.ACTION_SCREEN_ON);//當螢幕解鎖的時候觸發
		intentFilter.addAction(Intent.ACTION_USER_PRESENT);//當用戶重新喚醒手持裝置時觸發
		context.registerReceiver(screenBroadcastReceiver, intentFilter);
		Log.i("screenBR", "screenBroadcastReceiver註冊了");
	}
	//重寫廣播
	class ScreenBroadcastReceiver extends BroadcastReceiver{

		@Override
		public void onReceive(Context context, Intent intent) {
			String strAction = intent.getAction();
			if (Intent.ACTION_SCREEN_OFF.equals(strAction)){
				//螢幕鎖屏
				Log.i("screenBR", "螢幕鎖屏:ACTION_SCREEN_OFF觸發");
				Toast.makeText(context, "鎖屏了", Toast.LENGTH_SHORT).show();
			}else if (Intent.ACTION_SCREEN_ON.equals(strAction)){
				//螢幕解鎖(實際測試效果,不能用這個來判斷解鎖螢幕事件)
				//【因為這個是解鎖的時候觸發,而解鎖的時候廣播還未註冊】
				Log.i("screenBR", "螢幕解鎖:ACTION_SCREEN_ON觸發");
				Toast.makeText(context, "解鎖了", Toast.LENGTH_SHORT).show();
			}else if (Intent.ACTION_USER_PRESENT.equals(strAction)){
				//螢幕解鎖(該Action可以通過靜態註冊的方法註冊)
				//在解鎖之後觸發的,廣播已註冊
				Log.i("screenBR", "螢幕解鎖:ACTION_USER_PRESENT觸發");
				Toast.makeText(context, "解鎖了", Toast.LENGTH_SHORT).show();
			}else{
				//nothing
			}
		}
		
	}
	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		context.unregisterReceiver(screenBroadcastReceiver);
		Log.i("screenBR", "screenBroadcastReceiver取消註冊了");
	}
}


LogCat結果圖:



由於是靜態註冊的方式,所以大家可能會覺得那我要怎麼讓它長久地監聽這鎖屏、解鎖螢幕的廣播呢?

首先我們再次強調ACTION_SCREEN_ON和ACTION_SCREEN_OFF只能通過動態註冊的方式(程式碼內context.register和unregister),而ACTION_USER_PRESENT則是動態、靜態註冊兩種方式都可以。


那麼我們的突破口便是:我們可以動態地註冊一個關於螢幕解鎖後(ACTION_USER_PRESENT)的廣播者,並且在這個廣播的onReceive方法中實現我們要做的一些操作。例如我們可以開啟一個Service服務,用於註冊我們所想要的這個Broadcast Receiver


1.在Service中定義receiver

[java]  view plain copy 在CODE上檢視程式碼片 派生到我的程式碼片
  1. private BroadcastReceiver mScreenFilterReceiver = new BroadcastReceiver() {  
  2.     public void onReceive(Context context, Intent intent) {  
  3.             if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {  
  4.                 //做要求的處理  
  5.             }else if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){
  6. }  
  7.     }  
  8. };  

2.在Service的onCreate中定義IntentFilter及註冊receiver

[java]  view plain copy 在CODE上檢視程式碼片 派生到我的程式碼片
  1. IntentFilter ScreenFilter = new IntentFilter();  
  2. ScreenFilter.addAction(Intent.ACTION_SCREEN_ON);  
  3. ScreenFilter.addAction(Intent.ACTION_SCREEN_OFF); 
  4. registerReceiver(mScreenFilterReceiver, ScreenFilter);  

3.在Service的onDestroy中要反註冊這個receiver。

[java]  view plain copy 在CODE上檢視程式碼片 派生到我的程式碼片
  1. unregisterReceiver(mScreenFilterReceiver);