简体   繁体   English

如何检测用户何时打开/关闭 GPS 状态?

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

I want to block the user from changing WiFi, GPS and loading settings from my application.我想阻止用户从我的应用程序更改 WiFi、GPS 和加载设置。 The user need not on/off WiFi and GPS while running my application.(From notification bar).用户在运行我的应用程序时不需要打开/关闭 WiFi 和 GPS。(来自通知栏)。 Is there any BroadcastReceiver exist for listening GPS on/off?是否有任何BroadcastReceiver可以打开/关闭收听 GPS?

Well I did a lot of digging and found that addGpsStatusListener(gpsStatusListener) was deprecated in API 24. And for me, this didn't even work!好吧,我做了很多挖掘,发现 API 24 中不推荐使用addGpsStatusListener(gpsStatusListener) 。对我来说,这甚至不起作用! So, here is another alternative solution to this.所以,这是另一个替代解决方案。

If in your app, you want to listen to the GPS state change (I mean On/Off by user) .如果在您的应用程序中,您想收听 GPS 状态变化(我的意思是用户开/关) Using a Broadcast surely is the best approach.使用广播无疑是最好的方法。

Implementation:执行:

/**
 * 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.
        }
    }
};

Don't forget to register and unregister this efficiently in Fragment/Activity Lifecycle as well.不要忘记在 Fragment/Activity Lifecycle 中有效地注册和取消注册。

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

For example, if you are using this a Fragment , register it in the onResume and unregister in the onDestroy .例如,如果您使用的是Fragment ,请在onResume注册它并在onDestroy取消注册。 Also, if you are directing user to the settings to enable the Location Switch, unregistering in the onStop will not function since, your activity goes to onPause and Fragment is stopped.此外,如果您将用户引导至设置以启用位置开关,则在onStop取消注册将不起作用,因为您的活动将转到onPause并且 Fragment 已停止。

Well there may be many answers for this solution but this one is easy to manage and use.这个解决方案可能有很多答案,但是这个很容易管理和使用。 Propose your solutions if any.提出您的解决方案(如果有)。

You can listen the GPS status with a GpsStatus.Listener and register it with the LocationManager.您可以使用 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;
        }
    }
});

You need to have access to the context (for example in an "Activity" or "Application" class).您需要有权访问上下文(例如在“活动”或“应用程序”类中)。

Listen to LocationManager.PROVIDERS_CHANGED_ACTION events in your activity's onResume() method:在您的活动的onResume()方法中收听LocationManager.PROVIDERS_CHANGED_ACTION事件:

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

Add this instance of BroadcastReceiver to your Activity:将此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
                }
            }
        }
    };

Unregister the receiver in your activity's onPause() method:在您的活动的onPause()方法中取消注册接收器:

mActivity.unregisterReceiver(gpsSwitchStateReceiver);

This is not possible.这不可能。 You can't control/restrict the state of the hardware on your whim.您无法随心所欲地控制/限制硬件的状态。 This would be dangerous to have in the APIs and rightfully so no such API exists.这在 API 中是很危险的,因此不存在这样的 API。

In Kotlin try this:Kotlin 中试试这个:

Add a class which extends BroadcastReceiver :添加一个扩展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()
    }

}

Then as an example use it this way:然后作为示例使用它:

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

You can register a BroadcastReceiver for listening to Intent Action PROVIDERS_CHANGED_ACTION .你可以注册一个BroadcastReceiver来监听Intent Action PROVIDERS_CHANGED_ACTION This will broadcast when the configured location provider changes.这将在配置的位置提供程序更改时广播。 You can refer this link .你可以参考这个链接

You can detect status of GPS by following way.您可以通过以下方式检测 GPS 的状态。

Look at GpsStatus.Listener .看看GpsStatus.Listener Register it with locationManager.addGpsStatusListener(gpsStatusListener).使用 locationManager.addGpsStatusListener(gpsStatusListener) 注册它。

Also check this SO link for better understanding.另请检查此 SO 链接以更好地理解。

We can use LocationListener to know when GPS is on and when it is off.我们可以使用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
    }
}

See this project for more details: https://github.com/pR0Ps/LocationShare有关更多详细信息,请参阅此项目: https : //github.com/pR0Ps/LocationShare

Starting from API 19 you can register a BroadcastReceiver for listening to intent action LocationManager.MODE_CHANGED_ACTION从 API 19 开始,您可以注册一个BroadcastReceiver来监听意图操作LocationManager.MODE_CHANGED_ACTION

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

You can get location mode with您可以使用

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

Value returned should be one of the following:返回的值应该是以下之一:

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

You cannot use GpsStatus.Listener to do this.您不能使用 GpsStatus.Listener 来执行此操作。 You must use broadcast receiver.您必须使用广播接收器。 Use LocationManager.PROVIDERS_CHANGE_ACTION.使用 LocationManager.PROVIDERS_CHANGE_ACTION。 Not use Intent.ACTION_PROVIDER_CHANE.不使用 Intent.ACTION_PROVIDER_CHANE。 Good luck !祝你好运 !

I'm using android.location.LocationListener for this purpose:我为此目的使用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) { }
}`

NOTE (from the docs ): These methods are called if the LocationListener has been registered with the location manager service using the LocationManager.requestLocationUpdates(String, long, float, LocationListener) method注意(来自文档):如果 LocationListener 已使用LocationManager.requestLocationUpdates(String, long, float, LocationListener)方法注册到位置管理器服务,则会调用这些方法

Since I use Fused Location API for location-related stuff, I just set long minTime = 1 hour, float minDistance = 1km, in requestLocationUpdates and this results in very little overhead to my app.由于我将 Fused Location API 用于与位置相关的内容,因此我只是在requestLocationUpdates设置了long minTime = 1 小时, float minDistance = 1km,这对我的应用程序的开销很小。

And, of course, don't forget to locationManager.removeUpdates when you're done.而且,当然,完成后不要忘记locationManager.removeUpdates

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM