如何将位置模式改变为“高精度/电池节省”形成默认模式(仅限设备) [英] how to change the location mode to "high accuracy/battery saving" form it default mode(device only)

查看:619
本文介绍了如何将位置模式改变为“高精度/电池节省”形成默认模式(仅限设备)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用本教程来实现Google地图以获取当前位置

android谷歌地图教程
$ b

问题是,它没有得到我目前的位置,直到我已经开始我的设备的谷歌地图,并授予访问谷歌位置服务的权限。
在此之后,我的应用程序也获得我的当前位置。它的工作状况良好,直到设备上的位置。
当位置关闭时,它又需要启动设备的Google地图并授予Google位置服务的许可权。



我已根据说明生成密钥。



我发现设备位置模式存在问题。当我将设备模式手动更改为高精度/电池节电时,它工作正常。



因此,如何将位置模式更改为高精度/节省电量,以编程方式将其设置为默认模式(仅限设备)



以下是Activity代码:

  public class MapsActivity扩展FragmentActivity实现的OnMapReadyCallback,
GoogleApiClient .ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {

private GoogleMap mMap;
GoogleApiClient mGoogleApiClient;
位置mLastLocation;
标记mCurrLocationMarker;
LocationRequest mLocationRequest;

@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);

if(Build.VERSION.SDK_INT> = Build.VERSION_CODES.M){
checkLocationPermission();
}
//获取SupportMapFragment并在地图准备好使用时得到通知。
SupportMapFragment mapFragment =(SupportMapFragment)getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}


/ **
*操作一次可用的地图。
*当地图准备好使用时,会触发此回调。
*这是我们可以添加标记或线条,添加听众或移动相机的位置。在这种情况下,
*我们只在澳大利亚悉尼附近添加一个标记。
*如果设备上未安装Google Play服务,系统会提示用户在SupportMapFragment中安装
* it。只有当用户安装了
* Google Play服务并返回到应用时,才会触发此方法。
* /
@Override
public void onMapReady(GoogleMap googleMap){
mMap = googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

//初始化Google Play服务
if(Build.VERSION.SDK_INT> = Build.VERSION_CODES.M){
if(ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED){
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);



protected synchronized buildGoogleApiClient(){
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();


@Override
public void onConnected(Bundle bundle){

mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if(ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED){
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest,this);
}

}

@Override
public void onConnectionSuspended(int i){

}

@Override
public void onLocationChanged(位置位置){

mLastLocation = location;
if(mCurrLocationMarker!= null){
mCurrLocationMarker.remove();
}

//放置当前位置标记
LatLng latLng = new LatLng(location.getLatitude(),location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title(当前位置);
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mMap.addMarker(markerOptions);

//移动地图相机
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));

//停止位置更新
if(mGoogleApiClient!= null){
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,this);
}

}

@Override
public void onConnectionFailed(ConnectionResult connectionResult){

}

