簡體   English   中英

如何檢測用戶何時打開/關閉 GPS 狀態?

[英]How to detect when user turn on/off GPS state?

我想阻止用戶從我的應用程序更改 WiFi、GPS 和加載設置。 用戶在運行我的應用程序時不需要打開/關閉 WiFi 和 GPS。(來自通知欄)。 是否有任何BroadcastReceiver可以打開/關閉收聽 GPS?

好吧,我做了很多挖掘,發現 API 24 中不推薦使用addGpsStatusListener(gpsStatusListener) 。對我來說,這甚至不起作用! 所以,這是另一個替代解決方案。

如果在您的應用程序中,您想收聽 GPS 狀態變化(我的意思是用戶開/關) 使用廣播無疑是最好的方法。

執行:

/**
 * Following broadcast receiver is to listen the Location button toggle state in Android.
 */
private BroadcastReceiver mGpsSwitchStateReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {

        if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
            // Make an action or refresh an already managed state.
        }
    }
};

不要忘記在 Fragment/Activity Lifecycle 中有效地注冊和取消注冊。

registerReceiver(mGpsSwitchStateReceiver, new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION));

例如,如果您使用的是Fragment ,請在onResume注冊它並在onDestroy取消注冊。 此外,如果您將用戶引導至設置以啟用位置開關,則在onStop取消注冊將不起作用,因為您的活動將轉到onPause並且 Fragment 已停止。

這個解決方案可能有很多答案,但是這個很容易管理和使用。 提出您的解決方案(如果有)。

您可以使用 GpsStatus.Listener 監聽 GPS 狀態並將其注冊到 LocationManager。

LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.addGpsStatusListener(new android.location.GpsStatus.Listener()
{
    public void onGpsStatusChanged(int event)
    {
        switch(event)
        {
        case GPS_EVENT_STARTED:
            // do your tasks
            break;
        case GPS_EVENT_STOPPED:
            // do your tasks
            break;
        }
    }
});

您需要有權訪問上下文(例如在“活動”或“應用程序”類中)。

在您的活動的onResume()方法中收聽LocationManager.PROVIDERS_CHANGED_ACTION事件:

IntentFilter filter = new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION);
filter.addAction(Intent.ACTION_PROVIDER_CHANGED);
mActivity.registerReceiver(gpsSwitchStateReceiver, filter);

將此BroadcastReceiver實例添加到您的活動中:

private BroadcastReceiver gpsSwitchStateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
    
            if (LocationManager.PROVIDERS_CHANGED_ACTION.equals(intent.getAction())) {

                LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
                boolean isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
                boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

                if (isGpsEnabled || isNetworkEnabled) {
                    // Handle Location turned ON
                } else {
                    // Handle Location turned OFF
                }
            }
        }
    };

在您的活動的onPause()方法中取消注冊接收器:

mActivity.unregisterReceiver(gpsSwitchStateReceiver);

這不可能。 您無法隨心所欲地控制/限制硬件的狀態。 這在 API 中是很危險的,因此不存在這樣的 API。

Kotlin 中試試這個:

添加一個擴展BroadcastReceiver的類:

class GPSCheck(private val locationCallBack: LocationCallBack) :
    BroadcastReceiver() {
    interface LocationCallBack {
        fun turnedOn()
        fun turnedOff()
    }

    override fun onReceive(context: Context, intent: Intent) {
        val locationManager =
            context.getSystemService(LOCATION_SERVICE) as LocationManager
        if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) locationCallBack.turnedOn() else locationCallBack.turnedOff()
    }

}

然后作為示例使用它:

class MainActivity :AppCompatActivity(){

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        registerReceiver(GPSCheck(object : GPSCheck.LocationCallBack {
            override fun turnedOn() {
                Log.d("GpsReceiver", "is turned on")
            }

            override fun turnedOff() {
                Log.d("GpsReceiver", "is turned off")
            }
        }), IntentFilter(LocationManager.MODE_CHANGED_ACTION))
    }}

你可以注冊一個BroadcastReceiver來監聽Intent Action PROVIDERS_CHANGED_ACTION 這將在配置的位置提供程序更改時廣播。 你可以參考這個鏈接

您可以通過以下方式檢測 GPS 的狀態。

看看GpsStatus.Listener 使用 locationManager.addGpsStatusListener(gpsStatusListener) 注冊它。

另請檢查此 SO 鏈接以更好地理解。

我們可以使用LocationListener來知道 GPS 何時開啟和何時關閉。

class HomeActivity : AppCompatActivity() {
    private var locManager: LocationManager? = null
    private val locListener: LocationListener =
        object : LocationListener {
            override fun onLocationChanged(loc: Location) {
            }

            override fun onProviderEnabled(provider: String) {
                Log.d("abc", "enable")
            }

            override fun onProviderDisabled(provider: String) {
                Log.d("abc", "disable")
            }

            override fun onStatusChanged(
                provider: String,
                status: Int,
                extras: Bundle
            ) {
            }
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        locManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
    }

    override fun onResume() {
        super.onResume()
        startRequestingLocation()
    }

    override fun onStop() {
        super.onStop()
        try {
            locManager!!.removeUpdates(locListener)
        } catch (e: SecurityException) {
        }
    }

    private fun startRequestingLocation() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
            checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
        ) {
            requestPermissions(
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
                PERMISSION_REQUEST
            )
            return
        }
        locManager!!.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, locListener)
    }

    companion object {
        private const val PERMISSION_REQUEST = 1
    }
}

有關更多詳細信息,請參閱此項目: https : //github.com/pR0Ps/LocationShare

從 API 19 開始,您可以注冊一個BroadcastReceiver來監聽意圖操作LocationManager.MODE_CHANGED_ACTION

參考: https : //developer.android.com/reference/android/location/LocationManager.html#MODE_CHANGED_ACTION

您可以使用

try
{
    int locationMode = android.provider.Settings.Secure.getInt(context.getContentResolver(), android.provider.Settings.Secure.LOCATION_MODE);
} catch (android.provider.Settings.SettingNotFoundException e)
{
    e.printStackTrace();
}

返回的值應該是以下之一:

android.provider.Settings.Secure.LOCATION_MODE_BATTERY_SAVING
android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY
android.provider.Settings.Secure.LOCATION_MODE_OFF
android.provider.Settings.Secure.LOCATION_MODE_SENSORS_ONLY

您不能使用 GpsStatus.Listener 來執行此操作。 您必須使用廣播接收器。 使用 LocationManager.PROVIDERS_CHANGE_ACTION。 不使用 Intent.ACTION_PROVIDER_CHANE。 祝你好運 !

我為此目的使用android.location.LocationListener

`class MyOldAndroidLocationListener implements android.location.LocationListener {
    @Override public void onLocationChanged(Location location) { }

    //here are the methods you need
    @Override public void onStatusChanged(String provider, int status, Bundle extras) {}
    @Override public void onProviderEnabled(String provider) { }
    @Override public void onProviderDisabled(String provider) { }
}`

注意(來自文檔):如果 LocationListener 已使用LocationManager.requestLocationUpdates(String, long, float, LocationListener)方法注冊到位置管理器服務,則會調用這些方法

由於我將 Fused Location API 用於與位置相關的內容,因此我只是在requestLocationUpdates設置了long minTime = 1 小時, float minDistance = 1km,這對我的應用程序的開銷很小。

而且,當然,完成后不要忘記locationManager.removeUpdates

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM