如何检查是否启用了定位服务?


228

我正在Android操作系统上开发应用程序。我不知道如何检查位置服务是否已启用。

我需要一个方法,如果启用它们,则返回“ true”,否则未返回“ false”(因此,在最后一种情况下,我可以显示一个对话框来启用它们)。


3
我知道这是一个古老的话题,但是对于那些可能会关注的人……Google已为此发布了API;参见developers.google.com/android/reference/com/google/android/gms/…–
彼得·麦克伦南


仅供参考:SettingsApi现在已弃用。请改用developers.google.com/android/reference/com/google/android/gms/…
拉吉夫

Answers:


361

您可以使用以下代码检查是否启用了gps提供程序和网络提供程序。

LocationManager lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
boolean gps_enabled = false;
boolean network_enabled = false;

try {
    gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch(Exception ex) {}

try {
    network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch(Exception ex) {}

if(!gps_enabled && !network_enabled) {
    // notify user
    new AlertDialog.Builder(context)
        .setMessage(R.string.gps_network_not_enabled)
        .setPositiveButton(R.string.open_location_settings, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                context.startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
            }
        }
        .setNegativeButton(R.string.Cancel,null)
        .show();    
}

在清单文件中,您需要添加以下权限

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

谢谢你的代码。检查位置管理器:(lm.getAllProviders().contains(LocationManager.GPS_PROVIDER)NETWORK_PROVIDER)将确保您不要将用户扔到没有网络选项的设置页面。
彼得

26
另外:Settings.ACTION_SECURITY_SETTINGS应该是Settings.ACTION_LOCATION_SOURCE_SETTINGS
petter

2
您可以检查一下手机是否处于飞行模式并进行处理。... stackoverflow.com/questions/4319212/…–
John

2
lm.isProviderEnabled(LocationManager.GPS_PROVIDER)出现了一些问题,该问题过去总是返回false。当您使用新版本的Play服务时,似乎会发生这种情况:该对话框会显示一个对话框,您可以从该对话框中直接打开gps,而不会显示设置活动。当用户从该对话框中打开gps时,即使gps处于打开状态,该语句也始终返回false
Marcelo Noguti 2015年

7
也不应放置空的,混乱的,无用的try-catch块
Chisko

225

我使用以下代码进行检查:

public static boolean isLocationEnabled(Context context) {
    int locationMode = 0;
    String locationProviders;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
        try {
            locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);

        } catch (SettingNotFoundException e) {
            e.printStackTrace();
            return false;
        }

        return locationMode != Settings.Secure.LOCATION_MODE_OFF;

    }else{
        locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
        return !TextUtils.isEmpty(locationProviders);
    }


} 

7
为了清楚起见,可能希望在catch块中返回false。否则,将locationMode初始化为Settings.Secure.LOCATION_MODE_OFF。
RyanLeonard

2
这是一个很好的答案,因为它可以与新旧Android位置API一起使用。
Diederik 2015年

2
LOCATION_PROVIDERS_ALLOWED- 链接在API级别19中已弃用该常量。我们必须使用LOCATION_MODE和MODE_CHANGED_ACTION(或PROVIDERS_CHANGED_ACTION)
Choletski,2015年

3
该答案应被接受为正确答案。locationManager.isProviderEnabled()方法在我的4.4设备上不可靠(而且我看到其他开发人员在其他OS版本上也遇到了同样的问题)。就我而言,在每种情况下,它对于GPS均返回true(是否启用了定位服务都没有关系)。感谢您提供的出色解决方案!
strongmayer

2
这在我的测试设备Samsung SHV-E160K,android 4.1.2,API 16上不起作用。尽管我使GPS脱机,但此功能仍返回true。我在Android Nougat,API 7.1上进行了测试,它可以正常工作
HendraWD

37

就像现在的2020年

最新,最好和最短的方法是

public static Boolean isLocationEnabled(Context context)
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
// This is new method provided in API 28
            LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
            return lm.isLocationEnabled();
        } else {
// This is Deprecated in API 28
            int mode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE,
                    Settings.Secure.LOCATION_MODE_OFF);
            return  (mode != Settings.Secure.LOCATION_MODE_OFF);

        }
    }

1
优秀的 !但更重要的,摆脱铸造和直接传递LocationManager.classgetSystemService方法,因为调用需要API 23 ;-)
Mackovich

6
或者,您可以改用LocationManagerCompat。:)
Mokkun

使用return lm!= null && lm.isLocationEnabled(); 而不是返回lm.isLocationEnabled();
Dr. DS

35

您可以使用以下代码将用户定向到“设置”,他们可以在其中启用GPS:

    locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
    if( !locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) ) {
        new AlertDialog.Builder(context)
            .setTitle(R.string.gps_not_found_title)  // GPS not found
            .setMessage(R.string.gps_not_found_message) // Want to enable?
            .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialogInterface, int i) {
                    owner.startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                }
            })
            .setNegativeButton(R.string.no, null)
            .show();
    }

1
非常感谢,但我不需要代码来检查GPS,而只需定位服务即可。
Meroelyth

1
位置服务始终可用,但其他提供程序可能不可用。
lenik 2012年

4
@lenik,某些设备提供了一个设置(在“设置>个人>位置服务>访问我的位置”下),即使启用了特定的提供程序,该设置也似乎完全启用/禁用了位置检测。我亲眼看到这是我正在测试的手机,即使同时启用了Wifi和GPS,它们对我的应用程序来说似乎已经死了。不幸的是,自那以后我启用了该设置,即使禁用了“访问我的位置”设置,也无法重现原始方案。因此,我无法确定该设置是否影响isProviderEnabled()getProviders(true)方法。
Awnry熊,2014年

...我只是想把那个扔出去,以防其他人遇到同样的问题。我之前从未在经过测试的其他设备上看到过该设置。这似乎是整个系统范围内的位置检测终止开关。如果任何人有关于如何在任何经验isProviderEnabled()getProviders(true)方法响应时启用这样的设置(或禁用,这取决于你如何看待它),我会大为好奇,想知道你遇到了什么。
Awnry熊,2014年

25

迁移到Android X并使用

implementation 'androidx.appcompat:appcompat:1.1.0'

并使用LocationManagerCompat

在java中

private boolean isLocationEnabled(Context context) {
    LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
    return LocationManagerCompat.isLocationEnabled(locationManager);
}

在科特林

private fun isLocationEnabled(context: Context): Boolean {
    val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
    return LocationManagerCompat.isLocationEnabled(locationManager)
}

此功能适用于Android 1.0以后的所有Android版本。但是请注意,Before API version LOLLIPOP [API Level 21], this method would throw SecurityException if the location permissions were not sufficient to use the specified provider.因此,如果您没有网络或gps提供程序的权限,则它可能会引发异常,具体取决于启用了哪个功能。查看源代码以获取更多信息。
xuiqzy

15

解决以上问题的答案,在API 23中,您需要添加“危险”权限检查以及检查系统本身:

public static boolean isLocationServicesAvailable(Context context) {
    int locationMode = 0;
    String locationProviders;
    boolean isAvailable = false;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
        try {
            locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
        }

        isAvailable = (locationMode != Settings.Secure.LOCATION_MODE_OFF);
    } else {
        locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
        isAvailable = !TextUtils.isEmpty(locationProviders);
    }

    boolean coarsePermissionCheck = (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED);
    boolean finePermissionCheck = (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED);

    return isAvailable && (coarsePermissionCheck || finePermissionCheck);
}

无法解析符号Manifest.permission.ACCESS_COARSE_LOCATION和Manifest.permission.ACCESS_FINE_LOCATION
Gennady Kozlov

使用android.Manifest.permission.ACCESS_FINE_LOCATION
aLIEz

7

如果未启用任何提供程序,则“被动”是返回的最佳提供程序。参见https://stackoverflow.com/a/4519414/621690

    public boolean isLocationServiceEnabled() {
        LocationManager lm = (LocationManager)
                this.getSystemService(Context.LOCATION_SERVICE);
        String provider = lm.getBestProvider(new Criteria(), true);
        return (StringUtils.isNotBlank(provider) &&
                !LocationManager.PASSIVE_PROVIDER.equals(provider));
    }

7

是的,您可以检查以下代码:

public boolean isGPSEnabled(Context mContext) 
{
    LocationManager lm = (LocationManager)
    mContext.getSystemService(Context.LOCATION_SERVICE);
    return lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
}

清单文件中的权限:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

6

我认为,此if子句可以轻松检查位置服务是否可用:

LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if(!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) && !locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
        //All location services are disabled

}

