如何在Android中获取用户的当前位置 [英] How to get user's current location in Android

查看:194
本文介绍了如何在Android中获取用户的当前位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想点击一个按钮来获取用户的当前经济纬度。我知道你可以使用FusedLocationApi获取最后一个已知位置。但是我无法理解的是,gps或位置服务需要为此打开吗?如果是,如何检查用户是否已打开位置并获取当前位置。此外,如何在获取位置中包含棉花糖许可检查。

我已经提到:
1) googlesamples / android-play-location
2) googlesamples / android-XYZTouristAttractions
和许多其他链接,但无法完成一个完整的流程。



代码

  public class AccessLocationFragment extends BaseFragment implements View.OnClickListener,LocationListener,
GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener,GeneralDialogFragment.GeneralDialogClickListener {

private static final int MY_PERMISSIONS_REQUEST_LOCATION = 101;
private static final String TAG = AccessLocationFragment.class.getSimpleName();
private static final int REQUEST_CHECK_SETTINGS = 102;
私人按钮mAccessLocation;
private EditText mZipCode;
私人对话progressDialog;
私有GoogleApiClient mGoogleApiClient;
私人位置mLastLocation;

public static AccessLocationFragment newInstance(){
return new AccessLocationFragment();
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater,@Nullable ViewGroup容器,@Nullable Bundle savedInstanceState){
返回inflater。 inflate(R.layout.fragment_access_location,container,false);
}

@Override
public void onViewCreated(View view,@Nullable Bundle savedInstanceState){
super.onViewCreated(view,savedInstanceState);
RecycleApplication.getEventBus()。register(this);
mAccessLocation =(Button)view.findViewById(R.id.access_location);
mZipCode =(EditText)view.findViewById(R.id.zip_code);
mAccessLocation.setOnClickListener(this);

mZipCode.setOnEditorActionListener(new TextView.OnEditorActionListener(){
@Override
public boolean onEditorAction(TextView v,int actionId,KeyEvent event){
if(actionId == EditorInfo.IME_ACTION_DONE){
String zipCode = mZipCode.getText()。toString()。trim();
if(TextUtils.isEmpty(zipCode)){
Toast.makeText( (请输入邮编)Toast.LENGTH_SHORT).show();
} else {
Call< Address> response = mRecycleService.getAddress(zipCode);
response.enqueue( new GetLocationCallback(AccessLocationFragment.this));
}
}
return false;
}
});
//创建一个GoogleAPIClient实例。
if(mGoogleApiClient == null){
mGoogleApiClient = new GoogleApiClient.Builder(mActivity)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi( LocationServices.API)
.build();

if(!LocationUtils.checkFineLocationPermission(mActivity)){
//查看用户是否拒绝过去的许可
if(shouldShowRequestPermissionRationale(android.Manifest.permission.ACCESS_FINE_LOCATION )){
//显示一个简单的快餐栏来解释请求,而不是
showPermissionSnackbar();
} else {
requestFineLocationPermission();
}
} else {
displayLocationSettingsRequest();



private void startHomeActivity(Address address){
RecyclePreferences.getInstance()。setCity(address.getCity());
RecyclePreferences.getInstance()。setState(address.getState());
RecyclePreferences.getInstance()。setLatitude(address.getLatitude());
RecyclePreferences.getInstance()。setLongitude(address.getLongitude());
RecyclePreferences.getInstance()。setZipCode(address.getZipCode());
startActivity(new Intent(mActivity,HomeActivity.class));
mActivity.finish();
}
$ b $ @覆盖
public void onSuccess(调用< Address>调用,Response< Address>响应){
mActivity.hideProgressDialog(progressDialog);
if(response.isSuccessful()){
Address address = response.body();
startHomeActivity(address);
}
}

@Override
public void onFailure(Call< Address> call,Throwable t){
mActivity.hideProgressDialog(progressDialog);
}

@Override
public void onClick(View view){
if(view.getId()== R.id.access_location){
fetchAddress(mLastLocation);
}
}

@Override
public void onRequestPermissionsResult(int requestCode,String permissions [],int [] grantResults){$ b $ switch(requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION:{
if(grantResults [0] == PackageManager.PERMISSION_GRANTED){
displayLocationSettingsRequest();
}
}
}
}

private void fetchAddress(Location location){
mRecycleService = new RecycleRetrofitBuilder(mActivity).getService );
呼叫<地址> response = mRecycleService.getAddress(String.valueOf(location.getLatitude()),String.valueOf(location.getLongitude()));
progressDialog = mActivity.showProgressDialog(mActivity);
response.enqueue(new GetLocationCallback(AccessLocationFragment.this));


private void requestFineLocationPermission(){
requestPermissions(new String [] {Manifest.permission.ACCESS_FINE_LOCATION},MY_PERMISSIONS_REQUEST_LOCATION);
}

private void showPermissionSnackbar(){
GeneralDialogFragment generalDialogFragment = GeneralDialogFragment。
newInstance(权限,允许回收世界使用您的位置。,允许,返回,this);
mActivity.showDialogFragment(generalDialogFragment);
displayLocationSettingsRequest();
}

private void displayLocationSettingsRequest(){
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(10000);
locationRequest.setFastestInterval(10000/2);

LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()。addLocationRequest(locationRequest);
builder.setAlwaysShow(true);

PendingResult< LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient,builder.build());
result.setResultCallback(new ResultCallback< LocationSettingsResult>(){
@Override
public void onResult(LocationSettingsResult result){
final Status status = result.getStatus();
switch(status.getStatusCode()){
case LocationSettingsStatusCodes.SUCCESS:
getLocation();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
Log.i (TAG,位置设置不满意,向用户显示升级位置设置的对话框);
尝试{
status.startResolutionForResult(mActivity,REQUEST_CHECK_SETTINGS);
} catch(IntentSender。 SendIntentException e){
Log.i(TAG,PendingIntent无法执行请求。);
}
break;
case Loc ationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Log.i(TAG,位置设置不足,无法在此修复。 );
break;
}
}
});
}

private void getLocation(){
if(ActivityCompat.checkSelfPermission(mActivity,Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED
&&&& ActivityCompat.checkSelfPermission(mActivity,Manifest.permission.ACCESS_COARSE_LOCATION)!= PackageManager.PERMISSION_GRANTED){
return;
}
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
}
$ b $覆盖
public void onActivityResult(int requestCode ,int resultCode,Intent data){
super.onActivityResult(requestCode,resultCode,data); $ b $ if(requestCode == REQUEST_CHECK_SETTINGS){
getLocation();
}


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

@Override
public vo id onStop(){
mGoogleApiClient.disconnect();
super.onStop();
}

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

@Override
public void onDestroy(){
super.onDestroy();
RecycleApplication.getEventBus()。unregister(this);



@Override
public void onConnectionSuspended(int i){

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult){

}

@Override
public void onOk(DialogFragment dialogFragment){
dialogFragment 。解雇();
requestFineLocationPermission();
}

@Override
public void onCancel(DialogFragment dialogFragment){
dialogFragment.dismiss();

$ b

}

解决方案

对不起,我没有通过你的代码,我只是写你在你的问题中要求的功能。
首先,您需要建立一个与google api客户端的连接,如:

  private synchronized void buildGoogleApiClient(){
mGoogleApiClient =新的GoogleApiClient.Builder(GTApplication.getContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
。建立();
mGoogleApiClient.connect();
}

在我的经历中,你几乎总是被称为 onConnected()函数,您可以在API级别23之后请求位置权限:

  public void checkLocationPermission(){
if(ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED){
//您无权申请
ActivityCompat.requestPermissions(this,Manifest.permission.ACCESS_FINE_LOCATION),REQ_CODE);
} else {
//您有权限。
requestLocationAccess();






如果你申请了许可,你的将使用 REQ_CODE 调用onRequestPermissionsResult()函数。如果您需要更多信息来实施这些活动,请查看原始文档获取运行时权限这是非常有用的。

当您有权限时,您可以检查位置是否启用,如:

  public void requestLocationAccess ){
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval((long)(LocationHelper.UPDATE_INTERVAL_IN_MILLISECONDS * 1.1));
mLocationRequest.setFastestInterval(LocationHelper.UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
final LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()。addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true); //这是关键成分
com.google.android.gms.common.api.PendingResult< LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient,builder.build());
result.setResultCallback(new ResultCallback< LocationSettingsResult>(){
@Override
public void onResult(@NonNull LocationSettingsResult result){
if(requester!= null){
final Status resultStatus = result.getStatus();
switch(resultStatus.getStatusCode()){
case LocationSettingsStatusCodes.SUCCESS:
//所有位置设置都满足。用户的位置HERE



break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
//位置设置不满足,但可以通过显示用户对话框
try {
resultStatus.startResolutionForResult(this,REQUEST_LOCATION);
break;
} catch(IntentSender .SendIntentException被忽略){}
}
}
}
}
});



$ b $ p
$ b

如果需要向用户显示启用位置对话框,回调 onActivityResult()函数与请求代码 REQUEST_LOCATION



在完成所有这些过程之后,您可以调用 locationManager.getLastKnownLocation()或开始位置请求或任何您想要的内容。

PS:我已经从我的大班级中删除了这段代码,所以如果您发现任何错误,请随时提出。我只指定了一切顺利的情况,因为它包含了本质,你可以自己处理我希望的异常。

I want to fetch user's current lat long on click of a button. I know that you can get the last known location using FusedLocationApi. But what I am not able to understand is, gps or location services needs to be turned on for this? If yes, how to check that the user has turned on location and get the current location. Also, how to include marshmallow permission checks in getting the location.

I have already referred: 1) googlesamples/android-play-location 2) googlesamples/android-XYZTouristAttractions and many other links but unable to make a complete flow.

Code

public class AccessLocationFragment extends BaseFragment implements View.OnClickListener, LocationListener,
    GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, GeneralDialogFragment.GeneralDialogClickListener {

private static final int MY_PERMISSIONS_REQUEST_LOCATION = 101;
private static final String TAG = AccessLocationFragment.class.getSimpleName();
private static final int REQUEST_CHECK_SETTINGS = 102;
private Button mAccessLocation;
private EditText mZipCode;
private Dialog progressDialog;
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;

public static AccessLocationFragment newInstance() {
    return new AccessLocationFragment();
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_access_location, container, false);
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    RecycleApplication.getEventBus().register(this);
    mAccessLocation = (Button) view.findViewById(R.id.access_location);
    mZipCode = (EditText) view.findViewById(R.id.zip_code);
    mAccessLocation.setOnClickListener(this);

    mZipCode.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            if (actionId == EditorInfo.IME_ACTION_DONE) {
                String zipCode = mZipCode.getText().toString().trim();
                if (TextUtils.isEmpty(zipCode)) {
                    Toast.makeText(mActivity, "Please enter zip code", Toast.LENGTH_SHORT).show();
                } else {
                    Call<Address> response = mRecycleService.getAddress(zipCode);
                    response.enqueue(new GetLocationCallback(AccessLocationFragment.this));
                }
            }
            return false;
        }
    });
    // Create an instance of GoogleAPIClient.
    if (mGoogleApiClient == null) {
        mGoogleApiClient = new GoogleApiClient.Builder(mActivity)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }
    if (!LocationUtils.checkFineLocationPermission(mActivity)) {
        // See if user has denied permission in the past
        if (shouldShowRequestPermissionRationale(android.Manifest.permission.ACCESS_FINE_LOCATION)) {
            // Show a simple snackbar explaining the request instead
            showPermissionSnackbar();
        } else {
            requestFineLocationPermission();
        }
    } else {
        displayLocationSettingsRequest();
    }
}

private void startHomeActivity(Address address) {
    RecyclePreferences.getInstance().setCity(address.getCity());
    RecyclePreferences.getInstance().setState(address.getState());
    RecyclePreferences.getInstance().setLatitude(address.getLatitude());
    RecyclePreferences.getInstance().setLongitude(address.getLongitude());
    RecyclePreferences.getInstance().setZipCode(address.getZipCode());
    startActivity(new Intent(mActivity, HomeActivity.class));
    mActivity.finish();
}

@Override
public void onSuccess(Call<Address> call, Response<Address> response) {
    mActivity.hideProgressDialog(progressDialog);
    if (response.isSuccessful()) {
        Address address = response.body();
        startHomeActivity(address);
    }
}

@Override
public void onFailure(Call<Address> call, Throwable t) {
    mActivity.hideProgressDialog(progressDialog);
}

@Override
public void onClick(View view) {
    if (view.getId() == R.id.access_location) {
        fetchAddress(mLastLocation);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_LOCATION: {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
               displayLocationSettingsRequest();
            }
        }
    }
}

