1.简介:
在进行Android应用程序开发时,经常需要打开或关闭GPS。 在Android 设置中,可以手动进行这样的操作。那么,如何通过代码来实现呢,本篇将描述这样的方式。
2. GPS api接口:
Android SDK提供了打开或关闭GPS的接口,即:
android.provider.Settings.Secure类有2个静态方法:
public static final void setLocationProviderEnabled (ContentResolver cr, String provider, boolean enabled)
和
public static final boolean isLocationProviderEnabled (ContentResolver cr, String provider)
但是,这只在Android 2.2(从API Level 8)才开始提供。那么在2.2之前又该如何编程实现GPS的开关呢?
3. 通过反射SDK中隐藏的方法来获取:
3.1 分析SecuritySettings源码:
//com.android.settings.SecuritySettings.java
CheckBoxPreference localCheckBoxPreference3 = this.mGps;
if(paramPreference == localCheckBoxPreference3)
{
ContentResolver localContentResolver3 = getContentResolver();
boolean bool6 = this.mGps.isChecked();
Settings.Secure.setLocationProviderEnabled(localContentResolver3,"gps", bool6);
continue;
}
说明:
Settings.Secure.setLocationProviderEnabled是一个hide方法,不能被我们自己开发的应用程序之间调用,需要通过反射来调用。
3.2 setLocationProviderEnabled的源码:
public static final void setLocationProviderEnabled(ContentResolver cr,
String provider, boolean enabled) {
// to ensure thread safety, we write the provider name with a '+' or '-'
// and let the SettingsProvider handle it rather than reading and modifying
// the list of enabled providers.
if(enabled) {
provider = "+"+ provider;
}else{
provider = "-"+ provider;
}
putString(cr, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, provider);
}
3.3关键是要找到provider:使用SettingsAppWidgetProvider,源码如下:
private static PendingIntent getLaunchPendingIntent(Context paramContext, intparamInt1, intparamInt2)
{
Intent localIntent1 = newIntent();
Intent localIntent2 = localIntent1.setClass(paramContext, SettingsAppWidgetProvider.class);
Intent localIntent3 = localIntent1.addCategory("android.intent.category.ALTERNATIVE");
Uri localUri = Uri.parse("custom:"+ paramInt2);
Intent localIntent4 = localIntent1.setData(localUri);
returnPendingIntent.getBroadcast(paramContext, 0, localIntent1, 0);
}
说明:
通过PendingIntent来扔出1个Intent,接受者是 SettingsAppWidgetProvider.class,接受的参数有2个,1个是 Category:SettingsAppWidgetProvider.class(正是这个类自身),另1个是 Data:Uri.parse(“custom:” + paramInt2),这个paramInt2是Widget中的图标按钮的序号。
privatestatic final intBUTTON_BLUETOOTH = 4; privatestatic final intBUTTON_BRIGHTNESS = 1; privatestatic final intBUTTON_GPS = 3; privatestatic final intBUTTON_SYNC = 2; privatestatic final intBUTTON_WIFI = 0;
4.在App中的使用:
通过以上分析,那么我们只要送出custom:3的Uri给SettingsAppWidgetProvider.class,就应该可以由 SettingsAppWidgetProvider类来帮我们调用 Settings.Secure.setLocationProviderEnabled方法了。
4.1 打开或关闭GPS:
所以,在Activity中添加如下方法:
privatevoid toggleGPS() {
Intent gpsIntent = newIntent();
gpsIntent.setClassName("com.android.settings",
"com.android.settings.widget.SettingsAppWidgetProvider");
gpsIntent.addCategory("android.intent.category.ALTERNATIVE");
gpsIntent.setData(Uri.parse("custom:3"));
try{
PendingIntent.getBroadcast(this, 0, gpsIntent, 0).send();
}
catch(CanceledException e) {
e.printStackTrace();
}
}
说明:
函数功能更:用于开启或关闭GPS。如果当前是开启的,那么就会关闭它,反之亦然。
4.2:检查GPS状态:
secureClass = cl.loadClass("android.provider.Settings$Secure");
isMethod = secureClass.getMethod("isLocationProviderEnabled",
ContentResolver.class, String.class);
Boolean ret = (Boolean) isMethod.invoke(secureClass, this
.getContentResolver(),"gps");
或:
private void isGPSEnable() {
/* 用Setting.System来读取也可以,只是这是更旧的用法
String str = Settings.System.getString(getContentResolver(),
Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
*/
String str = Settings.Secure.getString(getContentResolver(),
Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
Log.v("GPS", str);
if(str != null) {
returnstr.contains("gps");
}
else{
returnfalse;
}
}