http://www.cnblogs.com/wii/archive/2012/03/18/2404947.html
對於android上GPS的控制,官方提供了相關的API
Settings.Secure.setLocationProviderEnabled(getContentResolver(), LocationManager.GPS_PROVIDER, true);
但是當我們調用setLocationProviderEnabled方法後,系統會拋出異常提示需要android.permission.WRITE_SECURE_SETTINGS的許可權,即便在mainfest中添加該許可權的請求也是一樣。setLocationProviderEnabled這個方法需要root的許可權,要使這個代碼能執行,程式就必須是系統的app,即安裝在/system/app下;或者是請求root許可權,這樣除了廠商能將自己的app安裝在/system/app 之下外,只能是需要請求root許可權了。
百度了一下,有解決辦法,但是說的不太清除,而且直接copy他們的代碼,運行後gps狀態也沒有改變。而且也沒有說明其原理。
其實除了使用 Settings.Secure.setLocationProviderEnabled 這個方法之外,還有一個方法就是使用系統內建的電量控制Widget來更改GPS的狀態。
具體代碼如下:
Intent intent = new Intent();
intent.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
intent.addCategory("android.intent.category.ALTERNATIVE");
intent.setData(Uri.parse("custom:3"));
context.sendBroadcast(intent);
這段代碼是什麼意思呢?其實就是通過intent將訊息發給com.android.settings.widget.SettingsAppWidgetProvider去處理,因為這個是系統內建的程式,所以他擁有root許可權。
那 Uri.parse("custom:3") 又是什麼意思呢,其實custom:3就是電量控制外掛程式上對應的各個按鈕,通過查看改代碼可以知道各個id的情況
private static final int BUTTON_BLUETOOTH = 4;
private static final int BUTTON_BRIGHTNESS = 1;
private static final int BUTTON_GPS = 3;
private static final int BUTTON_SYNC = 2;
private static final int BUTTON_WIFI = 0;
這樣就可以通過給 com.android.settings.widget.SettingsAppWidgetProvider 發送訊息實現更改GPS狀態了。同時,更改其他系統設設定的狀態也可以通過這個方法實現。
接下來控制WIFI的開關就很容易了,只要簡單調用一下代碼就可以實現了
WifiManager manager =null;
manager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
manager.setWifiEnabled(false);
manager.setWifiEnabled(true);
控制藍芽的開關
BluetoothAdapter bluetoothadapter = BluetoothAdapter.getDefaultAdapter();
bluetoothadapter.disable();
bluetoothadapter.enable();
控制飛航模式,Google沒有提供相關的api,但是我們可以通過intent廣播來實現
Intent intent;
Settings.System.putInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, enabled ? 1 : 0);
intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.putExtra("state", enabled);
context.sendBroadcast(intent);
這樣,我們就完成了情景模式中控制GPS/WIFI/藍芽/飛航模式 的功能。
在上面一篇文章中 http://www.cnblogs.com/wii/archive/2012/03/18/2404947.html
我們已經可以控制GPS/WIFI/藍芽/飛航模式了,現在
我們再來控制系統的音量和震動。
sdk提供了一個類來控制系統音量和震動的更改api,android.media.AudioManager 通過這個類,我們
將手機設定為靜音或者震動,和更改震動的類型。AudioManager無法在代碼中執行個體化,需要通過Context.getSystemService(Context.AUDIO_SERVICE)擷取到其執行個體。ok,擷取到AudioManager執行個體後,我們可以通過調用AudioManager的方法setRingerMode來控制聲音的類型。setRingerMode方法接受一個參數,我們只要根據需要更改的類型值傳入就可以拉。這3個分別是:
public static final int RINGER_MODE_SILENT = 0;
public static final int RINGER_MODE_VIBRATE = 1;
public static final int RINGER_MODE_NORMAL = 2;
醬紫,我們就可以通過以下代碼將聲音更改為 靜音了。
audio = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
audio.setRingerMode(AudioManager.RINGER_MODE_SILENT);
設定為靜音後在變成普通狀態可以通過調用一下代碼:
audio.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
audio.setStreamVolume(AudioManager.RINGER_MODE_NORMAL, ringerVolume, 0);
其中第二個參數就是鈴音的音量。
OK,控制了聲音後,我們接下來控制震動吧。
對于振動,系統有幾種類型,分別是 始終,一律不,僅在靜音下來電振和僅在非靜音下來電振 4種。
對于振動的控制,也是功過AudioManager的執行個體來完成的,通過調用setVibrateSetting方法來實現設定手機震動。
對於setVibrateSetting方法,需要傳入2個參數,第一個是震動的類型,分別是 VIBRATE_TYPE_NOTIFICATION 和 VIBRATE_TYPE_RINGER。
第二個是震動類型分比是 VIBRATE_SETTING_ON,VIBRATE_SETTING_OFF,VIBRATE_SETTING_ONLY_SILENT,VIBRATE_SETTING_ON,
根據參數的名稱我們都知道具體的作用拉,我就不作解釋了。
接下來我們就實現系統裡面提供的幾種震動類型吧
int vibrate_setting = -1;
int ring_mode = -1;
switch(profile.vibrate) {
case ProfileConstants.VIBRATE_ALWAYS_ON:// 總是震動
vibrate_setting = AudioManager.VIBRATE_SETTING_ON;
ring_mode = 1;
break;
case ProfileConstants.VIBRATE_NEVER://重不震動
vibrate_setting = AudioManager.VIBRATE_SETTING_OFF;
ring_mode = 0;
break;
case ProfileConstants.VIBRATE_ONLY_IN_SILENT://靜音下震動
vibrate_setting = AudioManager.VIBRATE_SETTING_ONLY_SILENT;
ring_mode = 1;
break;
case ProfileConstants.VIBRATE_UNLESS_SILENT://非靜音下震動
vibrate_setting = AudioManager.VIBRATE_SETTING_ON;
ring_mode = 0;
break;
}
Settings.System.putInt(resolver, "vibrate_in_silent", ring_mode);
audio.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, vibrate_setting);