4

我对NETWORK_PROVIDER使用了这种方法,但是您可以为GPS添加和。

LocationManager locationManager;

onCreate中,我将

   isLocationEnabled();
   if(!isLocationEnabled()) {
        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
        builder.setTitle(R.string.network_not_enabled)
                .setMessage(R.string.open_location_settings)
                .setPositiveButton(R.string.yes,
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                            }
                        })
                .setNegativeButton(R.string.cancel,
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                dialog.cancel();
                            }
                        });
        AlertDialog alert = builder.create();
        alert.show();
    } 

和检查方法

protected boolean isLocationEnabled(){
    String le = Context.LOCATION_SERVICE;
    locationManager = (LocationManager) getSystemService(le);
    if(!locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
        return false;
    } else {
        return true;
    }
}

2
您不需要if-then-else,就可以返回locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
LadyWoodi

4

这是一个非常有用的方法,true如果Location services启用,它会返回“ ” :

public static boolean locationServicesEnabled(Context context) {
        LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        boolean gps_enabled = false;
        boolean net_enabled = false;

        try {
            gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
        } catch (Exception ex) {
            Log.e(TAG,"Exception gps_enabled");
        }

        try {
            net_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        } catch (Exception ex) {
            Log.e(TAG,"Exception network_enabled");
        }
        return gps_enabled || net_enabled;
}

3

要在android谷歌地图中获取当前地理位置,您应该打开设备位置选项。要检查该位置是否开启,您可以从onCreate()方法中简单地调用此方法。

private void checkGPSStatus() {
    LocationManager locationManager = null;
    boolean gps_enabled = false;
    boolean network_enabled = false;
    if ( locationManager == null ) {
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    }
    try {
        gps_enabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    } catch (Exception ex){}
    try {
        network_enabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    } catch (Exception ex){}
    if ( !gps_enabled && !network_enabled ){
        AlertDialog.Builder dialog = new AlertDialog.Builder(MyActivity.this);
        dialog.setMessage("GPS not enabled");
        dialog.setPositiveButton("Ok", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                //this will navigate user to the device location settings screen
                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                startActivity(intent);
            }
        });
        AlertDialog alert = dialog.create();
        alert.show();
    }
}

3

对于科特林

 private fun isLocationEnabled(mContext: Context): Boolean {
    val lm = mContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
    return lm.isProviderEnabled(LocationManager.GPS_PROVIDER) || lm.isProviderEnabled(
            LocationManager.NETWORK_PROVIDER)
 }

对话

private fun showLocationIsDisabledAlert() {
    alert("We can't show your position because you generally disabled the location service for your device.") {
        yesButton {
        }
        neutralPressed("Settings") {
            startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS))
        }
    }.show()
}

这样叫

 if (!isLocationEnabled(this.context)) {
        showLocationIsDisabledAlert()
 }

提示:对话框需要以下导入(android studio应该为您处理)

import org.jetbrains.anko.alert
import org.jetbrains.anko.noButton

在清单中,您需要以下权限

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

2

您可以请求位置更新并一起显示对话框,例如GoogleMaps doas。这是代码:

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); //this is the key ingredient

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:
                // 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(getActivity(), 1000);
                } catch (IntentSender.SendIntentException ignored) {}
                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;
            }
        }
    });
}

如果您需要更多信息,请检查LocationRequest类。


您好,自最近两天以来,我一直在努力获取用户的当前位置。我需要该用户当前的时长,我知道可以使用google api客户端来完成。但是如何在其中集成棉花糖权限。另外,如果关闭了用户的位置服务,则如何启用它。你能帮我吗?
Chetna'9

嗨!您有很多问题,我无法在评论中回答。请提出一个新问题,以便我可以更正式地回答!
bentaf

我已经张贴在这里我的问题:stackoverflow.com/questions/39327480/...
Chetna

2

我使用第一个代码开始创建方法isLocationEnabled

 private LocationManager locationManager ;

protected boolean isLocationEnabled(){
        String le = Context.LOCATION_SERVICE;
        locationManager = (LocationManager) getSystemService(le);
        if(!locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
            return false;
        } else {
            return true;
        }
    }