private void fetchAddress(Location location) {
    mRecycleService = new RecycleRetrofitBuilder(mActivity).getService();
    Call<Address> response = mRecycleService.getAddress(String.valueOf(location.getLatitude()), String.valueOf(location.getLongitude()));
    progressDialog = mActivity.showProgressDialog(mActivity);
    response.enqueue(new GetLocationCallback(AccessLocationFragment.this));
}

private void requestFineLocationPermission() {
    requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION);
}

private void showPermissionSnackbar() {
    GeneralDialogFragment generalDialogFragment = GeneralDialogFragment.
            newInstance("Permissions", "Allow Recycle the World to use your location.", "Allow", "Go Back", this);
    mActivity.showDialogFragment(generalDialogFragment);
    displayLocationSettingsRequest();
}

private void displayLocationSettingsRequest() {
    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(10000);
    locationRequest.setFastestInterval(10000 / 2);

    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
    builder.setAlwaysShow(true);

    PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
    result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
        @Override
        public void onResult(LocationSettingsResult result) {
            final Status status = result.getStatus();
            switch (status.getStatusCode()) {
                case LocationSettingsStatusCodes.SUCCESS:
                    getLocation();
                    break;
                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                    Log.i(TAG, "Location settings are not satisfied. Show the user a dialog to upgrade location settings ");
                    try {
                        status.startResolutionForResult(mActivity, REQUEST_CHECK_SETTINGS);
                    } catch (IntentSender.SendIntentException e) {
                        Log.i(TAG, "PendingIntent unable to execute request.");
                    }
                    break;
                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    Log.i(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog not created.");
                    break;
            }
        }
    });
}

