首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 4.0+ 程序化開啟 GPS:權限變更與 Intent 方案適配

     編輯:程式設計綜合問答

背景

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);

檢查 GPS 是否已開啟


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); // 依賴系統內部實現,極不穩定

現代最佳實踐:Google Play Services Location API


// 依賴: 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) {
            // 忽略
        }
    }
});

權限聲明 (AndroidManifest.xml)








版本適配總結表

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 + 後台定位權限適配

核心原則

  1. 尊重用戶隱私:系統強制要求用戶手動授權開啟 GPS
  2. 使用 LocationSettingsRequest:系統標準彈窗,用戶信任度高、一鍵解決
  3. 優雅降級:GPS 不可用時嘗試網絡定位 (FusedLocationProvider 自動處理)
  4. 不要嘗試繞過系統限制:反射/廣播/Root 方案極不穩定,上架會被拒
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved