사용자에게 설정 페이지로 이동하여 위치 서비스를 활성화하고 다시 돌아 오도록 요청하는 전통적인 접근 방식과 달리 일부 최신 앱에서 동일한 작업을 수행하는 더 간단한 방법을 발견했습니다.
아래 스크린 샷을 참조하면 한 번의 클릭으로 위치 서비스를 활성화하라는 대화 상자가 사용자에게 표시되며 해당 앱에서 작동합니다.
어떻게 똑같이 할 수 있습니까?
사용자에게 설정 페이지로 이동하여 위치 서비스를 활성화하고 다시 돌아 오도록 요청하는 전통적인 접근 방식과 달리 일부 최신 앱에서 동일한 작업을 수행하는 더 간단한 방법을 발견했습니다.
아래 스크린 샷을 참조하면 한 번의 클릭으로 위치 서비스를 활성화하라는 대화 상자가 사용자에게 표시되며 해당 앱에서 작동합니다.
어떻게 똑같이 할 수 있습니까?
답변:
이 대화 상자는 Google Play 서비스에서 사용할 수있는 LocationSettingsRequest.Builder에 의해 생성됩니다 .
앱에 종속성을 추가해야합니다 build.gradle
.
compile 'com.google.android.gms:play-services-location:10.0.1'
그런 다음이 최소한의 예를 사용할 수 있습니다.
private void displayLocationSettingsRequest(Context context) {
GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API).build();
googleApiClient.connect();
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(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
Log.i(TAG, "All location settings are satisfied.");
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
Log.i(TAG, "Location settings are not satisfied. Show the user a dialog to upgrade location settings ");
try {
// Show the dialog by calling startResolutionForResult(), and check the result
// in onActivityResult().
status.startResolutionForResult(MainActivity.this, 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;
}
}
});
}
여기 에서 전체 예를 찾을 수 있습니다 .
You need to add a dependency to your app build.gradle: compile 'com.google.android.gms:play-services:8.1.0'
app
1)LocationRequest
원하는대로 만들기
LocationRequest mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10 * 1000)
.setFastestInterval(1 * 1000);
2) 만들기LocationSettingsRequest.Builder
LocationSettingsRequest.Builder settingsBuilder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
settingsBuilder.setAlwaysShow(true);
3) 가져 오기 LocationSettingsResponse
Task
다음 코드를 사용하여
Task<LocationSettingsResponse> result = LocationServices.getSettingsClient(this)
.checkLocationSettings(settingsBuilder.build());
참고 : LocationServices.SettingsApi
는 더 이상 사용되지 않으므로 SettingsClient
대신 사용하십시오 .
4) 작업OnCompleteListener
결과를 얻기 위해 a 를 추가 하고 Task
완료되면 클라이언트는 LocationSettingsResponse
객체 의 상태 코드를보고 위치 설정을 확인할 수 있습니다 .
result.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() {
@Override
public void onComplete(@NonNull Task<LocationSettingsResponse> task) {
try {
LocationSettingsResponse response =
task.getResult(ApiException.class);
} catch (ApiException ex) {
switch (ex.getStatusCode()) {
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
ResolvableApiException resolvableApiException =
(ResolvableApiException) ex;
resolvableApiException
.startResolutionForResult(MapsActivity.this,
LOCATION_SETTINGS_REQUEST);
} catch (IntentSender.SendIntentException e) {
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
break;
}
}
}
});
사례 1 : LocationSettingsStatusCodes.RESOLUTION_REQUIRED
: 위치가 활성화되어 있지 않지만 대화 상자 (를 호출하여 startResolutionForResult
) 에서 위치를 켜도록 요청하여 사용자에게 위치를 활성화하도록 요청할 수 있습니다 .
CASE 2 : LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE
: 위치 설정이 만족스럽지 않습니다. 그러나 설정을 수정할 방법이 없으므로 대화 상자를 표시하지 않습니다.
5) OnActivityResult
위치 설정 대화 상자에서 사용자 작업을 얻을 수 있습니다. RESULT_OK
=> 사용자가 위치를 켰습니다. RESULT_CANCELLED
-사용자가 위치 설정 요청을 거부했습니다.
Google지도와 유사한 작동
build.gradle 파일에 종속성 추가
compile 'com.google.android.gms:play-services:8.3.0'
이런 저런
compile 'com.google.android.gms:play-services-location:10.0.1'
import android.content.Context;
import android.content.IntentSender;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;
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.LocationSettingsStatusCodes;
import java.util.List;
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;
}
}
});
}
}
}
implementation 'com.google.android.gms:play-services-location:16.0.0'
변수 선언
private SettingsClient mSettingsClient;
private LocationSettingsRequest mLocationSettingsRequest;
private static final int REQUEST_CHECK_SETTINGS = 214;
private static final int REQUEST_ENABLE_GPS = 516;
아래 코드를 사용하여 대화 상자 열기
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(new LocationRequest().setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY));
builder.setAlwaysShow(true);
mLocationSettingsRequest = builder.build();
mSettingsClient = LocationServices.getSettingsClient(YourActivity.this);
mSettingsClient
.checkLocationSettings(mLocationSettingsRequest)
.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
//Success Perform Task Here
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
int statusCode = ((ApiException) e).getStatusCode();
switch (statusCode) {
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
ResolvableApiException rae = (ResolvableApiException) e;
rae.startResolutionForResult(YourActivity.this, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException sie) {
Log.e("GPS","Unable to execute request.");
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Log.e("GPS","Location settings are inadequate, and cannot be fixed here. Fix in Settings.");
}
}
})
.addOnCanceledListener(new OnCanceledListener() {
@Override
public void onCanceled() {
Log.e("GPS","checkLocationSettings -> onCanceled");
}
});
onActivityResult
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CHECK_SETTINGS) {
switch (resultCode) {
case Activity.RESULT_OK:
//Success Perform Task Here
break;
case Activity.RESULT_CANCELED:
Log.e("GPS","User denied to access location");
openGpsEnableSetting();
break;
}
} else if (requestCode == REQUEST_ENABLE_GPS) {
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
boolean isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!isGpsEnabled) {
openGpsEnableSetting();
} else {
navigateToUser();
}
}
}
private void openGpsEnableSetting() {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivityForResult(intent, REQUEST_ENABLE_GPS);
}
rae.startResolutionForResult(activity, REQUEST_CHECK_SETTINGS)
호출 되지 않습니다. startIntentSenderForResult(rae.getResolution().getIntentSender(), REQUEST_CHECK_SETTINGS, null, 0, 0, 0, null)
onActivityResult()
startIntentSenderForResult
방법 과 비슷한 것을 사용할 수 openGpsEnableSetting()
있습니까?
openGpsEnableSetting()
단순히 GPS 설정을 활성화하는 대화 상자를 시작합니다. 완료되면 onActivityResult()
로 호출됩니다 requestCode == REQUEST_ENABLE_GPS
.
onActivityResult()
Activity에서 호출되고 결과를 Fragment
같은 결과로 반환 할 수 있는지 궁금합니다 startIntentSenderForResult
.
Mattia Maestrini 덕분에 +1
using Android.Gms.Common.Apis;
using Android.Gms.Location;
public const int REQUEST_CHECK_SETTINGS = 0x1;
private void DisplayLocationSettingsRequest()
{
var googleApiClient = new GoogleApiClient.Builder(this).AddApi(LocationServices.API).Build();
googleApiClient.Connect();
var locationRequest = LocationRequest.Create();
locationRequest.SetPriority(LocationRequest.PriorityHighAccuracy);
locationRequest.SetInterval(10000);
locationRequest.SetFastestInterval(10000 / 2);
var builder = new LocationSettingsRequest.Builder().AddLocationRequest(locationRequest);
builder.SetAlwaysShow(true);
var result = LocationServices.SettingsApi.CheckLocationSettings(googleApiClient, builder.Build());
result.SetResultCallback((LocationSettingsResult callback) =>
{
switch (callback.Status.StatusCode)
{
case LocationSettingsStatusCodes.Success:
{
DoStuffWithLocation();
break;
}
case LocationSettingsStatusCodes.ResolutionRequired:
{
try
{
// Show the dialog by calling startResolutionForResult(), and check the result
// in onActivityResult().
callback.Status.StartResolutionForResult(this, REQUEST_CHECK_SETTINGS);
}
catch (IntentSender.SendIntentException e)
{
}
break;
}
default:
{
// If all else fails, take the user to the android location settings
StartActivity(new Intent(Android.Provider.Settings.ActionLocationSourceSettings));
break;
}
}
});
}
protected override void OnActivityResult(int requestCode, Android.App.Result resultCode, Intent data)
{
switch (requestCode)
{
case REQUEST_CHECK_SETTINGS:
{
switch (resultCode)
{
case Android.App.Result.Ok:
{
DoStuffWithLocation();
break;
}
case Android.App.Result.Canceled:
{
//No location
break;
}
}
break;
}
}
}
이것은 Huawei 또는 Google 서비스가 설치되지 않은 기타 장치에서는 작동하지 않습니다.
using android.Gms.Common.Apis; using Android.Gms.Location;
? 전화를 한 후 LocationServices.SettingsApi.CheckLocationSettings
내에서 콜백을 result.SetResultCallback(
받습니까? 각각에 중단 점을 놓고 코드가 무엇을하는지 확인하십시오
Android Marshmallow 6는 런타임 권한을 지원합니다. 런타임 권한은 Marshmallow에서만 작동하며 이전 Marshmallow에서는 여전히 이전 방식으로 작동합니다.
이 Android 개발자 공식 비디오에서 이에 대해 자세히 알아볼 수 있습니다.
https://www.youtube.com/watch?v=C8lUdPVSzDk
권한 요청 : http://developer.android.com/training/permissions/requesting.html
답변 해주신 Mattia Maestrini에게 감사드립니다.
compile 'com.google.android.gms:play-services-location:8.1.0'
충분합니다. 이렇게하면 앱에 불필요한 라이브러리가 포함되는 것을 방지하고 메서드 수를 낮게 유지하는 데 도움이됩니다.
Kotlin 솔루션
더하다 build.gradle(Module:app)
implementation 'com.google.android.gms:play-services-location:17.0.0'
implementation 'com.google.android.gms:play-services-maps:17.0.0'
그 후이 함수를 생성
fun enablegps() {
val mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(2000)
.setFastestInterval(1000)
val settingsBuilder = LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest)
settingsBuilder.setAlwaysShow(true)
val result = LocationServices.getSettingsClient(this).checkLocationSettings(settingsBuilder.build())
result.addOnCompleteListener { task ->
//getting the status code from exception
try {
task.getResult(ApiException::class.java)
} catch (ex: ApiException) {
when (ex.statusCode) {
LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> try {
Toast.makeText(this,"GPS IS OFF",Toast.LENGTH_SHORT).show()
// Show the dialog by calling startResolutionForResult(), and check the result
// in onActivityResult().
val resolvableApiException = ex as ResolvableApiException
resolvableApiException.startResolutionForResult(this,REQUEST_CHECK_SETTINGS
)
} catch (e: IntentSender.SendIntentException) {
Toast.makeText(this,"PendingIntent unable to execute request.",Toast.LENGTH_SHORT).show()
}
LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
Toast.makeText(
this,
"Something is wrong in your GPS",
Toast.LENGTH_SHORT
).show()
}
}
}
}
}
최근 Marshmallow 업데이트에서는 위치 설정이 켜져 있어도 앱에서 명시 적으로 권한을 요청해야합니다. 이를 위해 권장되는 방법은 사용자가 필요에 따라 권한을 전환 할 수있는 앱의 권한 섹션을 표시하는 것입니다. 이를위한 코드 스 니펫은 다음과 같습니다.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Location Permission");
builder.setMessage("The app needs location permissions. Please grant this permission to continue using the features of the app.");
builder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
}
});
builder.setNegativeButton(android.R.string.no, null);
builder.show();
}
} else {
// do programatically as show in the other answer
}
그리고 onRequestPermissionsResult
아래와 같이 메서드를 재정의합니다 .
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_COARSE_LOCATION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "coarse location permission granted");
} else {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
}
}
}
또 다른 접근 방식은 SettingsApi 를 사용하여 어떤 위치 공급자가 활성화되어 있는지 문의 할 수도 있습니다 . 활성화 된 항목이 없으면 앱 내에서 설정을 변경하라는 대화 상자를 표시 할 수 있습니다.
조사 중에 찾은 가장 간단한 방법은이 위치 요청 프로세스에 대한 Util 클래스를 만든 다음이를 호출하여 gps를 켜는 것입니다.
이 블로그를 확인하세요! 그것은 전체 이야기를 들려주었습니다.