Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android系統移植與調試之-------)增加一個雙擊物理按鍵打開和關閉閃光燈並將閃光燈狀態同步到下拉菜單中

Android系統移植與調試之-------)增加一個雙擊物理按鍵打開和關閉閃光燈並將閃光燈狀態同步到下拉菜單中

編輯:關於Android編程

最近有一個客戶有這樣的需求:

1、在【設置】--->【無障礙】中添加一個開關按鈕。

如果打開開關的話,雙擊某個物理按鍵的時候,打開閃光燈,再雙擊該物理按鍵的時候,關閉閃光燈。

如果關閉開關的話,雙擊該物理按鍵的時候,不做任何處理。

2、打開關閉閃光燈的狀態,在下拉菜單中也要同步。

如下圖所示的效果:

data-cke-saved-src=/uploadfile/Collfiles/20151111/2015111108241932.

當打開上面添加的開關後,如果雙擊POC鍵(POC鍵是我們公司自定義的一個物理按鍵)的時候,就打開閃光燈,並將下拉菜單中的閃光燈圖標點亮,如下圖所示

data-cke-saved-src=/uploadfile/Collfiles/20151111/2015111108241934.

如果再次雙擊POC鍵(POC鍵是我們公司自定義的一個物理按鍵)的時候,就關閉閃光燈,並將下拉菜單中的閃光燈圖標熄滅,如下圖所示

data-cke-saved-src=/uploadfile/Collfiles/20151111/2015111108241936.

====================================================================================================================================

下面來具體說說怎麼實現該功能:

第一步:添加開關按鈕布局

在packages/apps/Settings/res/xml/accessibility_settings.xml 文件中添加一個開關,開關位置放在【按電源按鈕結束通話】和【自動選擇屏幕】中間,代碼如下

        
        
        
 		
 		
        


在packages/apps/Settings/res/values-zh-rCN/strings.xml文件中添加相應的字符串

    
    雙擊[相機鍵]打開閃光燈
    雙擊[POC鍵]打開閃光燈
    開啟此功能後,攝像機暫時無法使用
    

 

packages/apps/Settings/res/values/strings.xml文件中添加相應的字符串

    
    Camera button twice,open flash light
    POC button twice,open flash light
    After open this feature, the camera can not be used
    

 

第二步:對該開關按鈕做邏輯處理,在packages/apps/Settings/src/com/android/settings/accessibility/AccessibilitySettings.java文件中

先定義一個字符串常量,該常量為添加的開關的key,定義該按鈕開關常量和SharedPreences常量,用來保存該按鈕打開關閉狀態值

 
    // added by ouyang start [2015-11-3] 
    private static final String TOGGLE_CAMER_BUTTON_START_FLASHLIGHT_PREFERENCE =
            toggle_camera_button__start_flashlight_preference;
    // added by ouyang end [2015-11-3] 
    
    // added by ouyang start [2015-11-3] 
	private SwitchPreference mToggleCameraButtonStartFlashlightPreference;
	private SharedPreferences preferences;
	private SharedPreferences.Editor editor;
	// added by ouyang end   [2015-11-3] 

 

通過該字符串找到定義的開關,並做些處理,如從保存好的Perference中讀取開關打開關閉狀態並顯示,在initializeAllPreferences方法中,添加如下代碼

// added by ouyang start [2015-11-3] 
        mToggleCameraButtonStartFlashlightPreference =
                (SwitchPreference) findPreference(TOGGLE_CAMER_BUTTON_START_FLASHLIGHT_PREFERENCE);
        if (android.os.SystemProperties.isHanbangVersion()) {
        	Log.e(TAG, is HanbangVersion());
            mToggleCameraButtonStartFlashlightPreference.setEnabled(false);
        }else{
        	Log.e(TAG, is not HanbangVersion());
            mToggleCameraButtonStartFlashlightPreference.setEnabled(true);
        }
        Log.e(TAG, mToggleCameraButtonStartFlashlightPreference.isEbable=+  mToggleCameraButtonStartFlashlightPreference.isEnabled());
        if (android.os.SystemProperties.isDT800Project()) {
        	mToggleCameraButtonStartFlashlightPreference.setTitle(R.string.accessibility_camera_button_start_flashlight_preference_title);
		}else if (android.os.SystemProperties.isE580Project()) {
			mToggleCameraButtonStartFlashlightPreference.setTitle(R.string.accessibility_camera_button_start_flashlight_preference_title_E580);
		}
        preferences= getActivity().getApplicationContext().getSharedPreferences(FlashLight,
                            Context.MODE_MULTI_PROCESS
                           +Context.MODE_WORLD_READABLE 
                           +Context.MODE_WORLD_WRITEABLE);
        editor=preferences.edit();
        boolean flashChecked=preferences.getBoolean(flashChecked, false);
        mToggleCameraButtonStartFlashlightPreference.setChecked(flashChecked);
        Log.e(TAG, flashChecked=+flashChecked);
        // added by ouyang end [2015-11-3] 


這段代碼主要是對該開關進行初始化,並對不同的項目進行判斷,DT800項目和E580項目加載不同的字符串來描述開關。這些方法可以在/frameworks/base/core/java/android/os/SystemProperties.java文件中自己添加,代碼如下:

       public static boolean isDT800Project() {
		return SystemProperties.get(ro.custom.build.version).contains(DT800);
       }   

        public static boolean isE580Project() {
		return SystemProperties.get(ro.custom.build.version).contains(E580);
        }

        public static boolean isHanbangVersion(){
		return SystemProperties.get(ro.product.model).contains(Hanbang);
        }
  

在packages/apps/Settings/src/com/android/settings/accessibility/AccessibilitySettings.java文件中的onPreferenceTreeClick方法中,要添加對該開關的點擊事件處理。