我检查条件是否成功打开地图,然后给与错误的意图ACTION_LOCATION_SOURCE_SETTINGS

    if (isLocationEnabled()) {
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        locationClient = getFusedLocationProviderClient(this);
        locationClient.getLastLocation()
                .addOnSuccessListener(new OnSuccessListener<Location>() {
                    @Override
                    public void onSuccess(Location location) {
                        // GPS location can be null if GPS is switched off
                        if (location != null) {
                            onLocationChanged(location);

                            Log.e("location", String.valueOf(location.getLongitude()));
                        }
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Log.e("MapDemoActivity", e.toString());
                        e.printStackTrace();
                    }
                });


        startLocationUpdates();

    }
    else {
        new AlertDialog.Builder(this)
                .setTitle("Please activate location")
                .setMessage("Click ok to goto settings else exit.")
                .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        startActivity(intent);
                    }
                })
                .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        System.exit(0);
                    }
                })
                .show();
    }

在此处输入图片说明


1

可以用最简单的方式做

private boolean isLocationEnabled(Context context){
int mode =Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE,
                        Settings.Secure.LOCATION_MODE_OFF);
                final boolean enabled = (mode != android.provider.Settings.Secure.LOCATION_MODE_OFF);
return enabled;
}

1

如果您使用的是AndroidX,请使用以下代码检查位置服务是否已启用:

fun isNetworkServiceEnabled(context: Context) = LocationManagerCompat.isLocationEnabled(context.getSystemService(LocationManager::class.java))

0

要检查网络提供者,如果您同时检查GPS提供者和NETwork提供者的返回值,则只需将传递给isProviderEnabled的字符串更改为LocationManager.NETWORK_PROVIDER-两者均为false表示没有位置服务


0
private boolean isGpsEnabled()
{
    LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
    return service.isProviderEnabled(LocationManager.GPS_PROVIDER)&&service.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}

0
    LocationManager lm = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
    boolean gps_enabled = false;
    boolean network_enabled = false;

    try {
        gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
    } catch(Exception e){
         e.printStackTrace();
    }

    try {
        network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    } catch(Exception e){
         e.printStackTrace();
    }

    if(!gps_enabled && !network_enabled) {
        // notify user
        new AlertDialog.Builder(this)
                .setMessage("Please turn on Location to continue")
                .setPositiveButton("Open Location Settings", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                        startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                    }

                }).
                setNegativeButton("Cancel",null)
                .show();
    }

0
public class LocationUtil {
private static final String TAG = LocationUtil.class.getSimpleName();

public static LocationManager getLocationManager(final Context context) {
    return (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
}

public static boolean isNetworkProviderEnabled(final Context context) {
    return getLocationManager(context).isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}

public static boolean isGpsProviderEnabled(final Context context) {
    return getLocationManager(context).isProviderEnabled(LocationManager.GPS_PROVIDER);
}

// Returns true even if the location services are disabled. Do not use this method to detect location services are enabled.
private static boolean isPassiveProviderEnabled(final Context context) {
    return getLocationManager(context).isProviderEnabled(LocationManager.PASSIVE_PROVIDER);
}

public static boolean isLocationModeOn(final Context context) throws Exception {
    int locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
    return locationMode != Settings.Secure.LOCATION_MODE_OFF;
}

public static boolean isLocationEnabled(final Context context) {
    try {
        return isNetworkProviderEnabled(context) || isGpsProviderEnabled(context)  || isLocationModeOn(context);
    } catch (Exception e) {
        Log.e(TAG, "[isLocationEnabled] error:", e);
    }
    return false;
}

public static void gotoLocationSettings(final Activity activity, final int requestCode) {
    Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
    activity.startActivityForResult(intent, requestCode);
}

public static String getEnabledProvidersLogMessage(final Context context){
    try{
        return "[getEnabledProvidersLogMessage] isNetworkProviderEnabled:"+isNetworkProviderEnabled(context) +
                ", isGpsProviderEnabled:" + isGpsProviderEnabled(context) +
                ", isLocationModeOn:" + isLocationModeOn(context) +
                ", isPassiveProviderEnabled(ignored):" + isPassiveProviderEnabled(context);
    }catch (Exception e){
        Log.e(TAG, "[getEnabledProvidersLogMessage] error:", e);
        return "provider error";
    }
}

}

使用isLocationEnabled方法检测启用的位置服务。

https://github.com/Polidea/RxAndroidBle/issues/327#页面将提供更多信息,为什么不使用被动提供程序,而是使用位置模式。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.