編輯:關於Android編程
最近有一個客戶有這樣的需求:
1、在【設置】--->【無障礙】中添加一個開關按鈕。
如果打開開關的話,雙擊某個物理按鍵的時候,打開閃光燈,再雙擊該物理按鍵的時候,關閉閃光燈。
如果關閉開關的話,雙擊該物理按鍵的時候,不做任何處理。
2、打開關閉閃光燈的狀態,在下拉菜單中也要同步。
如下圖所示的效果:
當打開上面添加的開關後,如果雙擊POC鍵(POC鍵是我們公司自定義的一個物理按鍵)的時候,就打開閃光燈,並將下拉菜單中的閃光燈圖標點亮,如下圖所示
如果再次雙擊POC鍵(POC鍵是我們公司自定義的一個物理按鍵)的時候,就關閉閃光燈,並將下拉菜單中的閃光燈圖標熄滅,如下圖所示
====================================================================================================================================
下面來具體說說怎麼實現該功能:
第一步:添加開關按鈕布局
在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的值來判斷定義的開關是否是打開的,如果開關是打開的再判斷閃光燈是打開還是關閉,如果是打開的,雙擊後就關閉閃光燈。如果是關閉的,就打開閃光燈。並更新下拉菜單的圖標和相應的狀態。如果開關是關閉的,不進行打開關閉閃光燈的操作。
摘要:Android L平台在圖形渲染方面有一項重要的改進,它引入了一個專門的線程用於執行渲染工作,UI線程負責生成的顯示列表(DisplayList),渲染線程負責重放
一、訪問網絡資源1、使用統一資源定位符獲取網絡資源的路徑urlURL url = new URL(path);2、通過url打開網絡連接(連接方式有http連接,ftp連
認識ReactReact是一個用於構建用戶界面的JavaScript庫。 React主要用於構建UI,很多人認為React是MVC中的V,即視圖。 React起源於Fac
上兩篇我們分析完了處理器的process方法的findAndParseTargets方法來獲取了一個集合,該集合包含了你使用注解的類的TypeElement和這個類中的注