代碼如下,添加幾行代碼:

else if (mTogglePowerButtonEndsCallPreference == preference) {
            handleTogglePowerButtonEndsCallPreferenceClick();
            return true;
        } 
        // added by ouyang start [2015-11-3] 
        else if (mToggleCameraButtonStartFlashlightPreference == preference) {
            handleToggleCameraButtonStartFlashlightPreferenceClick();
            return true;
        } 
        // added by ouyang end [2015-11-3] 
        else if (mToggleLockScreenRotationPreference == preference) {
            handleLockScreenRotationPreferenceClick();
            return true;
        } 


其中handleToggleCameraButtonStartFlashlightPreferenceClick()方法自己自定義的,代碼如下:

   // added by ouyang start [2015-11-3] 
    private void handleToggleCameraButtonStartFlashlightPreferenceClick(){
    	if (mToggleCameraButtonStartFlashlightPreference.isChecked()) {
            editor.putBoolean(flashChecked, true);
            editor.commit();
	}else{
	   editor.putBoolean(flashChecked, false);
	   editor.commit();
	}
    }
    // added by ouyang end [2015-11-3] 


該方法主要功能是保存該開關是打開狀態還是關閉狀態,這個狀態值可以讓其他的進程讀取。

 

第三步:定義一個BroadcastReceiver,並動態注冊該廣播。代碼文件在frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java

,在該文件中添加一個BroadcastReceiver

 //added by ouyang
    private final BroadcastReceiver mFlashBroadcastReceiver =new BroadcastReceiver(){
    	boolean isDoublePress = false;
    	@Override
    	public void onReceive(Context context, Intent intent) {
    		String action = intent.getAction();
    		Log.d(TAG, action=  + action);
    		Log.d(TAG, isDoublePress=  + isDoublePress);
    		Log.d(TAG, now time =  + new SimpleDateFormat(yyyy-MM-dd hh:mm:ss.SSS).format(new Date()));
    		if ((action == com.runbo.camera.key.up) || (action == com.runbo.poc.key.up)) {
    			Handler checkHandler = new Handler();
    			if (!isDoublePress) {
    				isDoublePress = true;
    				Log.i(TAG, <----===============Single Press the Camera Key---->);
    				Runnable CheckDoubleRunnable = new Runnable() {
    					@Override
    					public void run() {
    						isDoublePress = false;
    					}
    				};
    				checkHandler.postDelayed(CheckDoubleRunnable, 500);
    			} else {
    				isDoublePress = false;
    				Log.i(TAG, <----============Double Press the Camera Key ---->);
    				boolean handlerReceiver = false;  
    				boolean flashChecked=false;
    				try {
    					Context myContext= context.createPackageContext(com.android.settings,
    							Context.CONTEXT_IGNORE_SECURITY);
    					SharedPreferences sharedPreferences = myContext.getSharedPreferences(FlashLight,
    							Context.MODE_WORLD_READABLE | Context.MODE_MULTI_PROCESS);
        				flashChecked = sharedPreferences.getBoolean(flashChecked, false);
					} catch (Exception e) {
						Log.d(TAG, Log.getStackTraceString(e));
					}				
    				if (action == com.runbo.camera.key.up) {
    					if (android.os.SystemProperties.isDT800Project()
    							&& !android.os.SystemProperties.isHanbangVersion()) {
    						handlerReceiver = true;
    					}
    				} else if (action == com.runbo.poc.key.up) {
    					if (android.os.SystemProperties.isE580Project()) {
    						handlerReceiver = true;
    					}
    				}
    				Log.d(TAG, handlerReceiver=  + handlerReceiver);
    				Log.d(TAG, flashChecked=  + flashChecked);
    				if (handlerReceiver && flashChecked) {
    					Log.i(TAG, ============mState.value=+mState.value);
    					if (!mState.value) {
    						boolean newState = !mState.value;
    						mFlashlightController.setFlashlight(newState);
    					    refreshState(newState ? UserBoolean.USER_TRUE : UserBoolean.USER_FALSE);
    						Log.i(TAG, ============setFlashlight(true);============);
						}else{
							boolean newState = !mState.value;
    						mFlashlightController.setFlashlight(newState);
    					    refreshState(newState ? UserBoolean.USER_TRUE : UserBoolean.USER_FALSE);
							Log.i(TAG, ============setFlashlight(false);============);
						}
    				}
    			}
    		}
    	}
    };


在FlashlightTile的構造方法中進行注冊,代碼如下:

  public FlashlightTile(Host host) {
        super(host);
        mFlashlightController = host.getFlashlightController();
        mFlashlightController.addListener(this);
        
        //added by ouyang start
        IntentFilter pocFilter = new IntentFilter();
        pocFilter.addAction(com.runbo.poc.key.up);
        pocFilter.addAction(com.runbo.camera.key.up);
        this.mContext.registerReceiver(mFlashBroadcastReceiver, pocFilter);
        Log.d(TAG, registerReceiver(mFlashBroadcastReceiver, pocFilter));
        //added by ouyang end
    }

 

該BroadcastReceiver接收通過按POC鍵後釋放而發送的廣播“com.runbo.poc.key.up”和通過按Camera鍵後釋放而發送的廣播“com.runbo.camera.key.up”,這兩個廣播是自定義的廣播。然後判斷是單擊還是雙擊,當雙擊後再通過讀取SharedPreferences的值來判斷定義的開關是否是打開的,如果開關是打開的再判斷閃光燈是打開還是關閉,如果是打開的,雙擊後就關閉閃光燈。如果是關閉的,就打開閃光燈。並更新下拉菜單的圖標和相應的狀態。如果開關是關閉的,不進行打開關閉閃光燈的操作。

 

 
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved