編輯:關於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的值來判斷定義的開關是否是打開的,如果開關是打開的再判斷閃光燈是打開還是關閉,如果是打開的,雙擊後就關閉閃光燈。如果是關閉的,就打開閃光燈。並更新下拉菜單的圖標和相應的狀態。如果開關是關閉的,不進行打開關閉閃光燈的操作。
Chromium on Android: Android L平台上WebView的變化及其對浏覽器廠商的影響分析
摘要:Android L平台在圖形渲染方面有一項重要的改進,它引入了一個專門的線程用於執行渲染工作,UI線程負責生成的顯示列表(DisplayList),渲染線程負責重放
Android中的網絡編程
一、訪問網絡資源1、使用統一資源定位符獲取網絡資源的路徑urlURL url = new URL(path);2、通過url打開網絡連接(連接方式有http連接,ftp連
[深入剖析React Native]React 初探
認識ReactReact是一個用於構建用戶界面的JavaScript庫。 React主要用於構建UI,很多人認為React是MVC中的V,即視圖。 React起源於Fac
深入理解ButterKnife源碼並掌握原理(三)
上兩篇我們分析完了處理器的process方法的findAndParseTargets方法來獲取了一個集合,該集合包含了你使用注解的類的TypeElement和這個類中的注