
我问的是成功收到FINE和COARSE权限.然后构建Googleapiclient并创建LocationRequest,然后创建FusedLocationAPI.getLastLocation,它继续返回null.我知道在询问位置之前应该建立连接.因为在checkLocation()方法之后调用建立Connection的onStart(),所以在构建Googleapiclient后立即调用mLocationapiclient.connect().正在点击onConnected方法,当我检查mLocationapiclient.isConnected()时,它表示’true’.然后当我尝试使用FusedLocationAPI检索LastLocation时,它总是返回null.我感到困惑,因为我已多次检查并且有连接但没有检索到位置.我哪里错了?
主要活动:
@EActivity(R.layout.activity_main)public class MainActivity extends AppCompatActivity implements Googleapiclient.ConnectionCallbacks, Googleapiclient.OnConnectionFailedListener, LocationListener { private static final int MY_PERMISSION_REQUEST_CODE = 7171; private static final int PLAY_SERVICES_RESolUTION_REQUEST = 7172; private static int UPDATE_INTERVAL = 5000; // seconds private static int FATEST_INTERVAL = 3000; // seconds private static int disPLACEMENT = 10; // meters private LocationRequest mLocatiionRequest; private Googleapiclient mGoogleapiclient; private Location mLastLocation; @AfterVIEws voID retrIEveLocation() { int fineLocationPermission = checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION); int coarseLocationPermission = checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION); if (fineLocationPermission != PackageManager.PERMISSION_GRANTED && coarseLocationPermission != PackageManager.PERMISSION_GRANTED) { this.requestPermissions( new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, MY_PERMISSION_REQUEST_CODE ); } else { if (this.isPlayServiceAvailable()) { this.buildGoogleapiclient(); this.createLocationRequest(); this.mLastLocation = LocationServices.FusedLocationAPI.getLastLocation(this.mGoogleapiclient); String message = ""; if (this.mLastLocation != null) message = "Lat: " + this.mLastLocation.getLatitude() + ", Lon: " + this.mLastLocation.getLongitude(); else message = "DIDn't manage to get location."; Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show(); } }}@OverrIDepublic voID onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { case MY_PERMISSION_REQUEST_CODE: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (this.isPlayServiceAvailable()) this.buildGoogleapiclient(); } break; }}@OverrIDepublic voID onConnected(@Nullable Bundle bundle) { this.retrIEveLocation();}@OverrIDepublic voID onConnectionSuspended(int i) { this.mGoogleapiclient.connect();}@OverrIDepublic voID onConnectionFailed(@NonNull ConnectionResult connectionResult) {}@OverrIDepublic voID onLocationChanged(Location location) { this.mLastLocation = location;}@OverrIDeprotected voID onStart() { super.onStart(); if (this.mGoogleapiclient != null) this.mGoogleapiclient.connect();}@OverrIDeprotected voID onStop() { LocationServices.FusedLocationAPI.removeLocationUpdates(this.mGoogleapiclient, this); if (this.mGoogleapiclient != null) this.mGoogleapiclient.disconnect(); super.onStop();}private boolean isPlayServiceAvailable() { int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); if (resultCode != ConnectionResult.SUCCESS) { if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) { GooglePlayServicesUtil.getErrorDialog(resultCode, this, PLAY_SERVICES_RESolUTION_REQUEST).show(); } else { Toast.makeText(getApplicationContext(), "The device is not supported", Toast.LENGTH_LONG).show(); finish(); } return false; } return true;}private voID buildGoogleapiclient() { if (this.mGoogleapiclient == null) // avoID recreating clIEnt when it is already connected this.mGoogleapiclient = new Googleapiclient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addAPI(LocationServices.API) .build(); if (!this.mGoogleapiclient.isConnected()) // avoID unwanted hitting of onConnect callback this.mGoogleapiclient.connect();}private voID createLocationRequest() { this.mLocatiionRequest = new LocationRequest(); this.mLocatiionRequest.setInterval(this.UPDATE_INTERVAL); this.mLocatiionRequest.setFastestInterval(this.FATEST_INTERVAL); this.mLocatiionRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); this.mLocatiionRequest.setSmallestdisplacement(this.disPLACEMENT);}private voID startLocationUpdates() { int fineLocationPermission = checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION); int coarseLocationPermission = checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION); if (fineLocationPermission != PackageManager.PERMISSION_GRANTED && coarseLocationPermission != PackageManager.PERMISSION_GRANTED) { return; } LocationServices.FusedLocationAPI.requestLocationUpdates(this.mGoogleapiclient, this.mLocatiionRequest, this);}private voID stopLocationUpdates() { LocationServices.FusedLocationAPI.removeLocationUpdates(this.mGoogleapiclient, this);}}
Build.graddle:
apply plugin: 'com.androID.application'apply plugin: 'androID-apt'def AAVersion = '4.3.1'apt { arguments { androIDManifestfile variant.outputs[0]?.processResources?.manifestfile resourcePackagename 'com.mosy.kalin.mosy' }}androID { compileSdkVersion 26 buildToolsversion "26.0.0" defaultConfig { applicationID "mosy.mosyandroID" minSdkVersion 26 targetSdkVersion 26 versionCode 1 versionname "1.0" testInstrumentationRunner "androID.support.test.runner.AndroIDJUnitRunner" } buildTypes { release { MinifyEnabled false proguardfiles getDefaultProguardfile('proguard-androID.txt'), 'proguard-rules.pro' } }}dependencIEs { compile filetree(dir: 'libs', include: ['*.jar']) androIDTestCompile('com.androID.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.androID.support', module: 'support-annotations' }) apt "org.androIDannotations:androIDannotations:$AAVersion" compile "org.androIDannotations:androIDannotations-API:$AAVersion" compile 'com.androID.support:appcompat-v7:26.0.0-beta2' compile 'com.androID.support:design:26.+' compile 'com.androID.support.constraint:constraint-layout:1.0.2' compile 'com.androID.support:support-v4:26.0.0-beta2' compile 'com.squareup.okhttp3:okhttp:3.8.1' compile 'com.Google.androID.gms:play-services-location:11.0.4' testCompile 'junit:junit:4.12'}解决方法:
2 Reson为此
> getLastLocation()不总是给位置.您还必须编写位置更新
>在某些设备中,谷歌播放服务有时会无法连接
因此,为避免这种情况,您还必须从GPS获取位置,请考虑以下代码
在构建gradle中添加此依赖项
compile 'com.Google.androID.gms:play-services-location:10.2.1'compile 'cn.pedant.sweetalert:library:1.3'添加此类以获取位置 – LocationResolver.java
import androID.app.Activity;import androID.content.Context;import androID.content.Intent;import androID.content.IntentSender;import androID.content.pm.PackageManager;import androID.location.Location;import androID.location.LocationManager;import androID.net.ConnectivityManager;import androID.net.NetworkInfo;import androID.net.Uri;import androID.os.Build;import androID.os.Bundle;import androID.provIDer.Settings;import androID.support.v4.app.ActivityCompat;import androID.support.v4.content.ContextCompat;import androID.text.TextUtils;import androID.util.Log;import androID.Widget.Toast;import com.Google.androID.gms.common.ConnectionResult;import com.Google.androID.gms.common.API.Googleapiclient;import com.Google.androID.gms.location.LocationListener;import com.Google.androID.gms.location.LocationRequest;import com.Google.androID.gms.location.LocationServices;import com.Google.androID.gms.location.LocationSettingsRequest;import cn.pedant.SweetAlert.SweetAlertDialog;import static androID.content.Context.LOCATION_SERVICE;public class LocationResolver implements Googleapiclient.ConnectionCallbacks, Googleapiclient.OnConnectionFailedListener, LocationListener, androID.location.LocationListener { // The minimum distance to change Updates in meters private static final long MIN_disTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters // The minimum time between updates in milliseconds private static final long MIN_TIME_BW_UPDATES = 1000 * 60 ; // 1 minute //Location Request code private final int REQUEST_LOCATION = 2; //Google Api ClIEnt private Googleapiclient mGoogleapiclient; //Location request for Google fused location API private LocationRequest mLocationRequest; //Location manager for location services private LocationManager mLocationManager; private OnLocationResolved mOnLocationResolved; private Activity mActivity; //Location permission Dialog private SweetAlertDialog mDialog; public LocationResolver(Activity activity){ mActivity=activity; buildGoogleapiclient(); mLocationManager = (LocationManager) activity.getSystemService(LOCATION_SERVICE); createLocationRequest(); } public voID resolveLocation(Activity activity, OnLocationResolved onLocationResolved){ this.mOnLocationResolved = onLocationResolved; this.mActivity=activity; if (isEveryThingEnabled()){ startLocationPooling(); } } public interface OnLocationResolved{ voID onLocationResolved(Location location); } /* * Checking every criteria are enabled for getting location from device * */ public boolean isEveryThingEnabled() { if (!isLocationPermissionEnabled()) { showPermissionRequestDialog(); return false; } else if (!isLocationEnabled(mActivity)) { showLocationSettingsDialog(); return false; } else if (!isConnected()) { showWifiSettingsDialog(mActivity); return false; } return true; } /* * This function checks if location permissions are granted or not * */ public boolean isLocationPermissionEnabled() { return !(Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED); } /* * PrevIoUs location permissions were denIEd , this function opens app settings page * So user can enable permission manually * */ private voID startAppDetailsActivity() { final Intent i = new Intent(); i.setAction(Settings.ACTION_APPliCATION_DETAILS_SETTINGS); i.addcategory(Intent.category_DEFAulT); i.setData(Uri.parse("package:" + mActivity.getPackagename())); mActivity.startActivity(i); } private voID showLocationSettingsDialog() { SweetAlertDialog builder = new SweetAlertDialog(mActivity, SweetAlertDialog.WARNING_TYPE); builder.setTitleText("Need Location"); builder.setContentText("In order for the app to work seamlessly.Please enable Location Service."); builder.setConfirmText("Enable"); builder.setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() { @OverrIDe public voID onClick(SweetAlertDialog dialog) { dialog.cancel(); startLocationSettings(); } }); builder.setCancelText("Cancel"); builder.setCancelClickListener(new SweetAlertDialog.OnSweetClickListener() { @OverrIDe public voID onClick(SweetAlertDialog dialog) { dialog.cancel(); } }); builder.show(); } private voID startLocationSettings() { mActivity.startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)); } /* * location permissions were denIEd with "do not show" unchecked.. this function shows a dialog describing why this app * need location permission. * */ private voID showPermissionRequestDialog() { if (mDialog != null) mDialog.cancel(); mDialog = new SweetAlertDialog(mActivity, SweetAlertDialog.norMAL_TYPE); mDialog.setTitleText("You need location permission"); mDialog.setContentText("Enable location permission"); mDialog.setConfirmText("grant"); mDialog.setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() { @OverrIDe public voID onClick(SweetAlertDialog dialog) { dialog.cancel(); ActivityCompat.requestPermissions(mActivity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION); } }); mDialog.setCancelText("Cancel"); mDialog.setCancelClickListener(new SweetAlertDialog.OnSweetClickListener() { @OverrIDe public voID onClick(SweetAlertDialog dialog) { dialog.cancel(); } }); mDialog.show(); } /* * * * PrevIoUsly Permission Request was cancelled with 'Dont Ask Again', * Redirect to Settings after showing information about why you need the permission * * */ private voID showPermissionDenIEdDialog() { if (mDialog != null) mDialog.cancel(); mDialog = new SweetAlertDialog(mActivity, SweetAlertDialog.norMAL_TYPE); mDialog.setTitleText("Need Location Permission"); mDialog.setContentText("Enable location permission"); mDialog.setConfirmText("grant"); mDialog.setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() { @OverrIDe public voID onClick(SweetAlertDialog dialog) { dialog.cancel(); startAppDetailsActivity(); } }); mDialog.setCancelText("Cancel"); mDialog.setCancelClickListener(new SweetAlertDialog.OnSweetClickListener() { @OverrIDe public voID onClick(SweetAlertDialog dialog) { dialog.cancel(); } }); mDialog.show(); } public voID onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case REQUEST_LOCATION: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { startLocationPooling(); } else { if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) && ActivityCompat.shouldShowRequestPermissionRationale(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION)) { showPermissionRequestDialog(); } else { showPermissionDenIEdDialog(); } } } } } /* * Starting location pooling * */ public voID startLocationPooling() { if (ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // // 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; } Location location = LocationServices.FusedLocationAPI.getLastLocation( mGoogleapiclient); if (location != null) { mOnLocationResolved.onLocationResolved(location); } else { if (mGoogleapiclient.isConnected())//if GoogleClIEnt can get location from device the go for location update startLocationUpdates(); else getLocation(); //Google ClIEnt cannot connected to its server. so we are fetching location directly from device } } private synchronized voID buildGoogleapiclient() { mGoogleapiclient = new Googleapiclient.Builder(mActivity) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addAPI(LocationServices.API) .build(); } public voID onDestroy() { mGoogleapiclient.disconnect(); } public voID onStop() { if (mDialog != null) { mDialog.cancel(); } stopLocationUpdates(); mGoogleapiclient.disconnect(); } public voID onStart() { mGoogleapiclient.connect(); } @OverrIDe public voID onConnected(Bundle bundle) { // startLocationPooling(); } /* * checks whether the device connected or not*/ public boolean isConnected() { try { ConnectivityManager cm = (ConnectivityManager) mActivity.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = cm.getActiveNetworkInfo(); return netInfo != null && netInfo.isConnected(); } catch (Exception e) { return false; } } @OverrIDe public voID onConnectionSuspended(int i) { mGoogleapiclient.connect(); } @OverrIDe public voID onLocationChanged(Location location) { if (location != null) { mOnLocationResolved.onLocationResolved(location); stopLocationUpdates(); } } @OverrIDe public voID onStatusChanged(String s, int i, Bundle bundle) { } @OverrIDe public voID onProvIDerEnabled(String s) { } @OverrIDe public voID onProvIDerDisabled(String s) { } @OverrIDe public voID onConnectionFailed(ConnectionResult connectionResult) { if (connectionResult.hasResolution()) { try { // Start an Activity that trIEs to resolve the error connectionResult.startResolutionForResult(mActivity, ConnectionResult.RESolUTION_required); } catch (IntentSender.SendIntentException e) { e.printstacktrace(); } } else { Log.e("TAG", "Location services connection Failed with code==>" + connectionResult.getErrorCode()); Log.e("TAG", "Location services connection Failed Because of==> " + connectionResult.getErrorMessage()); } } private voID createLocationRequest() { Log.i("TAG", "CreateLocationRequest"); mLocationRequest = new LocationRequest(); long UPDATE_INTERVAL = 10 * 1000; mLocationRequest.setInterval(UPDATE_INTERVAL); long FASTEST_INTERVAL = 10000; mLocationRequest.setFastestInterval(FASTEST_INTERVAL); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder() .addLocationRequest(mLocationRequest); //************************** builder.setAlwaysShow(true); //this is the key ingredIEnt //************************** } private voID startLocationUpdates() { Log.i("TAG", "StartLocationUpdates"); if (Build.VERSION.SDK_INT >= 23) { if (ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) { // Todo: ConsIDer calling LocationServices.FusedLocationAPI.requestLocationUpdates(mGoogleapiclient, mLocationRequest, this); } } else { LocationServices.FusedLocationAPI.requestLocationUpdates(mGoogleapiclient, mLocationRequest, this); } } private voID stopLocationUpdates() { try { if (mGoogleapiclient.isConnected()) LocationServices.FusedLocationAPI.removeLocationUpdates(mGoogleapiclient, this); if (mLocationManager != null) { mLocationManager.removeUpdates(this); } } catch (Exception e) { e.printstacktrace(); } } public voID getLocation() { try { // getting GPS status Boolean isGPSEnabled = mLocationManager .isProvIDerEnabled(LocationManager.GPS_PROVIDER); // getting network status Boolean isNetworkEnabled = mLocationManager .isProvIDerEnabled(LocationManager.NETWORK_PROVIDER); if (!isGPSEnabled && !isNetworkEnabled) { Log.e("Location", "No provIDer enabled"); } else { if (ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mActivity, 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; } Location location = null; // First get location from Network ProvIDer if (isNetworkEnabled) { if (mLocationManager != null) { location = mLocationManager .getLastKNownLocation(LocationManager.NETWORK_PROVIDER); if (location != null) { mOnLocationResolved.onLocationResolved(location); } else { mLocationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_disTANCE_CHANGE_FOR_UPDATES, this); Log.d("Network", "Network"); } } } // if GPS Enabled get lat/long using GPS Services if (isGPSEnabled) { if (location == null) { if (mLocationManager != null) { location = mLocationManager .getLastKNownLocation(LocationManager.GPS_PROVIDER); if (location != null) { mOnLocationResolved.onLocationResolved(location); } else { mLocationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_disTANCE_CHANGE_FOR_UPDATES, this); Log.d("GPS Enabled", "GPS Enabled"); } } } } } } catch (Exception e) { e.printstacktrace(); } } /* * checks whether the device connected or not*/ public static boolean isNetWorkConnected(Context context) { try { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = cm.getActiveNetworkInfo(); return netInfo != null && netInfo.isConnected(); } catch (Exception e) { return false; } } public voID showWifiSettingsDialog(final Context context) { SweetAlertDialog builder = new SweetAlertDialog(context, SweetAlertDialog.WARNING_TYPE); builder.setTitleText("Need Internet"); builder.setContentText("Please enable your internet connection"); builder.setConfirmText("Enable"); builder.setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() { @OverrIDe public voID onClick(SweetAlertDialog dialog) { dialog.cancel(); startWifiSettings(context); } }); builder.setCancelText("Cancel"); builder.setCancelClickListener(new SweetAlertDialog.OnSweetClickListener() { @OverrIDe public voID onClick(SweetAlertDialog dialog) { dialog.cancel(); } }); builder.show(); } private voID startWifiSettings(Context context) { try { context.startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS)); } catch (Exception e) { Toast.makeText(context, "Something went wrong", Toast.LENGTH_SHORT).show(); } } public static boolean isLocationEnabled(Context context) { int locationMode = 0; String locationProvIDers; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { try { locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE); } catch (Settings.SettingNotFoundException e) { e.printstacktrace(); return false; } return locationMode != Settings.Secure.LOCATION_MODE_OFF; } else { locationProvIDers = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED); return !TextUtils.isEmpty(locationProvIDers); } }}在您的活动中,请遵循以下步骤
创建并初始化LocationResolver变量
private LocationResolver mLocationResolver;@OverrIDeprotected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_main);mLocationResolver=new LocationResolver(this);}并将这些行添加到您的活动中
@OverrIDeprotected voID onStart() { super.onStart(); mLocationResolver.onStart();}@OverrIDeprotected voID onStop() { super.onStop(); mLocationResolver.onStop();}@OverrIDeprotected voID onDestroy() { super.onDestroy(); mLocationResolver.onDestroy();}@OverrIDepublic voID onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); mLocationResolver.onRequestPermissionsResult(requestCode, permissions, grantResults);}用法:当您想要位置时,使用此代码获取位置
voID retrIEveLocation() { mLocationResolver.resolveLocation(this, new LocationResolver.OnLocationResolved() { @OverrIDe public voID onLocationResolved(Location location) { // Do what ever you want } }); } 总结 以上是内存溢出为你收集整理的android – FusedLocationApi.getLastLocation始终为null,即使是onCreated()全部内容,希望文章能够帮你解决android – FusedLocationApi.getLastLocation始终为null,即使是onCreated()所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)