24

我想阻止用户从我的应用程序中更改 WiFi、GPS 和加载设置。运行我的应用程序时,用户不需要打开/关闭 WiFi 和 GPS。(来自通知栏)。有没有BroadcastReceiver听GPS开/关的存在?

4

11 回答 11

36

好吧,我做了很多挖掘,发现它 addGpsStatusListener(gpsStatusListener)在 API 24 中已被弃用。对我来说,这甚至都行不通!因此,这是另一个替代解决方案。

如果在您的应用程序中,您想收听 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));

例如,如果您正在使用此 a Fragment,请在 中注册并在 中onResume取消注册onDestroy。此外,如果您将用户引导至启用位置开关的设置,则在其中取消注册onStop将不起作用,因为您的活动将进入onPause并且片段已停止。

这个解决方案可能有很多答案,但是这个解决方案很容易管理和使用。如果有的话,提出你的解决方案。

于 2016-09-26T12:23:32.370 回答
27

You can listen the GPS status with a GpsStatus.Listener and register it with the 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).

于 2013-04-03T04:51:19.273 回答
7

LocationManager.PROVIDERS_CHANGED_ACTION在您的活动方法中收听事件onResume()

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);
于 2019-03-08T09:12:22.570 回答
3

这是不可能的。您无法随心所欲地控制/限制硬件的状态。这在 API 中是很危险的,因此不存在这样的 API 是理所当然的。

于 2013-04-03T04:24:24.663 回答
3

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))
    }}
于 2020-06-08T04:44:03.977 回答
2

您可以注册一个BroadcastReceiver用于收听IntentAction PROVIDERS_CHANGED_ACTION。这将在配置的位置提供程序更改时广播。你可以参考这个链接

于 2013-04-03T04:41:05.967 回答
2

我们可以使用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

于 2020-06-10T11:36:16.007 回答
1

You can detect status of GPS by following way.

Look at GpsStatus.Listener. Register it with locationManager.addGpsStatusListener(gpsStatusListener).

Also check this SO link for better understanding.

于 2013-04-03T04:50:07.637 回答
0

从 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
于 2016-09-13T14:17:06.760 回答
-1

您不能使用 GpsStatus.Listener 来执行此操作。您必须使用广播接收器。使用 LocationManager.PROVIDERS_CHANGE_ACTION。不使用 Intent.ACTION_PROVIDER_CHANE。祝你好运 !

于 2014-12-03T11:48:46.977 回答
-1

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 来处理与位置相关的内容,因此我只需设置 long minTime= 1 小时 float minDistance= 1 公里,requestLocationUpdates 这对我的应用程序产生的开销非常小。

当然,完成后不要忘记locationManager.removeUpdates

于 2018-07-31T09:07:33.010 回答