Android 4.0 (API 14) 起,安全策略收緊,**第三方 App 無法直接程序化開啟/關閉 GPS**,需用戶手動在系統設置中操作。舊代碼 (發送 GPS_ENABLED_CHANGE 廣播) 在高版本失效甚至崩潰。
public void openGpsSettings() {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
// 或更精確:直接跳轉到「位置」開關頁面 (API 19+)
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
public boolean isGpsEnabled(Context context) {
LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
return lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
// 使用
if (!isGpsEnabled(this)) {
new AlertDialog.Builder(this)
.setTitle("GPS 未開啟")
.setMessage("請開啟 GPS 以使用定位功能")
.setPositiveButton("去設置", (d, w) -> openGpsSettings())
.setNegativeButton("取消", null)
.show();
}
// 這段代碼在 Android 4.0+ 失效/危險
Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", true);
sendBroadcast(intent); // 需簽名權限 WRITE_SECURE_SETTINGS,第三方無法獲取
// 甚至嘗試發送 Settings AppWidget 廣播 (極不推薦)
Intent poke = new Intent();
poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
poke.setData(Uri.parse("3"));
sendBroadcast(poke); // 依賴系統內部實現,極不穩定
// 依賴: implementation 'com.google.android.gms:play-services-location:21.0.1'
FusedLocationProviderClient fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
LocationRequest locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10000)
.setFastestInterval(5000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
SettingsClient settingsClient = LocationServices.getSettingsClient(this);
Task task = settingsClient.checkLocationSettings(builder.build());
task.addOnSuccessListener(this, response -> {
// GPS 已滿足精度要求,可直接請求定位
startLocationUpdates();
});
task.addOnFailureListener(this, e -> {
if (e instanceof ResolvableApiException) {
// 彈出系統標準對話框,引導用戶一鍵開啟 GPS/位置模式
try {
ResolvableApiException resolvable = (ResolvableApiException) e;
resolvable.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException ex) {
// 忽略
}
}
});
| Android 版本 | 程序開啟 GPS | 推薦方案 |
|---|---|---|
| < 4.0 (API < 14) | 可 (發送廣播/修改 Settings.Secure) | 已淘汰 |
| 4.0 - 5.1 (API 14-22) | 不可 | 跳轉 Settings.ACTION_LOCATION_SOURCE_SETTINGS |
| 6.0 - 9.0 (API 23-28) | 不可 | 運行時權限 + 跳轉設置 / LocationSettingsRequest |
| 10.0+ (API 29+) | 不可 | LocationSettingsRequest + 後台定位權限適配 |