1

我有一个应用程序,它可以获取用户当前的位置,然后加载Google地图并在他们的区域绘制感兴趣的标记。它完美地运行在棉花糖下的一切。我已经添加了运行时权限检查,并且他们正在设置,因为我会得到提示,并且在我接受后,我会在手机设置中看到应用程序详细信息中列出的权限。然而,我不能为了我的生活找出为什么我没有找回位置。Android Marshmallow getLast位置/地点不适用的歌曲

我使用的例子如下https://developer.android.com/training/location/retrieve-current.html

看到我与清单中的标签设置的所有权限。我甚至有我的片段实现LocationListener。但是,onLocationChanged方法永远不会被调用。我像下面的谷歌API客户端的onConnected方法中调用它..

@Override 
    public void onConnected(@Nullable Bundle bundle) { 
     try { 
      Log.d("MYAPPTAG","isConnected: " + mGoogleApiClient.isConnected()); 
      LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
      myLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
     } catch (SecurityException ex) { 
      myLocation = null; 
     } 
    } 

的onConnected方法不会被调用,因为我让我登录到控制台。但myLocation始终为空。我在控制台中每次的消息我称之为getLastLocation,说

No Location to return for getLastLocation() 
GoogleSignatureVerifier: com.myappname.android signature not valid. Found: LONG KEY HERE 

是不是有什么特别的,我需要在棉花糖做什么?

我OnLocationChanged方法

@Override 
    public void onLocationChanged(Location location) { 
     myLocation = location; 
     Log.d("MYAPPTAG", "LocatinChngListner, loc: " + location.getLatitude() + "," + location.getLongitude());  
    } 

的AndroidManifest.xml - 权限部分(上文节点)

<!--- App permissions --> 
    <permission android:name="com.myappname.android.permission.MAPS_RECEIVE" android:protectionLevel="signature"/> 
    <uses-permission android:name="com.myappname.android.permission.MAPS_RECEIVE"/> 
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> 
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/> 
    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.GET_ACCOUNTS"/> 
    <uses-permission android:name="android.permission.CALL_PHONE"/> 
    <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" /> 
    <uses-permission android:name="android.permission.WRITE_CONTACTS" /> 
    <uses-permission android:name="android.permission.WAKE_LOCK" /> 
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> 

    <permission android:name="com.myappname.android.permission.C2D_MESSAGE" android:protectionLevel="signature" /> 
    <uses-permission android:name="com.myappname.android.permission.C2D_MESSAGE"/> 

onCreate方法片断

createLocationRequest(); 
     if (mGoogleApiClient == null) { 
      mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(LocationServices.API) 
       .build(); 
     } 

createLocationRequest方法

private void createLocationRequest(){ 
     mLocationRequest = LocationRequest.create(); 
     mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
     mLocationRequest.setInterval(5000); 
     mLocationRequest.setFastestInterval(1000); 
    } 

在onStart()的onStop()方法

@Override 
public void onStart() { 
     if (!mGoogleApiClient.isConnected()) mGoogleApiClient.connect(); 
     super.onStart(); 
    } 

@Override  
public void onStop() { 
     if (mGoogleApiClient.isConnected()) mGoogleApiClient.disconnect(); 
     super.onStop(); 
    } 

我称右下此代码片段onCreate方法后

if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1 && (ContextCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)) { 
      requestPermissions(new String[] { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION }, REQUEST_PERMISSION_USER_LOCATION); 
     } else { 
      googleMapsLocationPermissionContainer.setVisibility(View.GONE); 
      getUserLocationAndInitializeMap(); 
     } 

googleMapsLocationPermissionContainer只是我覆盖的布局地图直到授予权限。

getUserLocationAndInitializeMap()

try { 
       MapsInitializer.initialize(getActivity()); 
       // Set reference for map object 
       if (map == null) { 
        mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map); 
        mapFragment.getMapAsync(this); 
// Here I set the map to invisible then after I plot all the markers I set it to visible again 

        mapFragment.getView().setVisibility(View.INVISIBLE); 
       } 
      } catch (Exception e) { 
       // Show the google maps alert dialog 
       showGoogleMapsErrorDialog(); 
      } 
