【问题标题】:Get user's current location once with permission获得用户当前位置一次有权限
【发布时间】:2017-03-16 16:39:05
【问题描述】:

我正在构建一个应用程序,我需要获取用户的当前位置。过程是我想先检查用户的android版本的SDK版本是否为23 - Marshmallow,如果是,则请求权限。

如果用户允许,它将启用或打开该位置。如果用户拒绝,它会再次请求。

但如果用户的android版本低于23,则进入流程:

应用程序获取位置,然后将纬度和经度存储到双变量中,并且可以访问其他方法。

你能告诉我如何正确实现这个功能吗?就像一步一步的过程。谢谢

【问题讨论】:

    标签: android android-location


    【解决方案1】:
    public class MainActivity extends ActionBarActivity implements
        ConnectionCallbacks, OnConnectionFailedListener {
    ...
    @Override
    public void onConnected(Bundle connectionHint) {
        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
                mGoogleApiClient);
        if (mLastLocation != null) {
            mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
            mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
        }
    }}
    

    onConnected 是您在实现 GoogleApiClientCallback 方法后获得的回调。上述方法只会获取最后一个已知位置的纬度和经度。有关先决条件,请参阅@jitesh mohite 答案

    【讨论】:

      【解决方案2】:

      以下将解决您的问题

      私有静态最终 int PERMISSION_REQUEST_CODE = 1;

      //用于检查和请求marshmellow的运行时权限并开始跟踪位置

       private void requestRunTimePermissionAndStartTracking() {
              if (Build.VERSION.SDK_INT >= 23) {
                  // Marshmallow+
                  if (!checkPermission(getBaseContext())) {
                      requestPermission(mActivity, PERMISSION_REQUEST_CODE);
                  } else {
                           // get location here
                  }
              } else {
                 // get location here
              }
          }
      
      
      // check whether we are having location permission for marshmellow
          public static boolean checkPermission(Context context) {
              int result = ContextCompat.checkSelfPermission(context, Manifest.permission
                      .ACCESS_FINE_LOCATION);
              if (result == PackageManager.PERMISSION_GRANTED) {
                  return true;
              } else {
                  return false;
      
              }
          }
      
      // used to request for location permission.
          public static void requestPermission(Activity activity , int code) {
              if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission
                      .ACCESS_FINE_LOCATION)) {
                  Toast.makeText(activity, "GPS permission allows us to access location data. Please allow " +
                          "in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
              } else {
                  ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission
                          .ACCESS_FINE_LOCATION, Manifest.permission
                          .ACCESS_COARSE_LOCATION}, code);
              }
          }
      

      如果用户在 marshmellow 设备中接受位置请求,则覆盖以下代码

       @Override
          public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
              switch (requestCode) {
                  case PERMISSION_REQUEST_CODE:
                      if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                          Util.showToast(getBaseContext(), getBaseContext().getString(R.string
                                  .loc_permission_granted));
                          Util.startActivityAndLocationTracking(getApplicationContext());
                      } else {
                          Util.showToast(getBaseContext(), getBaseContext().getString(R.string
                                  .loc_permission_denied));
                      }
                      break;
                  default:
                      break;
              }
          }
      

      【讨论】:

      【解决方案3】:

      使用以下类获取当前位置:

      public class GPSTracker extends Service implements 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 = 3000; // 3 seconds
          private final Context mContext;
          // Declaring a Location Manager
          protected LocationManager locationManager;
          // flag for GPS status
          boolean isGPSEnabled = false;
          // flag for network status
          boolean isNetworkEnabled = false;
          boolean canGetLocation = false;
          Location location; // location
          double latitude; // latitude
          double longitude; // longitude
          Fragment frag;
      
          public GPSTracker(Context context, Fragment frag) {
              this.mContext = context;
              this.frag = frag;
              getLocation();
          }
      
          @SuppressWarnings("ResourceType")
          public Location getLocation() {
              try {
                  locationManager = (LocationManager) mContext
                          .getSystemService(LOCATION_SERVICE);
      
                  // getting GPS status
                  isGPSEnabled = locationManager
                          .isProviderEnabled(LocationManager.GPS_PROVIDER);
      
                  // getting network status
                  isNetworkEnabled = locationManager
                          .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
      
                  if (!isGPSEnabled && !isNetworkEnabled) {
                      //
      //                Toast.makeText(mContext,"no network provider is enabled",Toast.LENGTH_SHORT).show();
                  } else {
                      this.canGetLocation = true;
                      // First get location from Network Provider
                      if (isNetworkEnabled) {
      
                          locationManager.requestLocationUpdates(
                                  LocationManager.NETWORK_PROVIDER,
                                  MIN_TIME_BW_UPDATES,
                                  MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                          if (locationManager != null) {
                              location = locationManager
                                      .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                              if (location != null) {
                                  latitude = location.getLatitude();
                                  longitude = location.getLongitude();
                              }
                          }
                      }
                      // if GPS Enabled get lat/long using GPS Services
                      if (isGPSEnabled) {
                          if (location == null) {
                              locationManager.requestLocationUpdates(
                                      LocationManager.GPS_PROVIDER,
                                      MIN_TIME_BW_UPDATES,
                                      MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                              if (locationManager != null) {
                                  location = locationManager
                                          .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                                  if (location != null) {
                                      latitude = location.getLatitude();
                                      longitude = location.getLongitude();
                                  }
                              }
                          }
                      }
                  }
      
              } catch (Exception e) {
                  e.printStackTrace();
              }
      
              return location;
          }
      
          @Override
          public void onLocationChanged(Location location) {
              this.location = location;
          }
      
          @Override
          public void onProviderDisabled(String provider) {
          }
      
          @Override
          public void onProviderEnabled(String provider) {
          }
      
          @Override
          public void onStatusChanged(String provider, int status, Bundle extras) {
          }
      
          @Override
          public IBinder onBind(Intent arg0) {
              return null;
          }
      
          public double getLatitude() {
              if (location != null) {
                  latitude = location.getLatitude();
              }
      
              return latitude;
          }
      
          public double getLongitude() {
              if (location != null) {
                  longitude = location.getLongitude();
              }
      
              return longitude;
          }
      
          public boolean canGetLocation() {
              return this.canGetLocation;
          }
      
          public void showSettingsAlert() {
              if (mContext != null) {
                  AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
      
                  alertDialog.setTitle("GPS Setting");
      
                  alertDialog
                          .setMessage("GPS is not enabled. Do you want to go to settings menu?");
      
                  alertDialog.setPositiveButton("Settings",
                          new DialogInterface.OnClickListener() {
                              public void onClick(DialogInterface dialog, int which) {
                                  Intent intent = new Intent(
                                          Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                                  mContext.startActivity(intent);
                              }
                          });
      
                  alertDialog.setNegativeButton("Cancel",
                          new DialogInterface.OnClickListener() {
                              public void onClick(DialogInterface dialog, int which) {
                                  dialog.cancel();
                              }
                          });
      
                  alertDialog.show();
              }
          }
      
          public void stopUsingGPS() {
              if (locationManager != null) {
                  if (ActivityCompat.checkSelfPermission(Application.getAppContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, 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.
                      ActivityCompat.requestPermissions((Activity)mContext, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 789);
      
                  }
                  locationManager.removeUpdates(GPSTracker.this);
              }
          }
      
      }
      

      然后按照此流程在具有运行时权限

      的 Activity/Fragment 中使用
      private void getGpsLink() {
                  if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
       if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION)) {
      Toast.makeText(getActivity(), "Location permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
       Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.fromParts("package", getActivity().getPackageName(), null));
      intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
       intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
      startActivityForResult(intent, 789);
      }else{
                      ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_LOCATION);
          }
      
      
                  } else {
                      GPSTracker gps = new GPSTracker(getActivity(), null);
      
      
                      if (gps.canGetLocation()) {
                         String latitude = String.valueOf(gps.getLatitude());
                         String longitude= String.valueOf(gps.getLongitude());
      
                          CallSearchApi();
                      } else {
                          showSettingsAlert();
                      }
                  }
              }
      

      希望对你有帮助

      【讨论】:

      • 不要使用android framework apis定位,使用google services location apis,看这里:developer.android.com/training/location/index.html
      • 谢谢 Saurabh Srivastava,我会试试你的代码,但我认为他是对的。谷歌服务位置 API 更加一致。但是 Abhinav Puri,你能告诉我怎么做吗?
      猜你喜欢
      • 2023-03-30
      • 1970-01-01
      • 2017-07-06
      • 1970-01-01
      • 2019-08-14
      • 2011-12-14
      • 2023-03-25
      • 2011-07-20
      • 2023-03-03
      相关资源
      最近更新 更多