public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
public boolean checkLocationPermission(){
if(ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED){

//询问用户是否需要解释
if(ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)){

//向用户显示解释*异步* - 不要阻止
//此线程正在等待用户的响应!在用户
//看到解释后,再次尝试请求权限。

//一旦显示解释提示用户
ActivityCompat.requestPermissions(this,
new String [] {Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION) ;


}其他{
//不需要解释,我们可以申请许可。
ActivityCompat.requestPermissions(this,
new String [] {Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
返回false;
} else {
return true;
}
}

@Override
public void onRequestPermissionsResult(int requestCode,
String permissions [],int [] grantResults){
switch(requestCode){
case MY_PERMISSIONS_REQUEST_LOCATION:{
//如果请求被取消,结果数组是空的。
if(grantResults.length> 0
&&& amp; grantResults [0] == PackageManager.PERMISSION_GRANTED){

//授予权限。做你需要做的
//联系人相关的任务。
if(ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED){

if(mGoogleApiClient == null){
buildGoogleApiClient();
}
mMap.setMyLocationEnabled(true);
}

}其他{

// Permission denied,禁用取决于此权限的功能。
Toast.makeText(this,permission denied,Toast.LENGTH_LONG).show();
}
return;
}

//其他'case'行来检​​查此应用可能请求的其他权限。
//您可以根据您的要求在此添加其他案例陈述。
}
}
}

这里是清单文件代码:

 <?xml version =1.0encoding =utf-8?> 
< manifest xmlns:android =http://schemas.android.com/apk/res/android
package =com.example.googlemap>

<使用权限android:name =android.permission.INTERNET/>
< uses-permission android:name =android.permission.ACCESS_NETWORK_STATE/>
< uses-permission android:name =android.permission.WRITE_EXTERNAL_STORAGE/>
<使用权限android:name =com.google.android.providers.gsf.permission.READ_GSERVICES/>
< uses-permission android:name =android.permission.ACCESS_FINE_LOCATION/>


< permission
android:name =com.example.envent_pc03.googlemap.permission.MAPS_RECEIVE
android:protectionLevel =signature/>
<使用权限android:name =com.example.googlemap.permission.MAPS_RECEIVE/>
< uses-feature android:name =android.hardware.location.gps/>

< uses-feature
android:glEsVersion =0x00020000
android:required =true/>
<! -
使用
Google地图Android API v2时不需要ACCESS_COARSE / FINE_LOCATION权限,但您必须指定粗略或精细的
位置权限作为' MyLocation'功能。
- >
<! - <使用权限android:name =android.permission.ACCESS_FINE_LOCATION/> - >
<! - <使用权限android:name =android.permission.ACCESS_NETWORK_STATE/> - >
<! - <使用权限android:name =android.permission.INTERNET/> - >
<! - <使用权限android:name =com.google.android.providers.gsf.permission.READ_GSERVICES/> - >
<! -
使用
Google地图Android API v2时不需要ACCESS_COARSE / FINE_LOCATION权限,但您必须指定粗略或精细的
位置权限作为' MyLocation'功能。
- >
<! - <使用权限android:name =android.permission.ACCESS_COARSE_LOCATION/> - >
<! - <使用权限android:name =android.permission.ACCESS_FINE_LOCATION/> - >

< application
android:allowBackup =true
android:icon =@ mipmap / ic_launcher
android:label =@ string / app_name
android:supportsRtl =true
android:theme =@ style / AppTheme>

<! - -
Google Maps API API键被定义为字符串资源。
(请参阅文件res / values / google_maps_api.xml)。
请注意,API密钥已链接到用于签署APK的加密密钥。
您需要为每个加密密钥使用不同的API密钥,包括用于
的发行密钥签署APK进行发布。
您可以在src / debug /和src / release /中定义调试和发布目标的键。
- >
< meta-data
android:name =com.google.android.geo.API_KEY
android:value =@ string / google_maps_key/>

< activity
android:name =。MapsActivity
android:label =@ string / title_activity_maps>
< intent-filter>

< category android:name =android.intent.category.LAUNCHER/>
< / intent-filter>
< / activity>
< / application>

< / manifest>


解决方案

在请求位置更新之前,您需要检查正确根据您的要求定位设置。



创建一个LocationSettingsRequest.Builder并添加应用程序将使用的所有LocationRequests:

  LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()。addLocationRequest(mLocationRequest); 

检查位置设置是否满足,使用

  PendingResult< LocationSettingsResult> result = 
LocationServices.SettingsApi.checkLocationSettings(mGoogleClient,builder.build());

当PendingResult返回时,客户端可以通过查看LocationSettingsResult的状态代码来检查位置设置对象。

  result.setResultCallback(new ResultCallback< LocationSettingsResult>(){
@Override
public void onResult(LocationSettingsResult result){
final Status status = result.getStatus();
final LocationSettingsStates = result.getLocationSettingsStates();
switch(status.getStatusCode()){
case LocationSettingsStatusCodes.SUCCESS:
//所有位置设置都满足客户端可以初始化位置
//在这里请求
...
break;
case LocationSettingsStatusCodes .RESOLUTION_REQUIRED:
//位置设置不满意,但可以通过显示用户
来修复//一个对话框。
try {
//通过调用startResolutionForResult(),
//显示对话框,并在onActivityResult()中检查结果。
status.startResolutionForResult(
MapsActivity.this,
REQUEST_CHECK_SETTINGS);
} catch(SendIntentException e){
//忽略错误。
}
break;
案例LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
//位置设置不满意。但是,我们无法修复
//设置,所以我们不会显示对话框。
...
break;
}
}
});

对话框的结果将通过onActivityResult(int,int,Intent)返回

  @Override 
protected void onActivityResult(int requestCode,int resultCode,Intent data){
final LocationSettingsStates states = LocationSettingsStates。 fromIntent(意向);
switch(requestCode){
case REQUEST_CHECK_SETTINGS:
switch(resultCode){
case Activity.RESULT_OK:
//所有必需的更改都已成功完成
...
break;
案例Activity.RESULT_CANCELED:
//用户被要求更改设置,但未选择
...
break;
默认值:
break;
}
break;


仅供参考,请阅读 SettingsApi 文件,它很好地解释了这个案例。



或者,您可以直接将用户重定向到位置设置页面。

  int locationMode =设置.Secure.getInt(activityUnderTest.getContentResolver(),Settings.Secure.LOCATION_MODE); 

检查 location_mode 以获取可能的返回值。

  if(locationMode == LOCATION_MODE_HIGH_ACCURACY){
//请求位置更新
} else {//将用户重定向到设置页面
startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}


I'm trying to implement a google map for getting current location using this tutorial

android google map tutorial

The problem is ,It is not getting my current location untill I have started my device's google map and grant permission to access google location services. After this my application also get my current location. And it's working fine untill location is on in the device. And when location is turned off it's again need to started device's google map and grant permission for google location services.

I have already generate the key according to instructions.

I'm found the problem in device location mode.when I'm changing device mode to high accuracy/battery saving manually, it works fine.

So how to change the location mode to "high accuracy/battery saving" form it default mode(device only) programmatically

Here is the Activity code:

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,
        LocationListener {

    private GoogleMap mMap;
    GoogleApiClient mGoogleApiClient;
    Location mLastLocation;
    Marker mCurrLocationMarker;
    LocationRequest mLocationRequest;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            checkLocationPermission();
        }
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }


    /**
     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

        //Initialize Google Play Services
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_FINE_LOCATION)
                    == PackageManager.PERMISSION_GRANTED) {
                buildGoogleApiClient();
                mMap.setMyLocationEnabled(true);
            }
        }
        else {
            buildGoogleApiClient();
            mMap.setMyLocationEnabled(true);
        }
    }

    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnected(Bundle bundle) {

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(1000);
        mLocationRequest.setFastestInterval(1000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onLocationChanged(Location location) {

        mLastLocation = location;
        if (mCurrLocationMarker != null) {
            mCurrLocationMarker.remove();
        }

        //Place current location marker
        LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(latLng);
        markerOptions.title("Current Position");
        markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
        mCurrLocationMarker = mMap.addMarker(markerOptions);

        //move map camera
        mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        mMap.animateCamera(CameraUpdateFactory.zoomTo(11));

        //stop location updates
        if (mGoogleApiClient != null) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

    public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
    public boolean checkLocationPermission(){
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {

            // Asking user if explanation is needed
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION)) {

                // Show an explanation to the user *asynchronously* -- don't block
                // this thread waiting for the user's response! After the user
                // sees the explanation, try again to request the permission.

                //Prompt the user once explanation has been shown
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        MY_PERMISSIONS_REQUEST_LOCATION);


            } else {
                // No explanation needed, we can request the permission.
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        MY_PERMISSIONS_REQUEST_LOCATION);
            }
            return false;
        } else {
            return true;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_LOCATION: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    // permission was granted. Do the
                    // contacts-related task you need to do.
                    if (ContextCompat.checkSelfPermission(this,
                            Manifest.permission.ACCESS_FINE_LOCATION)
                            == PackageManager.PERMISSION_GRANTED) {

                        if (mGoogleApiClient == null) {
                            buildGoogleApiClient();
                        }
                        mMap.setMyLocationEnabled(true);
                    }

                } else {

                    // Permission denied, Disable the functionality that depends on this permission.
                    Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
                }
                return;
            }

            // other 'case' lines to check for other permissions this app might request.
            // You can add here other case statements according to your requirement.
        }
    }
}

here is the manifest file code:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.googlemap">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />


    <permission
        android:name="com.example.envent_pc03.googlemap.permission.MAPS_RECEIVE"
        android:protectionLevel="signature" />
    <uses-permission android:name="com.example.googlemap.permission.MAPS_RECEIVE"/>
    <uses-feature android:name="android.hardware.location.gps" />

    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true"/>
    <!--
         The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
         Google Maps Android API v2, but you must specify either coarse or fine
         location permissions for the 'MyLocation' functionality. 
    -->
    <!--<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />-->
    <!--<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />-->
    <!--<uses-permission android:name="android.permission.INTERNET" />-->
    <!--<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />-->
    <!--
         The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
         Google Maps Android API v2, but you must specify either coarse or fine
         location permissions for the 'MyLocation' functionality.
    -->
    <!--<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>-->
    <!--<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />-->

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!--
             The API key for Google Maps-based APIs is defined as a string resource.
             (See the file "res/values/google_maps_api.xml").
             Note that the API key is linked to the encryption key used to sign the APK.
             You need a different API key for each encryption key, including the release key that is used to
             sign the APK for publishing.
             You can define the keys for the debug and release targets in src/debug/ and src/release/. 
        -->
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key" />

        <activity
            android:name=".MapsActivity"
            android:label="@string/title_activity_maps">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

解决方案

Before requesting location updates, you need to check for correct location settings as per your requirement.

Create a LocationSettingsRequest.Builder and add all of the LocationRequests that the app will be using:

 LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest);

Check whether location settings are satisfied, using

PendingResult<LocationSettingsResult> result =
         LocationServices.SettingsApi.checkLocationSettings(mGoogleClient, builder.build());

When the PendingResult returns, the client can check the location settings by looking at the status code from the LocationSettingsResult object.

 result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
     @Override
     public void onResult(LocationSettingsResult result) {
         final Status status = result.getStatus();
         final LocationSettingsStates = result.getLocationSettingsStates();
         switch (status.getStatusCode()) {
             case LocationSettingsStatusCodes.SUCCESS:
                 // All location settings are satisfied. The client can initialize location
                 // requests here.
                 ...
                 break;
             case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                 // Location settings are not satisfied. But could be fixed by showing the user
                 // a dialog.
                 try {
                     // Show the dialog by calling startResolutionForResult(),
                     // and check the result in onActivityResult().
                     status.startResolutionForResult(
                         MapsActivity.this,
                         REQUEST_CHECK_SETTINGS);
                 } catch (SendIntentException e) {
                     // Ignore the error.
                 }
                 break;
             case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                 // Location settings are not satisfied. However, we have no way to fix the
                 // settings so we won't show the dialog.
                 ...
                 break;
         }
     }
 });

The result of the dialog will be returned via onActivityResult(int, int, Intent)

 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
     final LocationSettingsStates states = LocationSettingsStates.fromIntent(intent);
     switch (requestCode) {
         case REQUEST_CHECK_SETTINGS:
             switch (resultCode) {
                 case Activity.RESULT_OK:
                     // All required changes were successfully made
                     ...
                     break;
                 case Activity.RESULT_CANCELED:
                     // The user was asked to change settings, but chose not to
                     ...
                     break;
                 default:
                     break;
             }
             break;
     }
 }

For reference, read SettingsApi document which explains the case very well.

Alternatively, you can directly redirect the user to location settings page.

int locationMode = Settings.Secure.getInt(activityUnderTest.getContentResolver(), Settings.Secure.LOCATION_MODE);

Check location_mode for possible return values.

if(locationMode == LOCATION_MODE_HIGH_ACCURACY) {
   //request location updates
} else { //redirect user to settings page
   startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}

这篇关于如何将位置模式改变为“高精度/电池节省”形成默认模式(仅限设备)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