【Android】位置修改相关

获取位置服务总开关状态

//获取LOCATION_MODE值,但adb状态下无法获取
//0为关闭,1 gps、2 network、3 高精度等
int state = Settings.Secure.getInt(mContext.getContentResolver(),Settings.Secure.LOCATION_MODE,Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
//获取location_providers_allowed,adb状态下可以读取
String s = Settings.Secure.getString(mContext.getContentResolver(),"location_providers_allowed");

实现

Android5-8

修改Settings.Secure+发送广播

private void setLocationEnabled(Context context, int mode){
    int oldMode = Settings.Secure.getInt(context.getContentResolver(),
            Settings.Secure.LOCATION_MODE,
            Settings.Secure.LOCATION_MODE_OFF);
    updateLocationMode(context, oldMode, mode);
}

private boolean updateLocationMode(Context context, int oldMode, int newMode) {
    Intent intent = new Intent("com.android.settings.location.MODE_CHANGING");
    intent.putExtra("CURRENT_MODE", oldMode);
    intent.putExtra("NEW_MODE", newMode);
    context.sendBroadcast(intent, android.Manifest.permission.WRITE_SECURE_SETTINGS);
    return Settings.Secure.putInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE, newMode);
}

Android9

@RequiresApi(api = Build.VERSION_CODES.P)
public static void setProviderEnabledForUser(Context context, String provider, boolean enabled){
    LocationManager locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
    try{
        Field field = UserHandle.class.getDeclaredField("SYSTEM");
        field.setAccessible(true);
        UserHandle userHandle = (UserHandle) field.get(UserHandle.class);
        Method method = LocationManager.class.getDeclaredMethod(
                    "setProviderEnabledForUser",
                    String.class,
                    boolean.class,
                    serHandle.class);
        method.invoke(locationManager, provider, enabled, userHandle);
    }catch(Exception e){
        Log.e(TAG, "can not setProviderEnabledForUser:(" + provider +"," + enabled +")");
    }
}

Android10以上

@RequiresApi(api = Build.VERSION_CODES.Q)
public static void setLocationEnabledForUser(Context context, boolean enabled){
    LocationManager locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
    try{
        Field field = UserHandle.class.getDeclaredField("SYSTEM");
        field.setAccessible(true);
        UserHandle userHandle = (UserHandle) field.get(UserHandle.class);
        Method method = LocationManager.class.getDeclaredMethod(
                    "setLocationEnabledForUser",
                    boolean.class,
                    UserHandle.class);
        method.invoke(locationManager, enabled, userHandle);
    }catch(Exception e){
        Log.e(TAG, "can not setLocationEnabledForUser:(" + enabled +")");
    }
}

实例

关闭位置信息总开关:
在这里插入图片描述

public class LocationUtil {

    private static void updateLocationMode(Context context, int oldMode, int newMode) {
        Intent intent = new Intent("com.android.settings.location.MODE_CHANGING");
        intent.putExtra("CURRENT_MODE", oldMode);
        intent.putExtra("NEW_MODE", newMode);
        context.sendBroadcast(intent, android.Manifest.permission.WRITE_SECURE_SETTINGS);
        Settings.Secure.putInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE, newMode);
    }

    /**
     * Settings.Secure.LOCATION_MODE_OFF // 关闭
     * Settings.Secure.LOCATION_MODE_SENSORS_ONLY // GPS only
     * Settings.Secure.LOCATION_MODE_BATTERY_SAVING // 降低GPS上报频率
     * Settings.Secure.LOCATION_MODE_HIGH_ACCURACY // 高精度
     */
    public static void setLocationEnabled(Context context, int mode){
        int oldMode = Settings.Secure.getInt(context.getContentResolver(),
                Settings.Secure.LOCATION_MODE,
                Settings.Secure.LOCATION_MODE_OFF);
        updateLocationMode(context, oldMode, mode);
    }
}

定位默认高精度

Android8.1版本

1.修改xml文件

地址:\SettingsProvider\res\values

<string name="def_location_providers_allowed" translatable="false">gps,network</string>

该种方法只针对于国内系统有效
注:当手动切换到低耗电模式时,重启后会自动开启高精度
当修改含有GMS的海外系统时,单纯修改xml字符串无效,会出现:
1).重启后生效
2).进安卓设置页面后恢复
3).恢复出厂设置后重置
排查原因
由于是海外系统,有gms
手动点进设置中切换时会有弹窗提示,所以需要在开机之后通过代码进行修改
应用需要满足:
1).系统应用
2).gms开机启动慢,所以选择在接收到开机广播后进行处理,在AndroidMainfest.xml中声明权限

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

网上查到都是在Launcher的onCreate进行延迟处理,但客户需求不打包UI,而且还要考虑到主题切换等操作,所以在对应的系统应用中添加,用广播处理是一样的。

2.修改java文件

adb获取为null,即用户没有手动更改过定位模式

adb shell settings get system location_mode_changed

注:需要手动切换后再次获取,看看该属性值是否有变化
若无变化,可参考文章:android 默认打开高精度定位模式,accept Improve location accuracy
在Android8.1中,LocationMode.java中有将location_mode_changed属性值进行改变,以达到判断用户手动设置

在开机广播进行处理

// 判断用户是否手动设置了定位模式
int mode = Settings.System.getInt(getContentResolver(), "location_mode_changed", 0); 

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){
    Settings.Secure.setLocationProviderEnabled(localContentResolver, "network", true);
}
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值