LocationSettingsRequest.Builder ma metodę setAlwaysShow(boolean show)
. Chociaż dokument wskazuje, że obecnie nic nie robi (aktualizacja 2015-07-05: zaktualizowana dokumentacja Google usunęła to sformułowanie), ustawienie builder.setAlwaysShow(true);
umożliwi zachowanie Google Maps:
Oto kod, dzięki któremu to działa:
if (googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(getActivity())
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
googleApiClient.connect();
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(30 * 1000);
locationRequest.setFastestInterval(5 * 1000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
final LocationSettingsStates state = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
status.startResolutionForResult(
getActivity(), 1000);
} catch (IntentSender.SendIntentException e) {
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
break;
}
}
});
}
Z dokumentacji systemu Android
W przypadku Kotlin patrz tutaj: https://stackoverflow.com/a/61868985/12478830
RESOLUTION_REQUIRED
. Następnie, gdy akceptuję i włączam lokalizację, trafiaSUCCESS
i całkowicie pomijaonActivityResult()
. NaciśnięcieNo
lub cofnięcie powoduje zniknięcie okna dialogowego na sekundę, a następnie ponowne załadowanie i uderzenieRESOLUTION_REQUIRED
. Jedynym sposobem na pozbycie się tego okna dialogowego jest zaakceptowanie lub zamknięcie i ponowne otwarcie aplikacji.launchMode
NIE można ustawić nasingleInstance
inaczej, to NIE zadziała. Okno dialogowe nigdy się nie pojawi ionActivityResult
zostanie wywołane automatycznie. NIE MASZandroid:launchMode="singleInstance"
swojej aktywności wAndroidManifest
. Nauczyłem się tego bardzo ciężko po 3 godzinachChciałbym dodać kilka zmian w odpowiedzi kai dla tych, którzy szukają obsługi przycisków Tak / Nie.
Deklaruj tę stałą w swojej działalności
protected static final int REQUEST_CHECK_SETTINGS = 0x1;
zadzwoń
settingsrequest()
do swojego onStart ()public void settingsrequest() { LocationRequest locationRequest = LocationRequest.create(); locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); locationRequest.setInterval(30 * 1000); locationRequest.setFastestInterval(5 * 1000); LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder() .addLocationRequest(locationRequest); builder.setAlwaysShow(true); //this is the key ingredient 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(); final LocationSettingsStates state = result.getLocationSettingsStates(); switch (status.getStatusCode()) { case LocationSettingsStatusCodes.SUCCESS: // All location settings are satisfied. The client can initialize location // requests here. break; case LocationSettingsStatusCodes.RESOLUTION_REQUIRED: // Location settings are not satisfied. But could be fixed by showing the user // a dialog. try { // Show the dialog by calling startResolutionForResult(), // and check the result in onActivityResult(). status.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS); } catch (IntentSender.SendIntentException e) { // Ignore the error. } 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. break; } } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { // Check for the integer request code originally supplied to startResolutionForResult(). case REQUEST_CHECK_SETTINGS: switch (resultCode) { case Activity.RESULT_OK: startLocationUpdates(); break; case Activity.RESULT_CANCELED: settingsrequest();//keep asking if imp or do whatever break; } break; } }
źródło
LocationServices.SettingsApi jest teraz przestarzałe, więc używamy SettingsClient
LocationRequest mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(10); mLocationRequest.setSmallestDisplacement(10); mLocationRequest.setFastestInterval(10); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder(); builder.addLocationRequest(mLocationRequest);
Następnie sprawdź, czy aktualne ustawienia lokalizacji są prawidłowe. Utwórz zadanie LocationSettingsResponse:
Task<LocationSettingsResponse> task=LocationServices.getSettingsClient(this).checkLocationSettings(builder.build());
Następnie dodaj Listener
task.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() { @Override public void onComplete(Task<LocationSettingsResponse> task) { try { LocationSettingsResponse response = task.getResult(ApiException.class); // All location settings are satisfied. The client can initialize location // requests here. } catch (ApiException exception) { switch (exception.getStatusCode()) { case LocationSettingsStatusCodes.RESOLUTION_REQUIRED: // Location settings are not satisfied. But could be fixed by showing the // user a dialog. try { // Cast to a resolvable exception. ResolvableApiException resolvable = (ResolvableApiException) exception; // Show the dialog by calling startResolutionForResult(), // and check the result in onActivityResult(). resolvable.startResolutionForResult( HomeActivity.this, 101); } catch (IntentSender.SendIntentException e) { // Ignore the error. } catch (ClassCastException e) { // Ignore, should be an impossible error. } 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. break; } } } });
Dodano onActivityResult
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { final LocationSettingsStates states = LocationSettingsStates.fromIntent(data); switch (requestCode) { case 101: switch (resultCode) { case Activity.RESULT_OK: // All required changes were successfully made Toast.makeText(HomeActivity.this,states.isLocationPresent()+"",Toast.LENGTH_SHORT).show(); break; case Activity.RESULT_CANCELED: // The user was asked to change settings, but chose not to Toast.makeText(HomeActivity.this,"Canceled",Toast.LENGTH_SHORT).show(); break; default: break; } break; } }
Skorzystaj z linku SettingsClient
źródło
implementation 'com.google.android.gms:play-services-location:16.0.0'
zamiast tego mógłbym użyć .Działa podobnie do map Google?
Kod źródłowy: https://drive.google.com/open?id=0BzBKpZ4nzNzUOXM2eEhHM3hOZk0
Dodaj zależności w pliku build.gradle:
compile 'com.google.android.gms:play-services:8.3.0'
LUB
compile 'com.google.android.gms:play-services-location:10.0.1'
public class LocationOnOff_Similar_To_Google_Maps extends AppCompatActivity { protected static final String TAG = "LocationOnOff"; private GoogleApiClient googleApiClient; final static int REQUEST_LOCATION = 199; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setFinishOnTouchOutside(true); // Todo Location Already on ... start final LocationManager manager = (LocationManager) LocationOnOff_Similar_To_Google_Maps.this.getSystemService(Context.LOCATION_SERVICE); if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && hasGPSDevice(LocationOnOff_Similar_To_Google_Maps.this)) { Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps already enabled",Toast.LENGTH_SHORT).show(); finish(); } // Todo Location Already on ... end if(!hasGPSDevice(LocationOnOff_Similar_To_Google_Maps.this)){ Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps not Supported",Toast.LENGTH_SHORT).show(); } if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && hasGPSDevice(LocationOnOff_Similar_To_Google_Maps.this)) { Log.e("keshav","Gps already enabled"); Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps not enabled",Toast.LENGTH_SHORT).show(); enableLoc(); }else{ Log.e("keshav","Gps already enabled"); Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps already enabled",Toast.LENGTH_SHORT).show(); } } private boolean hasGPSDevice(Context context) { final LocationManager mgr = (LocationManager) context .getSystemService(Context.LOCATION_SERVICE); if (mgr == null) return false; final List<String> providers = mgr.getAllProviders(); if (providers == null) return false; return providers.contains(LocationManager.GPS_PROVIDER); } private void enableLoc() { if (googleApiClient == null) { googleApiClient = new GoogleApiClient.Builder(LocationOnOff_Similar_To_Google_Maps.this) .addApi(LocationServices.API) .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() { @Override public void onConnected(Bundle bundle) { } @Override public void onConnectionSuspended(int i) { googleApiClient.connect(); } }) .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() { @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.d("Location error","Location error " + connectionResult.getErrorCode()); } }).build(); googleApiClient.connect(); LocationRequest locationRequest = LocationRequest.create(); locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); locationRequest.setInterval(30 * 1000); locationRequest.setFastestInterval(5 * 1000); LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder() .addLocationRequest(locationRequest); builder.setAlwaysShow(true); PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build()); result.setResultCallback(new ResultCallback<LocationSettingsResult>() { @Override public void onResult(LocationSettingsResult result) { final Status status = result.getStatus(); switch (status.getStatusCode()) { case LocationSettingsStatusCodes.RESOLUTION_REQUIRED: try { // Show the dialog by calling startResolutionForResult(), // and check the result in onActivityResult(). status.startResolutionForResult(LocationOnOff_Similar_To_Google_Maps.this, REQUEST_LOCATION); finish(); } catch (IntentSender.SendIntentException e) { // Ignore the error. } break; } } }); } } }
źródło
Ola Cabs korzysta z nowo wydanego interfejsu Settings API, aby osiągnąć tę funkcjonalność. Zgodnie z nowym interfejsem API użytkownik nie musi przechodzić do strony ustawień, aby włączyć usługi lokalizacyjne, zapewniając bezproblemową integrację dla tego samego. Przeczytaj poniżej, aby uzyskać więcej informacji:
https://developers.google.com/android/reference/com/google/android/gms/location/SettingsApi
źródło
SettingsAPI
został wycofany, teraz używaszSettingsClient
developers.google.com/android/reference/com/google/android/gms/…Zależność
compile 'com.google.android.gms:play-services-location:10.0.1'
Kod
import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.IntentSender; import android.location.LocationManager; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.PendingResult; import com.google.android.gms.common.api.ResultCallback; import com.google.android.gms.common.api.Status; import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationServices; import com.google.android.gms.location.LocationSettingsRequest; import com.google.android.gms.location.LocationSettingsResult; import com.google.android.gms.location.LocationSettingsStates; import com.google.android.gms.location.LocationSettingsStatusCodes; public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { public static final int REQUEST_LOCATION=001; GoogleApiClient googleApiClient; LocationManager locationManager; LocationRequest locationRequest; LocationSettingsRequest.Builder locationSettingsRequest; Context context; PendingResult<LocationSettingsResult> pendingResult; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); context = this; locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { Toast.makeText(this, "Gps is Enabled", Toast.LENGTH_SHORT).show(); } else { mEnableGps(); } } public void mEnableGps() { googleApiClient = new GoogleApiClient.Builder(context) .addApi(LocationServices.API).addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); googleApiClient.connect(); mLocationSetting(); } public void mLocationSetting() { locationRequest = LocationRequest.create(); locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); locationRequest.setInterval(1 * 1000); locationRequest.setFastestInterval(1 * 1000); locationSettingsRequest = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest); mResult(); } public void mResult() { pendingResult = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, locationSettingsRequest.build()); pendingResult.setResultCallback(new ResultCallback<LocationSettingsResult>() { @Override public void onResult(@NonNull LocationSettingsResult locationSettingsResult) { Status status = locationSettingsResult.getStatus(); switch (status.getStatusCode()) { case LocationSettingsStatusCodes.SUCCESS: // All location settings are satisfied. The client can initialize location // requests here. break; case LocationSettingsStatusCodes.RESOLUTION_REQUIRED: try { status.startResolutionForResult(MainActivity.this, REQUEST_LOCATION); } catch (IntentSender.SendIntentException e) { } 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. break; } } }); } //callback method @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { final LocationSettingsStates states = LocationSettingsStates.fromIntent(data); switch (requestCode) { case REQUEST_LOCATION: switch (resultCode) { case Activity.RESULT_OK: // All required changes were successfully made Toast.makeText(context, "Gps enabled", Toast.LENGTH_SHORT).show(); break; case Activity.RESULT_CANCELED: // The user was asked to change settings, but chose not to Toast.makeText(context, "Gps Canceled", Toast.LENGTH_SHORT).show(); break; default: break; } break; } } @Override public void onConnected(@Nullable Bundle bundle) { } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { } }
źródło
Możesz także dodać kilka żądań lokalizacji dla Buildera, aby uzyskać okno dialogowe „Użyj GPS, Wi-Fi i sieci komórkowych do lokalizacji” zamiast tylko „Użyj GPS do lokalizacji”
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder() .addLocationRequest(createLocationRequest(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY)) .addLocationRequest(createLocationRequest(LocationRequest.PRIORITY_HIGH_ACCURACY)) .setAlwaysShow(true); PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
źródło
W Kotlinie użyj tego kodu:
import android.app.Activity import android.content.Intent import android.content.IntentSender import android.os.Bundle import android.util.Log import androidx.appcompat.app.AppCompatActivity import com.google.android.gms.common.api.GoogleApiClient import com.google.android.gms.common.api.PendingResult import com.google.android.gms.common.api.Status import com.google.android.gms.location.* class MainActivity : AppCompatActivity() { private var googleApiClient: GoogleApiClient? = null private val REQUESTLOCATION = 199 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableLoc() } private fun enableLoc() { googleApiClient = GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addConnectionCallbacks(object : GoogleApiClient.ConnectionCallbacks { override fun onConnected(bundle: Bundle?) {} override fun onConnectionSuspended(i: Int) { googleApiClient?.connect() } }) .addOnConnectionFailedListener { }.build() googleApiClient?.connect() val locationRequest = LocationRequest.create() locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY locationRequest.interval = 30 * 1000.toLong() locationRequest.fastestInterval = 5 * 1000.toLong() val builder = LocationSettingsRequest.Builder() .addLocationRequest(locationRequest) builder.setAlwaysShow(true) val result: PendingResult<LocationSettingsResult> = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build()) result.setResultCallback { result -> val status: Status = result.status when (status.statusCode) { LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> try { status.startResolutionForResult( this@MainActivity, REQUESTLOCATION ) } catch (e: IntentSender.SendIntentException) { } } } } override fun onActivityResult( requestCode: Int, resultCode: Int, data: Intent? ) { super.onActivityResult(requestCode, resultCode, data) when (requestCode) { REQUESTLOCATION -> when (resultCode) { Activity.RESULT_OK -> Log.d("abc","OK") Activity.RESULT_CANCELED -> Log.d("abc","CANCEL") } } } }
źródło
Proszę sprawdzić moje bardzo proste rozwiązanie, aby uzyskać lokalizację użytkownika na pierwszym planie.
https://github.com/Maqsood007/UserLocation-Android/blob/master/app/src/main/java/jetpack/skill/userlocation_android/utils/LocationUtility.kt
źródło
Nowa zaktualizowana odpowiedź Sierpień 2020 wprowadź opis linku tutaj
mój fragment jest jak ta aktualizacja, jeśli używasz w swojej działalności
import android.app.Activity; import android.content.Intent; import android.content.IntentSender; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import com.google.android.gms.common.api.ApiException; import com.google.android.gms.common.api.ResolvableApiException; import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationServices; import com.google.android.gms.location.LocationSettingsRequest; import com.google.android.gms.location.LocationSettingsResponse; import com.google.android.gms.location.LocationSettingsStatusCodes; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; public class FragmentSearch extends Fragment { View SearchFragmentview; protected static final int REQUEST_CHECK_SETTINGS = 0x1; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { SearchFragmentview=inflater.inflate(R.layout.fragment_search,container,false); getLocationDialog(); return SearchFragmentview; } private void getLocationDialog() { LocationRequest locationRequest = LocationRequest.create(); locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); locationRequest.setInterval(30 * 1000); locationRequest.setFastestInterval(5 * 1000); LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder() .addLocationRequest(locationRequest); builder.setAlwaysShow(true); //this is the key ingredient Task<LocationSettingsResponse> result = LocationServices.getSettingsClient(getContext()).checkLocationSettings(builder.build()); result.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() { @Override public void onComplete(Task<LocationSettingsResponse> task) { try { LocationSettingsResponse response = task.getResult(ApiException.class); // All location settings are satisfied. The client can initialize location // requests here. } catch (ApiException exception) { switch (exception.getStatusCode()) { case LocationSettingsStatusCodes.RESOLUTION_REQUIRED: // Location settings are not satisfied. But could be fixed by showing the // user a dialog. try { // Cast to a resolvable exception. ResolvableApiException resolvable = (ResolvableApiException) exception; // Show the dialog by calling startResolutionForResult(), // and check the result in onActivityResult(). resolvable.startResolutionForResult( getActivity(), REQUEST_CHECK_SETTINGS); } catch (IntentSender.SendIntentException e) { // Ignore the error. } catch (ClassCastException e) { // Ignore, should be an impossible error. } 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. break; } } } }); } public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQUEST_CHECK_SETTINGS: switch (resultCode) { case Activity.RESULT_OK: // All required changes were successfully made break; case Activity.RESULT_CANCELED: // The user was asked to change settings, but chose not to break; default: break; } break; } }[enter image description here][2] }
źródło
GoogleApiClient jest przestarzały . Nowa implementacja w Kotlinie może wyglądać następująco.
Zależności
// Google Maps Location Services implementation 'com.google.android.gms:play-services-location:17.1.0' implementation 'com.google.android.gms:play-services-maps:17.0.0'
Kod
val locationRequest = LocationRequest.create() .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) .setInterval(30 * 1000) .setFastestInterval(5 * 1000) val builder = LocationSettingsRequest.Builder() .addLocationRequest(locationRequest) .setAlwaysShow(true) val pendingResult = LocationServices .getSettingsClient(activity) .checkLocationSettings(builder.build()) pendingResult.addOnCompleteListener { task -> if (task.isSuccessful.not()) { task.exception?.let { if (it is ApiException && it.statusCode == LocationSettingsStatusCodes.RESOLUTION_REQUIRED) { // Show the dialog by calling startResolutionForResult(), // and check the result in onActivityResult(). (it as ResolvableApiException).startResolutionForResult(activity, MainActivity.REQUEST_CODE_LOCATION) } } } }
źródło