private void getLocation() {
    if (ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CHECK_SETTINGS) {
        getLocation();
    }
}

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

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

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

@Override
public void onDestroy() {
    super.onDestroy();
    RecycleApplication.getEventBus().unregister(this);
}


@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}

@Override
public void onOk(DialogFragment dialogFragment) {
    dialogFragment.dismiss();
    requestFineLocationPermission();
}

@Override
public void onCancel(DialogFragment dialogFragment) {
    dialogFragment.dismiss();

}

}

解决方案

Sorry, I haven't go through your code, I am just writing the functions that you have asked for in your question. First, you need to build a connection to google api client like:

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

After this in my experience, you almost always get called onConnected() function where you can ask for the location permission after API level 23:

public void checkLocationPermission(){
    if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
        // You don't have the permission you need to request it 
        ActivityCompat.requestPermissions(this, Manifest.permission.ACCESS_FINE_LOCATION), REQ_CODE);
    }else{
        // You have the permission.
        requestLocationAccess();
    }
}

If you requested the permission your onRequestPermissionsResult() function will be called with the REQ_CODE. If you need more info to implement the events check the original documentation for runtime permissions it is very useful.
When you have the permission you can check if the location is enabled like:

public void requestLocationAccess(){
    LocationRequest mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval((long) (LocationHelper.UPDATE_INTERVAL_IN_MILLISECONDS*1.1));
    mLocationRequest.setFastestInterval(LocationHelper.UPDATE_INTERVAL_IN_MILLISECONDS);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    final LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest);
    builder.setAlwaysShow(true); //this is the key ingredient
    com.google.android.gms.common.api.PendingResult<LocationSettingsResult> result =
                LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
    result.setResultCallback(new ResultCallback<LocationSettingsResult>(){
        @Override
        public void onResult(@NonNull LocationSettingsResult result){
            if(requester != null){
                final Status resultStatus = result.getStatus();
                switch(resultStatus.getStatusCode()){
                    case LocationSettingsStatusCodes.SUCCESS:
                        // All location settings are satisfied. You can ask for the user's location HERE



                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        // Location settings are not satisfied. But could be fixed by showing the user a dialog.
                        try{
                            resultStatus.startResolutionForResult(this, REQUEST_LOCATION);
                            break;
                        }catch(IntentSender.SendIntentException ignored){}
                    }
                }
            }
        }
    });  
}

If the enable location dialog needed to be shown to the user you will get a callback in onActivityResult() function with the request code REQUEST_LOCATION)

That's it after you done with all this process you can call locationManager.getLastKnownLocation() or start location request or whatever you want.

PS.: I have cut this code from my bigger class, so please if you find any mistakes feel free to ask. I have specified only the case when everything goes well, because it contains the essence, you can handle the exceptions yourself I hope.

这篇关于如何在Android中获取用户的当前位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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