需求:GPS位置信息模式默认为“仅限设备”, 应客户的要求,默认为“高精确度”
修改:/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
- <string name="def_location_providers_allowed" translatable="false">gps</string>
+ <string name="def_location_providers_allowed" translatable="false">gps,network</string>
编译后烧录,发现没变化还是默认仅限设备(我的项目中有gms),追踪源码发现在SettingsHelper.java中被限制了。
源码路径:frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
...
} else if (Settings.Secure.LOCATION_PROVIDERS_ALLOWED.equals(name)) {
setGpsLocation(value);
return;
}
...
private void setGpsLocation(String value) {
UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
if (um.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION)) {
return;
}
final String GPS = LocationManager.GPS_PROVIDER;
boolean enabled =
GPS.equals(value) ||
value.startsWith(GPS + ",") ||
value.endsWith("," + GPS) ||
value.contains("," + GPS + ",");
Settings.Secure.setLocationProviderEnabled(
mContext.getContentResolver(), GPS, enabled);
}
可以看到,如果def_location_providers_allowed的值包含gps,就还是默认仅限设备,如果只设置为network,就默认关闭gps了。直接设置
final String NETWORK = LocationManager.NETWORK_PROVIDER;
Settings.Secure.setLocationProviderEnabled(
mContext.getContentResolver(), NETWORK, enabled);
会有google的弹窗提示,不符合我们的要求。
1.使用adb命令抓取弹窗所在的activity,得到com.google.android.location.network.ConfirmAlertActivity
2.根据activity名字,搜索log得到关键词content://com.google.settings/partner/network_location_opt_in
3.反编译GmsCore_arm.apk,从GmsCore_arm的源码中知道点击同意之后对network_location_opt_in的值做了操作,然后关闭弹窗。
adb查看activity
apktool反编译
修改:/package/apps/Launcher3/src/com/android/launcher3/launcher.java
// 在onCreate()方法中添加
mHandler.postDelayed(new Runnable() {
public void run() {
// 判断用户是否手动设置了定位模式
int mode = Settings.System.getInt(getContentResolver(), "location_mode_changed", 0); // 1 : has changed 0 : no change
// 去掉Improve location accuracy弹窗
ContentResolver localContentResolver = getContentResolver();
ContentValues localContentValues = new ContentValues();
localContentValues.put("name", "network_location_opt_in");
localContentValues.put("value", 1);
localContentResolver.insert(Uri.parse("content://com.google.settings/partner"), localContentValues);
if(mode == 0){ // user did not choose the location mode
Settings.Secure.setLocationProviderEnabled(localContentResolver, "network", true);
}
}
}, 10000); // 这里加延时是由于google的应用服务起来比较慢,起来之后会设置network_location_opt_in的值
修改:/package/apps/Launcher3/AndroidManifest.xml
<uses-permission android:name="com.google.android.providers.settings.permission.WRITE_GSETTINGS" />
修改:/package/apps/Launcher3/Android.mk
LOCAL_CERTIFICATE := platform
修改:/package/apps/Settings/src/com/android/settings/location/LocationMode.java
@Override
public void onRadioButtonClicked(RadioButtonPreference emiter) {
int mode = Settings.Secure.LOCATION_MODE_OFF;
if (emiter == mHighAccuracy) {
mode = Settings.Secure.LOCATION_MODE_HIGH_ACCURACY;
} else if (emiter == mBatterySaving) {
mode = Settings.Secure.LOCATION_MODE_BATTERY_SAVING;
} else if (emiter == mSensorsOnly) {
mode = Settings.Secure.LOCATION_MODE_SENSORS_ONLY;
}
+ Settings.System.putInt(getContentResolver(), "location_mode_changed", 1); // 1 : has changed 0 : no change
setLocationMode(mode);
}
可以在studio中编写,然后对apk做系统签名验证。
对apk系统签名.