Fused Location Provider仅适用于某些手机

时间:2016-09-29 23:25:07

标签: android android-6.0-marshmallow android-permissions fusedlocationproviderapi

更新1:我发现代码确实有效,但它并未要求获得使用您位置的权限。如果您转到应用程序权限并手动授予其位置访问权限,则可以正常运行。我仍然不知道如何让它在运行时询问位置权限。

我正在学习融合位置提供程序并制作了一个只显示lat和long的应用程序。我使用的是我的LG G4和6.0并遵循这个伟大的YouTube Tutorial,但是当我在手机上运行它时,它只显示纬度和长文本而不是gps坐标。我在Motorolla X 2015和Moto Droid Turbo上进行了测试,它可以工作。

编译SDK版本:7.0
Gradle版本:2.14.1
Android插件版本:2.2.0
构建工具版本:24.0.2

清单:

<?xml version = "1.0" encoding = "utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.nathan.gpstest">
    <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">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

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

Gradle Dependancies:

dependencies {
  compile fileTree(include: ['*.jar'], dir: 'libs')
  androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
    exclude group: 'com.android.support', module: 'support-annotations'
  })
  compile 'com.android.support:appcompat-v7:24.2.1'
  testCompile 'junit:junit:4.12'
    //compile 'com.google.android.gms:play-services:9.6.1'
  compile 'com.google.android.gms:play-services-location:9.6.1'
}

MainActivity:

package com.example.nathan.gpstest;

import android.content.pm.PackageManager;
import android.location.Location;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.FusedLocationProviderApi;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {

  TextView latitudeText;
  TextView longitudeText;
  private FusedLocationProviderApi locationProvider = LocationServices.FusedLocationApi;
  private GoogleApiClient googleApiClient;
  private LocationRequest locationRequest;
  private double myLatitude;
  private double mylongitude;

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

    latitudeText = (TextView) findViewById(R.id.tvLatitude);
    longitudeText = (TextView) findViewById(R.id.tvLongitude);


    googleApiClient = new GoogleApiClient.Builder(this)
      .addApi(LocationServices.API)
      .addConnectionCallbacks(this)
      .addOnConnectionFailedListener(this)
      .build();

    locationRequest = new LocationRequest();
    locationRequest.setInterval(10 * 1000);
    locationRequest.setFastestInterval(15 * 1000);
    locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
  }

  @Override
  public void onConnected(Bundle bundle) {
    requestLocationUpdates();
  }

  private void requestLocationUpdates() {
    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
      // TODO: Consider calling
      //    ActivityCompat#requestPermissions
      // here to request the missing permissions, and then overriding
      //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
      //                                          int[] grantResults)
      // to handle the case where the user grants the permission. See the documentation
      // for ActivityCompat#requestPermissions for more details.
      return;
    }
    LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
  }

  @Override
  public void onConnectionSuspended(int i) {
    latitudeText.setText("Connection Suspended");
  }

  @Override
  public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    latitudeText.setText("Connection Failed");

  }

  @Override
  public void onLocationChanged(Location location) {
    myLatitude = location.getLatitude();
    mylongitude = location.getLongitude();

    latitudeText.setText("Latitude : " + String.valueOf(myLatitude));
    //latitudeText.setText("Latitude : " + String.valueOf(myLatitude));
    longitudeText.setText("Longitude : " + String.valueOf(mylongitude));
  }

  @Override
  protected void onStart() {
    super.onStart();
    googleApiClient.connect();
  }

  @Override
  protected void onResume() {
    super.onResume();
    if (googleApiClient.isConnected()) {
      requestLocationUpdates();
    }
  }

  @Override
  protected void onPause() {
    super.onPause();
    LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
  }

  @Override
  protected void onStop() {
    super.onStop();
    googleApiClient.disconnect();
  }
}

1 个答案:

答案 0 :(得分:0)

这可能与您的代码尚未处理的Android M中的新运行时权限有关,我之前有一个这样的案例,我的应用程序将在我的大多数设备中运行,但安装在新手机上时(使用Android 6.0+)它会崩溃。

原因是在运行时没有使用显式权限请求

你可以尝试以下方法:

        int currentapiVersion = android.os.Build.VERSION.SDK_INT;

        int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);

        Bundle tmpSavedInstanceState = savedInstanceState;


        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_FINE_LOCATION)) {

            // Show an expanation 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.

            Toast.makeText(this, "Please accept the permission so you can use the location services", Toast.LENGTH_LONG).show();
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERM_REQUEST);

        } else {

            // No explanation needed, we can request the permission.

            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERM_REQUEST);

            // MY_PERM_REQUEST is an
            // app-defined int constant. The callback method gets the
            // result of the request.
        }



        if (permissionCheck == PackageManager.PERMISSION_GRANTED || currentapiVersion <= Build.VERSION_CODES.M) {
            //Execute location service call if user has explicitly granted ACCESS_FINE_LOCATION..
            // use location services 
        }

异步权限&#39;请求将返回调用此回调:

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


                    //do whatever you want with your location API
                    // everything went well, use the location services


                } else {

                    // permission denied. Disable the
                    // functionality that depends on this permission.
                }
                return;
            }

            // other 'case' lines to check for other
            // permissions this app might request
        }
    } 

您还可以查看@Blackkara提到的documentation

请告诉我这是否有帮助=)