原文地址:http://blog.csdn.net/stevenhu_223/article/details/9052083?reload#java
在Android源碼中,提供的快捷開關相對是比較少的,Android4.0系統默認提供的桌面快捷開關AppWidget上只有5種開關(分別是Wifi開關、藍牙開關、GPS開關、同步開關、亮度設置開關)如下圖所示:
當然,有時候就需要開發實現承載更多的快捷開關的AppWidget來實現用戶體驗,所以,本文主要針對這些開關的主要代碼實現來重點解決開發這些快捷開關。
本文涉及到的快捷開關代碼實現有Wifi、藍牙、GPS、同步、亮度設置、飛行模式、移動數據流量(實現開啓和關閉移動網絡)、靜音模式、重啓、關機、鎖屏、屏幕旋轉等。需要注意的是:實現這些開關控制時都需要在AndroidManifest.xml文件中添加相應的權限。
一般這些開關在被設置改變時,系統會向外界發送相應的廣播。所以,當用代碼實現操作這些開關時,我們可以通過動態註冊廣播接收器,來接收這些系統發送的狀態改變廣播,以此來驗證我們是否正常設置改變了這些開關。
當然,在本文以下的一些實例代碼中,開關按鈕也隨着狀態的改變而顯示不同的文字,動態註冊廣播接收會顯得有點多餘,不過這只是證明系統會發送相應的廣播,還應用開發還是有用處的,至少我們可以在不同的進程中監聽接收這些廣播。
1. Wifi開關:
1). Wifi開關由WifiManager這個類控制實現。
2). 當Wifi開關改變時,系統會向外界發送廣播android.net.wifi.WIFI_STATE_CHANGED;
示列代碼如下:
- package com.example.wst;
- import android.app.Activity;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.net.wifi.WifiManager;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class WifiSwitchTest extends Activity implements OnClickListener
- {
- private WifiManager mWifiManager;
- private Button mWifiButton;
- //Wifi設置改變系統發送的廣播
- public static final String WIFI_STATE_CHANGED = "android.net.wifi.WIFI_STATE_CHANGED";
- private TestChange mTestChange;
- private IntentFilter mIntentFilter;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
- mTestChange = new TestChange();
- mIntentFilter = new IntentFilter();
- // 添加廣播接收器過濾的廣播
- mIntentFilter.addAction("android.net.wifi.WIFI_STATE_CHANGED");
- mWifiButton = (Button)findViewById(R.id.wifi);
- refreshButton();
- mWifiButton.setOnClickListener(this);
- }
- @Override
- protected void onDestroy()
- {
- // TODO Auto-generated method stub
- super.onDestroy();
- // 解除廣播接收器
- unregisterReceiver(mTestChange);
- }
- @Override
- protected void onResume()
- {
- // TODO Auto-generated method stub
- super.onResume();
- // 註冊廣播接收器
- registerReceiver(mTestChange, mIntentFilter);
- }
- //更新按鈕
- private void refreshButton()
- {
- mWifiButton.setText(mWifiManager.isWifiEnabled() ? R.string.wifi_off : R.string.wifi_on);
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- if (mWifiManager.isWifiEnabled())
- {
- //關閉Wifi,按鈕顯示開啓
- mWifiManager.setWifiEnabled(false);
- }
- else
- {
- //開啓Wifi,按鈕顯示關閉
- mWifiManager.setWifiEnabled(true);
- }
- }
- private class TestChange extends BroadcastReceiver
- {
- @Override
- public void onReceive(Context context, Intent intent)
- {
- // TODO Auto-generated method stub
- String action = intent.getAction();
- if (WIFI_STATE_CHANGED.equals(action))
- {
- refreshButton();
- Toast.makeText(WifiSwitchTest.this, "Wifi設置有改變",
- Toast.LENGTH_SHORT).show();
- }
- }
- }
- }
權限添加:
- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
- <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
2. 藍牙開關:
1). 藍牙開關主要調用BluetoothAdapter相關方法實現
2). 藍牙有四種狀態:正在打開、打開、正在關閉、關閉
3). 藍牙狀態改變,系統向外界發送廣播android.bluetooth.adapter.action.STATE_CHANGED或android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED;
示例代碼如下:
- package com.example.bts;
- import android.app.Activity;
- import android.bluetooth.BluetoothAdapter;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class BluetoothSwitch extends Activity implements OnClickListener
- {
- private Button mBluetooth;
- private BluetoothAdapter mBluetoothAdapter;
- private TestChange mTestChange;
- private IntentFilter mIntentFilter;
- public static final String BLUETOOTH_STATE_CHANGED = "android.bluetooth.adapter.action.STATE_CHANGED";
- private static final String BLUETOOTH_ACTION = "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED";
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
- mTestChange = new TestChange();
- mIntentFilter = new IntentFilter();
- // 添加廣播接收器過濾的廣播
- mIntentFilter.addAction("android.bluetooth.adapter.action.STATE_CHANGED");
- mIntentFilter.addAction("android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED");
- mBluetooth = (Button)findViewById(R.id.blue);
- refreshButton();
- mBluetooth.setOnClickListener(this);
- }
- @Override
- protected void onDestroy()
- {
- // TODO Auto-generated method stub
- super.onDestroy();
- // 解除廣播接收器
- unregisterReceiver(mTestChange);
- }
- @Override
- protected void onResume()
- {
- // TODO Auto-generated method stub
- super.onResume();
- // 註冊廣播接收器
- registerReceiver(mTestChange, mIntentFilter);
- }
- //更新按鈕狀態
- private void refreshButton()
- {
- switch (getBluetoothStatus())
- {
- case BluetoothAdapter.STATE_ON:
- mBluetooth.setText(R.string.off);
- break;
- case BluetoothAdapter.STATE_TURNING_ON:
- mBluetooth.setText(R.string.oning);
- break;
- case BluetoothAdapter.STATE_OFF:
- mBluetooth.setText(R.string.on);
- break;
- case BluetoothAdapter.STATE_TURNING_OFF:
- mBluetooth.setText(R.string.offing);
- break;
- }
- }
- //獲取藍牙當前狀態
- private int getBluetoothStatus()
- {
- return mBluetoothAdapter.getState();
- }
- //設置藍牙開關
- private void setBluetoothStatus()
- {
- switch (getBluetoothStatus())
- {
- case BluetoothAdapter.STATE_ON:
- mBluetoothAdapter.disable();
- break;
- case BluetoothAdapter.STATE_TURNING_ON:
- mBluetoothAdapter.disable();
- break;
- case BluetoothAdapter.STATE_OFF:
- mBluetoothAdapter.enable();
- break;
- case BluetoothAdapter.STATE_TURNING_OFF:
- mBluetoothAdapter.enable();
- break;
- }
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- setBluetoothStatus();
- }
- private class TestChange extends BroadcastReceiver
- {
- @Override
- public void onReceive(Context context, Intent intent)
- {
- // TODO Auto-generated method stub
- String action = intent.getAction();
- if (BLUETOOTH_STATE_CHANGED.equals(action) || BLUETOOTH_ACTION.equals(action))
- {
- Toast.makeText(BluetoothSwitch.this, "藍牙模式設置有改變",
- Toast.LENGTH_SHORT).show();
- //動態刷新按鈕
- refreshButton();
- }
- }
- }
- }
權限添加:
- <uses-permission android:name="android.permission.BLUETOOTH" />
- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
3. 屏幕旋轉開關:
1). 屏幕旋轉開關設置主要調用android.provider.Settings.System的putInt和getInt方法實現。
2). 通過ContentObserver來動態觀察屏幕旋轉設置的改變。
示例代碼如下:
- package com.example.srs;
- import android.app.Activity;
- import android.content.ContentResolver;
- import android.content.Context;
- import android.database.ContentObserver;
- import android.net.Uri;
- import android.os.Bundle;
- import android.os.Handler;
- import android.provider.Settings;
- import android.provider.Settings.SettingNotFoundException;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class ScreenRotationSwitch extends Activity implements OnClickListener
- {
- private Button mRotationButton;
- private RotationObserver mRotationObserver;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- //創建觀察類對象
- mRotationObserver = new RotationObserver(new Handler());
- mRotationButton = (Button) findViewById(R.id.rotation);
- refreshButton();
- mRotationButton.setOnClickListener(this);
- }
- @Override
- protected void onDestroy() {
- // TODO Auto-generated method stub
- super.onDestroy();
- //解除觀察變化
- mRotationObserver.stopObserver();
- }
- @Override
- protected void onResume() {
- // TODO Auto-generated method stub
- super.onResume();
- //註冊觀察變化
- mRotationObserver.startObserver();
- }
- //更新按鈕狀態
- private void refreshButton()
- {
- if (getRotationStatus(this) == 1)
- {
- mRotationButton.setText(R.string.rotation_off);
- }
- else
- {
- mRotationButton.setText(R.string.rotation_on);
- }
- }
- //得到屏幕旋轉的狀態
- private int getRotationStatus(Context context)
- {
- int status = 0;
- try
- {
- status = android.provider.Settings.System.getInt(context.getContentResolver(),
- android.provider.Settings.System.ACCELEROMETER_ROTATION);
- }
- catch (SettingNotFoundException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return status;
- }
- private void setRotationStatus(ContentResolver resolver, int status)
- {
- //得到uri
- Uri uri = android.provider.Settings.System.getUriFor("accelerometer_rotation");
- //溝通設置status的值改變屏幕旋轉設置
- android.provider.Settings.System.putInt(resolver, "accelerometer_rotation", status);
- //通知改變
- resolver.notifyChange(uri, null);
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- if (getRotationStatus(this) == 1)
- {
- setRotationStatus(getContentResolver(), 0);
- }
- else
- {
- setRotationStatus(getContentResolver(), 1);
- }
- }
- //觀察屏幕旋轉設置變化,類似於註冊動態廣播監聽變化機制
- private class RotationObserver extends ContentObserver
- {
- ContentResolver mResolver;
- public RotationObserver(Handler handler)
- {
- super(handler);
- mResolver = getContentResolver();
- // TODO Auto-generated constructor stub
- }
- //屏幕旋轉設置改變時調用
- @Override
- public void onChange(boolean selfChange)
- {
- // TODO Auto-generated method stub
- super.onChange(selfChange);
- //更新按鈕狀態
- refreshButton();
- Toast.makeText(ScreenRotationSwitch.this, "旋轉屏幕設置有變化",
- Toast.LENGTH_SHORT).show();
- }
- public void startObserver()
- {
- mResolver.registerContentObserver(Settings.System
- .getUriFor(Settings.System.ACCELEROMETER_ROTATION), false,
- this);
- }
- public void stopObserver()
- {
- mResolver.unregisterContentObserver(this);
- }
- }
- }
權限添加:
- <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
4. 同步開關:
1). 同步開關設置主要由ContentResolver類(抽象類)的靜態函數來實現;
2). 當同步模式改變時,系統會向外界發送廣播com.android.sync.SYNC_CONN_STATUS_CHANGED;
示例代碼如下:
- package com.example.sst;
- import android.app.Activity;
- import android.content.BroadcastReceiver;
- import android.content.ContentResolver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.net.ConnectivityManager;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class SyncSwitchTest extends Activity implements OnClickListener
- {
- private Button mSyncButton;
- private TestChange mTestChange;
- private IntentFilter mIntentFilter;
- //同步模式改變系統發送的廣播
- private static final String SYNC_CONN_STATUS_CHANGED = "com.android.sync.SYNC_CONN_STATUS_CHANGED";
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mTestChange = new TestChange();
- mIntentFilter = new IntentFilter();
- //添加廣播接收器過濾的廣播
- mIntentFilter.addAction("com.android.sync.SYNC_CONN_STATUS_CHANGED");
- mSyncButton = (Button)findViewById(R.id.sync);
- refreshButton();
- mSyncButton.setOnClickListener(this);
- }
- @Override
- protected void onDestroy()
- {
- // TODO Auto-generated method stub
- super.onDestroy();
- //解除廣播接收器
- unregisterReceiver(mTestChange);
- }
- @Override
- protected void onResume() {
- // TODO Auto-generated method stub
- super.onResume();
- //註冊廣播接收器
- registerReceiver(mTestChange, mIntentFilter);
- }
- //更新按鈕狀態
- private void refreshButton()
- {
- mSyncButton.setText(getSyncStatus(this) ? R.string.sync_off : R.string.sync_on);
- }
- private boolean getSyncStatus(Context context)
- {
- ConnectivityManager connManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
- return connManager.getBackgroundDataSetting() && ContentResolver.getMasterSyncAutomatically();
- }
- private void setSyncStatus(boolean enbled)
- {
- /*getMasterSyncAutomatically和setMasterSyncAutomatically爲抽象類ContentResolver的靜態函數,
- * 所以可以直接通過類來調用
- */
- ContentResolver.setMasterSyncAutomatically(enbled);
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- if(getSyncStatus(this))
- {
- setSyncStatus(false);
- }
- else
- {
- setSyncStatus(true);
- }
- }
- private class TestChange extends BroadcastReceiver
- {
- @Override
- public void onReceive(Context context, Intent intent)
- {
- // TODO Auto-generated method stub
- String action = intent.getAction();
- if (SYNC_CONN_STATUS_CHANGED.equals(action))
- {
- refreshButton();
- Toast.makeText(SyncSwitchTest.this, "同步模式設置有改變", Toast.LENGTH_SHORT).show();
- }
- }
- }
- }
權限添加:
- <uses-permission android:name="android.permission.READ_SYNC_STATS" />
- <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
- <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
5. 亮度設置開關:
1). 亮度設置的主要調用Settings.System的putInt和getInt方法來處理,已經調用PowerManager的setBacklightBrightness方法來實現調節手機亮度。
2). PowerManager的setBacklightBrightness的方法是隱藏的,通過反射來調用實現。
3). 通過ContentObserver來動態觀察亮度設置的改變。
示例代碼如下:
- package com.example.bs;
- import java.lang.reflect.Field;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import android.app.Activity;
- import android.content.ContentResolver;
- import android.content.Context;
- import android.database.ContentObserver;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.PowerManager;
- import android.provider.Settings;
- import android.provider.Settings.SettingNotFoundException;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class BrightnessSwitch extends Activity implements OnClickListener
- {
- private Button mBrightness;
- private static final int LIGHT_NORMAL = 64;
- private static final int LIGHT_50_PERCENT = 127;
- private static final int LIGHT_75_PERCENT = 191;
- private static final int LIGHT_100_PERCENT = 255;
- private static final int LIGHT_AUTO = 0;
- private static final int LIGHT_ERR = -1;
- private BrightObserver mBrightObserver;
- private PowerManager mPowerManager;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mPowerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
- mBrightObserver = new BrightObserver(new Handler());
- mBrightness = (Button)findViewById(R.id.bright);
- refreshButton();
- mBrightness.setOnClickListener(this);
- }
- @Override
- protected void onDestroy()
- {
- // TODO Auto-generated method stub
- super.onDestroy();
- mBrightObserver.stopObserver();
- }
- @Override
- protected void onResume()
- {
- // TODO Auto-generated method stub
- super.onResume();
- mBrightObserver.startObserver();
- }
- //更新按鈕
- private void refreshButton()
- {
- switch (getBrightStatus())
- {
- case LIGHT_NORMAL:
- mBrightness.setText(R.string.light_50percent);
- break;
- case LIGHT_50_PERCENT:
- mBrightness.setText(R.string.light_75percent);
- break;
- case LIGHT_75_PERCENT:
- mBrightness.setText(R.string.light_100percent);
- break;
- case LIGHT_100_PERCENT:
- mBrightness.setText(R.string.light_auto);
- break;
- case LIGHT_AUTO:
- mBrightness.setText(R.string.light_normal);
- break;
- case LIGHT_ERR:
- mBrightness.setText(R.string.light_err);
- break;
- }
- }
- //得到當前亮度值狀態
- private int getBrightStatus()
- {
- // TODO Auto-generated method stub
- int light = 0;
- boolean auto = false;
- ContentResolver cr = getContentResolver();
- try
- {
- auto = Settings.System.getInt(cr,
- Settings.System.SCREEN_BRIGHTNESS_MODE) == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
- if (!auto)
- {
- light = android.provider.Settings.System.getInt(cr,
- Settings.System.SCREEN_BRIGHTNESS, -1);
- if (light > 0 && light <= LIGHT_NORMAL)
- {
- return LIGHT_NORMAL;
- }
- else if (light > LIGHT_NORMAL && light <= LIGHT_50_PERCENT)
- {
- return LIGHT_50_PERCENT;
- }
- else if (light > LIGHT_50_PERCENT && light <= LIGHT_75_PERCENT)
- {
- return LIGHT_75_PERCENT;
- }
- else if (light > LIGHT_75_PERCENT && light <= LIGHT_100_PERCENT)
- {
- return LIGHT_100_PERCENT;
- }
- }
- else
- {
- return LIGHT_AUTO;
- }
- }
- catch (SettingNotFoundException e1)
- {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
- return LIGHT_ERR;
- }
- private void setBrightStatus()
- {
- int light = 0;
- switch (getBrightStatus())
- {
- case LIGHT_NORMAL:
- light = LIGHT_50_PERCENT - 1;
- break;
- case LIGHT_50_PERCENT:
- light = LIGHT_75_PERCENT - 1;
- break;
- case LIGHT_75_PERCENT:
- light = LIGHT_100_PERCENT - 1;
- break;
- case LIGHT_100_PERCENT:
- startAutoBrightness(getContentResolver());
- break;
- case LIGHT_AUTO:
- light = LIGHT_NORMAL - 1;
- stopAutoBrightness(getContentResolver());
- break;
- case LIGHT_ERR:
- light = LIGHT_NORMAL - 1;
- break;
- }
- setLight(light);
- setScreenLightValue(getContentResolver(), light);
- }
- /*因爲PowerManager提供的函數setBacklightBrightness接口是隱藏的,
- * 所以在基於第三方開發調用該函數時,只能通過反射實現在運行時調用
- */
- private void setLight(int light)
- {
- try
- {
- //得到PowerManager類對應的Class對象
- Class<?> pmClass = Class.forName(mPowerManager.getClass().getName());
- //得到PowerManager類中的成員mService(mService爲PowerManagerService類型)
- Field field = pmClass.getDeclaredField("mService");
- field.setAccessible(true);
- //實例化mService
- Object iPM = field.get(mPowerManager);
- //得到PowerManagerService對應的Class對象
- Class<?> iPMClass = Class.forName(iPM.getClass().getName());
- /*得到PowerManagerService的函數setBacklightBrightness對應的Method對象,
- * PowerManager的函數setBacklightBrightness實現在PowerManagerService中
- */
- Method method = iPMClass.getDeclaredMethod("setBacklightBrightness", int.class);
- method.setAccessible(true);
- //調用實現PowerManagerService的setBacklightBrightness
- method.invoke(iPM, light);
- }
- catch (ClassNotFoundException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- catch (NoSuchFieldException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- catch (IllegalArgumentException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- catch (IllegalAccessException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- catch (NoSuchMethodException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- catch (InvocationTargetException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- setBrightStatus();
- }
- //啓動自動調節亮度
- public void startAutoBrightness(ContentResolver cr)
- {
- Settings.System.putInt(cr, Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
- }
- //關閉自動調節亮度
- public void stopAutoBrightness(ContentResolver cr)
- {
- Settings.System.putInt(cr, Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
- }
- //設置改變亮度值
- public void setScreenLightValue(ContentResolver resolver, int value)
- {
- android.provider.Settings.System.putInt(resolver, Settings.System.SCREEN_BRIGHTNESS,
- value);
- }
- private class BrightObserver extends ContentObserver
- {
- ContentResolver mResolver;
- public BrightObserver(Handler handler)
- {
- super(handler);
- mResolver = getContentResolver();
- }
- @Override
- public void onChange(boolean selfChange)
- {
- // TODO Auto-generated method stub
- super.onChange(selfChange);
- refreshButton();
- Toast.makeText(BrightnessSwitch.this, "亮度設置有改變", Toast.LENGTH_SHORT).show();
- }
- //註冊觀察
- public void startObserver()
- {
- mResolver.registerContentObserver(Settings.System
- .getUriFor(Settings.System.SCREEN_BRIGHTNESS), false,
- this);
- mResolver.registerContentObserver(Settings.System
- .getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE), false,
- this);
- }
- //解除觀察
- public void stopObserver()
- {
- mResolver.unregisterContentObserver(this);
- }
- }
- }
權限添加:
- <uses-permission android:name="android.permission.WRITE_SETTINGS" />
- <uses-permission android:name="android.permission.DEVICE_POWER" />
6. 飛行模式開關:
1). 飛行模式主要是調用Settings.System的getInt和setInt方法來處理。
2). 當飛行模式改變時,系統會向外界發送廣播android.intent.action.AIRPLANE_MODE;
示例代碼如下:
- package com.example.apmst;
- import android.app.Activity;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.os.Bundle;
- import android.provider.Settings;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class AirplaneModeSwitchTest extends Activity implements OnClickListener
- {
- private Button mAirplane;
- //飛行模式設置改變系統發送的廣播
- private static final String AIRPLANE_MODE = "android.intent.action.AIRPLANE_MODE";
- private TestChange mTestChange;
- private IntentFilter mIntentFilter;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mTestChange = new TestChange();
- mIntentFilter = new IntentFilter();
- // 添加廣播接收器過濾的廣播
- mIntentFilter.addAction("android.intent.action.AIRPLANE_MODE");
- mAirplane = (Button)findViewById(R.id.airplane);
- refreshButton();
- mAirplane.setOnClickListener(this);
- }
- @Override
- protected void onDestroy()
- {
- // TODO Auto-generated method stub
- super.onDestroy();
- // 解除廣播接收器
- unregisterReceiver(mTestChange);
- }
- @Override
- protected void onResume()
- {
- // TODO Auto-generated method stub
- super.onResume();
- // 註冊廣播接收器
- registerReceiver(mTestChange, mIntentFilter);
- }
- //更新按鈕狀態
- private void refreshButton()
- {
- mAirplane.setText(getAirplaneModeStatus() ? R.string.airplane_off : R.string.airplane_on);
- }
- //獲取飛行模式關閉或開啓狀態
- private boolean getAirplaneModeStatus()
- {
- boolean status = Settings.System.getInt(this.getContentResolver(),
- Settings.System.AIRPLANE_MODE_ON, 0) == 1 ? true : false;
- return status;
- }
- //開啓或關閉飛行模式
- private void setAirplaneMode(Context context, boolean enable)
- {
- Settings.System.putInt(context.getContentResolver(),
- Settings.System.AIRPLANE_MODE_ON, enable ? 1 : 0);
- Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
- intent.putExtra("state", enable);
- context.sendBroadcast(intent);
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- if (getAirplaneModeStatus())
- {
- setAirplaneMode(this, false);
- }
- else
- {
- setAirplaneMode(this, true);
- }
- }
- private class TestChange extends BroadcastReceiver
- {
- @Override
- public void onReceive(Context context, Intent intent)
- {
- // TODO Auto-generated method stub
- String action = intent.getAction();
- if (AIRPLANE_MODE.equals(action))
- {
- refreshButton();
- Toast.makeText(AirplaneModeSwitchTest.this, "飛行模式設置有改變",
- Toast.LENGTH_SHORT).show();
- }
- }
- }
- }
權限添加:
- <uses-permission android:name="android.permission.WRITE_SETTINGS" />
7. 移動數據流量開關:
1). 移動數據流量由ConnectivityManager類控制實現,這個類實現設置和獲取移動流量狀態的方法是隱藏的,所以我們只能通過反射來實現(或者在源碼下編譯APK)。
2). 相關廣播爲android.intent.action.ANY_DATA_STATE;
示例代碼如下:
- package com.example.mdst;
- import java.lang.reflect.Field;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import android.app.Activity;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.net.ConnectivityManager;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class MobileDataSwitchTest extends Activity implements OnClickListener
- {
- private ConnectivityManager mConnectivityManager;
- private Button mMobileDataButton;
- // 移動數據設置改變系統發送的廣播
- private static final String NETWORK_CHANGE = "android.intent.action.ANY_DATA_STATE";
- private TestChange mTestChange;
- private IntentFilter mIntentFilter;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mConnectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
- mTestChange = new TestChange();
- mIntentFilter = new IntentFilter();
- // 添加廣播接收器過濾的廣播
- mIntentFilter.addAction("android.intent.action.ANY_DATA_STATE");
- mMobileDataButton = (Button) findViewById(R.id.mobile_data);
- refreshButton();
- mMobileDataButton.setOnClickListener(this);
- }
- @Override
- protected void onDestroy()
- {
- // TODO Auto-generated method stub
- super.onDestroy();
- // 解除廣播接收器
- unregisterReceiver(mTestChange);
- }
- @Override
- protected void onResume()
- {
- // TODO Auto-generated method stub
- super.onResume();
- // 註冊廣播接收器
- registerReceiver(mTestChange, mIntentFilter);
- }
- private void refreshButton()
- {
- mMobileDataButton.setText(getMobileDataStatus() ? R.string.mobile_data_off : R.string.mobile_data_on);
- }
- //獲取移動數據開關狀態
- private boolean getMobileDataStatus()
- {
- String methodName = "getMobileDataEnabled";
- Class cmClass = mConnectivityManager.getClass();
- Boolean isOpen = null;
- try
- {
- Method method = cmClass.getMethod(methodName, null);
- isOpen = (Boolean) method.invoke(mConnectivityManager, null);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- return isOpen;
- }
- // 通過反射實現開啓或關閉移動數據
- private void setMobileDataStatus(boolean enabled)
- {
- try
- {
- Class<?> conMgrClass = Class.forName(mConnectivityManager.getClass().getName());
- //得到ConnectivityManager類的成員變量mService(ConnectivityService類型)
- Field iConMgrField = conMgrClass.getDeclaredField("mService");
- iConMgrField.setAccessible(true);
- //mService成員初始化
- Object iConMgr = iConMgrField.get(mConnectivityManager);
- //得到mService對應的Class對象
- Class<?> iConMgrClass = Class.forName(iConMgr.getClass().getName());
- /*得到mService的setMobileDataEnabled(該方法在android源碼的ConnectivityService類中實現),
- * 該方法的參數爲布爾型,所以第二個參數爲Boolean.TYPE
- */
- Method setMobileDataEnabledMethod = iConMgrClass.getDeclaredMethod(
- "setMobileDataEnabled", Boolean.TYPE);
- setMobileDataEnabledMethod.setAccessible(true);
- /*調用ConnectivityManager的setMobileDataEnabled方法(方法是隱藏的),
- * 實際上該方法的實現是在ConnectivityService(系統服務實現類)中的
- */
- setMobileDataEnabledMethod.invoke(iConMgr, enabled);
- } catch (ClassNotFoundException e)
- {
- e.printStackTrace();
- } catch (NoSuchFieldException e)
- {
- e.printStackTrace();
- } catch (SecurityException e)
- {
- e.printStackTrace();
- } catch (NoSuchMethodException e)
- {
- e.printStackTrace();
- } catch (IllegalArgumentException e)
- {
- e.printStackTrace();
- } catch (IllegalAccessException e)
- {
- e.printStackTrace();
- } catch (InvocationTargetException e)
- {
- e.printStackTrace();
- }
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- if (getMobileDataStatus())
- {
- setMobileDataStatus(false);
- mMobileDataButton.setText(R.string.mobile_data_on);
- }
- else
- {
- setMobileDataStatus(true);
- mMobileDataButton.setText(R.string.mobile_data_off);
- }
- }
- private class TestChange extends BroadcastReceiver
- {
- @Override
- public void onReceive(Context context, Intent intent)
- {
- // TODO Auto-generated method stub
- String action = intent.getAction();
- if (NETWORK_CHANGE.equals(action))
- {
- Toast.makeText(MobileDataSwitchTest.this, "移動數據設置有改變",
- Toast.LENGTH_SHORT).show();
- }
- }
- }
- }
權限添加:
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
- <uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />
8. 靜音模式開關:
1). 靜音模式由AudioManager控制實現,有三種狀態:正常(有聲音)、震動、靜音
2). 當模式改變時,系統會向外界發送廣播android.media.RINGER_MODE_CHANGED;
示例代碼如下:
- package com.example.sst;
- import android.app.Activity;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.media.AudioManager;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class SilentSwitchTes extends Activity implements OnClickListener
- {
- private AudioManager mAudioManager;
- private Button mSilentButton;
- private TestChange mTestChange;
- private IntentFilter mIntentFilter;
- //靜音模式改變系統發送的廣播
- public static final String RINGER_MODE_CHANGED = "android.media.RINGER_MODE_CHANGED";
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
- mTestChange = new TestChange();
- mIntentFilter = new IntentFilter();
- //添加廣播接收器過濾的廣播
- mIntentFilter.addAction("android.media.RINGER_MODE_CHANGED");
- mSilentButton = (Button)findViewById(R.id.silent);
- refreshButton();
- mSilentButton.setOnClickListener(this);
- }
- @Override
- protected void onDestroy()
- {
- // TODO Auto-generated method stub
- super.onDestroy();
- //解除廣播接收器
- unregisterReceiver(mTestChange);
- }
- @Override
- protected void onResume() {
- // TODO Auto-generated method stub
- super.onResume();
- //註冊廣播接收器
- registerReceiver(mTestChange, mIntentFilter);
- }
- //更新按鈕
- private void refreshButton()
- {
- switch (getSilentStatus())
- {
- case AudioManager.RINGER_MODE_SILENT:
- mSilentButton.setText(R.string.mode_vibrate);
- break;
- case AudioManager.RINGER_MODE_NORMAL:
- mSilentButton.setText(R.string.mode_silent);
- break;
- case AudioManager.RINGER_MODE_VIBRATE:
- mSilentButton.setText(R.string.mode_normal);
- break;
- }
- }
- //獲取手機當前的靜音模式狀態
- private int getSilentStatus()
- {
- return mAudioManager.getRingerMode();
- }
- //設置手機的靜音、正常、震動模式
- private void setSilentMode()
- {
- switch (getSilentStatus())
- {
- case AudioManager.RINGER_MODE_SILENT:
- mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
- break;
- case AudioManager.RINGER_MODE_NORMAL:
- mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
- break;
- case AudioManager.RINGER_MODE_VIBRATE:
- mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
- break;
- }
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- setSilentMode();
- }
- private class TestChange extends BroadcastReceiver
- {
- @Override
- public void onReceive(Context context, Intent intent)
- {
- // TODO Auto-generated method stub
- String action = intent.getAction();
- if (RINGER_MODE_CHANGED.equals(action))
- {
- refreshButton();
- Toast.makeText(SilentSwitchTes.this, "靜音模式設置有改變", Toast.LENGTH_SHORT).show();
- }
- }
- }
- }
靜音模式開關設置不需要添加權限。
<-----以下的開關設置實現需要有系統的UID使用Platform的apk簽名,否則是沒有權限調用的,會報SecurityException異常----->
注:1). 可以不通過apk簽名,直接在android源碼下編譯生成apk,再將apk安裝到手機;
2). 如果手機有root權限,那麼也不需要apk簽名,直接通過adb工具將apk推到system/app目錄下:操作指令爲adb remount---->adb push xxx.apk system/app (注:該apk將做爲系統應用)
9. GPS開關:
1). GPS開關設置的實現由Secure類的相關靜態方法實現。
2).Secure的isLocationProviderEnabled和setLocationProviderEnabled調用需要APK簽名;
示例代碼如下:
- package com.example.gst;
- import android.app.Activity;
- import android.content.Context;
- import android.location.LocationManager;
- import android.os.Bundle;
- import android.provider.Settings.Secure;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class GpsSwitchTest extends Activity implements OnClickListener
- {
- private Button mGpsButton;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mGpsButton = (Button)findViewById(R.id.gps);
- refreshButton();
- mGpsButton.setOnClickListener(this);
- }
- //根據當前的Gps狀態,初始化按鈕的顯示
- private void refreshButton()
- {
- mGpsButton.setText(getGpsStatus(this) ? R.string.gps_off : R.string.gps_on);
- }
- //獲取Gps開啓或關閉狀態
- private boolean getGpsStatus(Context context)
- {
- boolean status = Secure.isLocationProviderEnabled(context.getContentResolver(),
- LocationManager.GPS_PROVIDER);
- return status;
- }
- //打開或關閉Gps
- private void setGpsStatus(Context context, boolean enabled)
- {
- Secure.setLocationProviderEnabled(context.getContentResolver(),
- LocationManager.GPS_PROVIDER, enabled);
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- if (getGpsStatus(this))
- {
- setGpsStatus(this, false);
- mGpsButton.setText(R.string.gps_on);
- }
- else
- {
- setGpsStatus(this, true);
- mGpsButton.setText(R.string.gps_off);
- }
- }
- }
權限添加:
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
- <uses-permission android:name="android.permission.WRITE_SETTINGS" />
- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
10. 鎖屏:
1). 手機進入鎖屏主要由PowerManager的goToSleep函數實現。
2). PowerManager的goToSleep調用需要apk簽名。
示例代碼:
- package com.example.lsst;
- import android.app.Activity;
- import android.content.Context;
- import android.os.Bundle;
- import android.os.PowerManager;
- import android.os.SystemClock;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class LockScreenSwitchTest extends Activity implements OnClickListener
- {
- private PowerManager mPowerManager;
- private Button mLockButton;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
- mLockButton = (Button)findViewById(R.id.lock);
- mLockButton.setOnClickListener(this);
- }
- private void lockScreen()
- {
- //強制手機進入鎖屏,這時候手機會滅屏,點亮後是處於鎖屏狀態
- mPowerManager.goToSleep(SystemClock.uptimeMillis());
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- lockScreen();
- }
- }
權限添加:
- <uses-permission android:name="android.permission.USES_POLICY_FORCE_LOCK" />
- <uses-permission android:name="android.permission.DEVICE_POWER" />
11. 重啓:
1). 手機重啓需要調用PowerManager的reboot方法實現,參數爲null;
2). 該方法的調用,需要有系統的UID使用Platform的APK簽名,否則是沒有權限調用的,會報SecurityException異常。
示例代碼如下:
- package com.example.rs;
- import android.app.Activity;
- import android.content.Context;
- import android.os.Bundle;
- import android.os.PowerManager;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class RebootSwitch extends Activity implements OnClickListener
- {
- private Button mRebootButton;
- private PowerManager mPowerManager;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mPowerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
- mRebootButton = (Button)findViewById(R.id.reboot);
- mRebootButton.setOnClickListener(this);
- }
- private void reboot(String reason)
- {
- mPowerManager.reboot(null);
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- reboot(null);
- }
- }
權限添加:
- <uses-permission android:name="android.permission.REBOOT"/>
12. 關機:
1). 手機關機直接通過創建相關的Intent來啓動一個對話框,根據對話框的確認或取消鍵來選擇是否關機
2). 關機實現需要apk簽名。
示例代碼如下:
- package com.example.sds;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class ShutDownSwitch extends Activity implements OnClickListener
- {
- private Button mShutDown;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mShutDown = (Button)findViewById(R.id.shutdown);
- mShutDown.setOnClickListener(this);
- }
- @Override
- public void onClick(View v)
- {
- // TODO Auto-generated method stub
- Intent intent = new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN");
- intent.putExtra("android.intent.extra.KEY_CONFIRM", true);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- //彈出系統內置的對話框,選擇確定關機或取消關機
- startActivity(intent);
- }
- }
權限添加:
- <uses-permission android:name="android.permission.SHUTDOWN" />
ok,本文的快捷開關代碼實現介紹就到此結束,有了上面這些快捷開關的實現代碼,那麼當你想要開發一個AppWidget來承載和實現這些開關時就容易多了,至於如何去開發一個AppWidget,有興趣的讀者可以去找找相關這些方面的資料。
相關代碼下載鏈接:http://download.csdn.net/detail/stevenhu_223/5572751