+0

显示更多的代码。我正在做一个位置的应用程序,并在6.0上完美运行。我最初的猜测是你需要Android 6.0的清单权限。这在Android-23中是不同的。 –

+0

@AndreiT - 在23+中需要什么清单权限? – Phil

+0

就像这样:https://developer.android.com/training/permissions/requesting.html。我也拥有一切,在Android-6中,它只是没有工作,因为我错过了权限调用等等。 –

回答

1

我对这种做法如下:

@Override 
public void onResume() { 
    super.onResume(); 
    initGpsTracker(); 
} 

public synchronized void initGpsTracker() { 
    if (mMap != null) { 
     try { 
      checkIfPermissionAllowedForLocation(); 
     } catch (SecurityException secex) { 
      Toast.makeText(getActivity(), "not enabled in manifest", Toast.LENGTH_SHORT).show(); 
     } 
    } 
} 

/** 
* rule is the following. First we check if the permissions are there. If not, we check if we can enable or not. 
* If the permissions are check if gps is enabled. 
*/ 
private void checkIfPermissionAllowedForLocation() { 

    //if permissions are set then we go to else, check for gps 
    if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
     // Request missing location permission. 
     if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION)) { 
      askIfToRequestPermissions(); 
     } else { 
      requestPermissions(); 
     } 
    } else { 
     // Location permission has been granted, continue as usual. 
     if (!isGpsProviderEnabled()) { 
      askToEnableGPS(); 
     } else { 
      mMap.setMyLocationEnabled(true); 
     } 
    } 
} 


private void askToEnableGPS() { 
    CustomFragmentDialog customFragmentDialog = CustomFragmentDialog.newInstance(getString(R.string.enable_gps_title), 
      getString(R.string.enable_gps_message), 
      getString(R.string.ok), 
      getString(R.string.cancel), 
      callback); 
    customFragmentDialog.show(getFragmentManager(), CUSTOM_TAG); 
} 

private void requestPermissions() { 
    ActivityCompat.requestPermissions(getActivity(), 
      new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 
      REQUEST_CODE_LOCATION); 
} 

private void enableGPS() { 
    if (enableLocationService != null) { 
     enableLocationService.askToEnableGps(locationCallback); 
    } 
} 

private GoogleAskToEnableLocationService.GpsCallback locationCallback = new GoogleAskToEnableLocationService.GpsCallback() { 
    @Override 
    public void onSuccess() { 
     initGpsTracker(); 
    } 

    @Override 
    public void onResolutionRequired(Status status) { 
     try { 
      status.startResolutionForResult(getActivity(), CONNECTION_RESOLUTION_CODE); 
     } catch (IntentSender.SendIntentException setex) { 
      Toast.makeText(getActivity(), "Exception in sending intent:", Toast.LENGTH_SHORT).show(); 
     } 
    } 

    @Override 
    public void onError() { 
     Toast.makeText(getActivity(), "Location services unavailable!", Toast.LENGTH_SHORT).show(); 
    } 
}; 

private void askIfToRequestPermissions() { 
    CustomFragmentDialog customFragmentDialog = CustomFragmentDialog.newInstance(getString(R.string.enable_gps_title), 
      getString(R.string.enable_permissions_message), 
      getString(R.string.ok), 
      getString(R.string.cancel), 
      callback_permissions); 
    customFragmentDialog.show(getFragmentManager(), CUSTOM_TAG); 
} 

private CustomFragmentDialog.Callback callback = new CustomFragmentDialog.Callback() { 
    @Override 
    public void onPositiveButtonClicked(Bundle bundle) { 
     enableGPS(); 
    } 

    @Override 
    public void onNegativeButtonClicked(Bundle bundle) { 

    } 
}; 


private CustomFragmentDialog.Callback callback_permissions = new CustomFragmentDialog.Callback() { 
    @Override 
    public void onPositiveButtonClicked(Bundle bundle) { 
     requestPermissions(); 
    } 

    @Override 
    public void onNegativeButtonClicked(Bundle bundle) { 

    } 
}; 

private boolean isGpsProviderEnabled() { 
    return googleUtils.isGpsProviderEnabled(); 
} 
//inside it is a normal check if locationManager can access 
//the gps provider 
    if (locationManager.getProvider(provider) == null) { 
     return false; 
    } 

现在,请求允许存在一定的回调:

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    switch (requestCode) { 
     case CONNECTION_RESOLUTION_CODE: 
      switch (resultCode) { 
       case Activity.RESULT_OK: 
        initGpsTracker(); 
        break; 
       case Activity.RESULT_CANCELED: 
        Toast.makeText(getContext(), "Gps not enabled:", Toast.LENGTH_SHORT).show(); 
        break; 
       default: 
        break; 
      } 
      break; 
    } 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
    if (requestCode == REQUEST_CODE_LOCATION) { 
     if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
      initGpsTracker(); 
     } else { 
      Toast.makeText(getActivity(), "Manifest permission, not enabled", Toast.LENGTH_SHORT).show(); 

     } 
    } 
} 

现在,终于在那里你处理该位置的请求的类,所以你不必去设置:

public void askToEnableGps(final GpsCallback callback) { 
    if (locationClient == null) { 
     return; 
    } 
    mLocationRequestHighAccuracy = LocationRequest.create(); 
    mLocationRequestHighAccuracy.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
    mLocationRequestHighAccuracy.setInterval(30 * 1000); 
    mLocationRequestHighAccuracy.setFastestInterval(5 * 1000); 
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder() 
      .addLocationRequest(mLocationRequestHighAccuracy); 
    builder.setAlwaysShow(true); 
    PendingResult<LocationSettingsResult> result = 
      LocationServices.SettingsApi.checkLocationSettings(locationClient, builder.build()); 

    result.setResultCallback(getResultCallback(callback)); 
} 

private ResultCallback<LocationSettingsResult> getResultCallback(final GpsCallback callback) { 

    return new ResultCallback<LocationSettingsResult>() { 
     @Override 
     public void onResult(LocationSettingsResult result) { 
      if (result != null) { 
       final Status status = result.getStatus(); 
       if (callback != null) { 
        //final LocationSettingsStates statesResult = result.getLocationSettingsStates(); 
        switch (status.getStatusCode()) { 
         case LocationSettingsStatusCodes.SUCCESS: 
          // All location settings are satisfied. The client can initialize location 
          // requests here. 
          callback.onSuccess(); 
          break; 
         case LocationSettingsStatusCodes.RESOLUTION_REQUIRED: 
          // Location settings are not satisfied. But could be fixed by showing the user 
          // a dialog. 
          callback.onResolutionRequired(status); 
          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. 
          callback.onError(); 
          break; 
        } 
       } 
      } 
     } 
    }; 
} 

public interface GpsCallback { 
    /** 
    * callback method for when the result it is a success. 
    */ 
    void onSuccess(); 

    /** 
    * callback for when user interaction it is required. 
    * 
    * @param status the result from the service needed for the resolution. 
    */ 
    void onResolutionRequired(Status status); 

    /** 
    * Callback for when the change it is not possible. 
    */ 
    void onError(); 
} 
+0

让我知道它是否适合你。我仍在完善这个代码,所以它可能会有一些错误,对此抱歉。 –

+0

所有上面的代码可以在这里找到:https://github.com/toaderandrei/live_tracking –

+1

你的帮助是非常感谢。看完你的例子后,我最终修改了一些代码。主要问题,如果您在Android Studio中使用模拟器 - 请确保您单击GPS设置页面上的发送,否则设备永远不会获取GPS坐标。 – Phil

相关问题