如何在GPS打开/关闭时触发广播接收器?

45
public class BootReceiver extends BroadcastReceiver  {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
            Toast.makeText(context, "in android.location.PROVIDERS_CHANGED",
                Toast.LENGTH_SHORT).show();
            Intent pushIntent = new Intent(context, LocalService.class);
            context.startService(pushIntent);
        } else {
            Toast.makeText(context, "not in android.location.PROVIDERS_CHANGED",
                Toast.LENGTH_SHORT).show();
            Intent pushIntent = new Intent(context, LocalService.class);
            context.startService(pushIntent);
        }
    }

    @Override
    public void onLocationChanged(Location arg0) {

    }
}

在我的应用中,当GPS打开/关闭时,我需要触发广播接收器。请查看此问题并建议最佳实现方法。


1
你是否正在尝试监听位置模式的设置: “仅设备(使用GPS确定您的位置)”? - IgorGanapolsky
5个回答

76

当用户想要触发开启/关闭位置信息时,这将非常有用。

您应该将此操作添加到清单中。

<action android:name="android.location.PROVIDERS_CHANGED" />

添加此操作后,您可以触发广播接收器。

<receiver android:name=".GpsLocationReceiver">
    <intent-filter>
        <action android:name="android.location.PROVIDERS_CHANGED" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</receiver>

在你的BroadcastReceiver类中,你需要实现下面给出的LocationListener接口。

public class GpsLocationReceiver extends BroadcastReceiver {        
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
            Toast.makeText(context, "in android.location.PROVIDERS_CHANGED",
            Toast.LENGTH_SHORT).show();
            Intent pushIntent = new Intent(context, LocalService.class);
            context.startService(pushIntent);
        }
    }
}

1
你有关于屏幕旋转广播接收器的解决方案吗?请帮忙。 - Ashish Sahu
3
为什么我需要在这里实现LocationListener? - Kartihkraj Duraisamy
@Kartihkraj... 不需要在这里实现LocationListener.. 我已经进行了编辑。 - Deepak Gupta
15
这段代码如何告诉你位置模式是开启还是关闭? - IgorGanapolsky
4
除了广播接收器的意图过滤器之外,在哪里添加<action android:name="android.location.PROVIDERS_CHANGED" />? - Mahendra Chhimwal

42

我想添加 @Deepak Gupta 回答

我想在你的 fragmentactivity 中添加代码,以注册动态广播接收器当 GPS 状态改变时。

在你的 activity 或 fragment 中,按照如下方式注册你的广播接收器。

private BroadcastReceiver gpsReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().matches(LocationManager.PROVIDERS_CHANGED_ACTION)) {
            //Do your stuff on GPS status change
        }
    }
};

对于片段(fragment)

getContext().registerReceiver(gpsReceiver, new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION));

对于活动

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

这可以在任何有上下文(Context)访问权限的地方使用,不仅限于活动(Activity)或片段(Fragment)内部。希望对你有所帮助。


2
不需要硬编码动作字符串。而是使用 ...matches(LocationManager.PROVIDERS_CHANGED_ACTION)...new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION) - tir38
谢谢@tir38,我已经使用LocationManager.PROVIDERS_CHANGED_ACTION更新了我的答案。 - pRaNaY
registerReceiver是什么?@pRaNaY - CodeAlo
1
这是一种用于注册BroadcastReceiver的活动方法。请查看https://developer.android.com/reference/android/content/Context.html。 - pRaNaY
这还能用吗?我好像无法在LocationManager.PROVIDERS_CHANGED_ACTION上接收广播。 - Sid
使用这个,我们无法知道它是开启还是关闭的。 - nayan dhabarde

14

你可以尝试这段代码,正如用户@DanielNugent所指出的:

    ContentResolver contentResolver = getContext().getContentResolver();
    // Find out what the settings say about which providers are enabled
    int mode = Settings.Secure.getInt(
            contentResolver, Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);

    if (mode != Settings.Secure.LOCATION_MODE_OFF) {
      if (mode == Settings.Secure.LOCATION_MODE_HIGH_ACCURACY) {
        locationMode = "High accuracy. Uses GPS, Wi-Fi, and mobile networks to determine location";
      } else if (mode == Settings.Secure.LOCATION_MODE_SENSORS_ONLY) {
          locationMode = "Device only. Uses GPS to determine location";
      } else if (mode == Settings.Secure.LOCATION_MODE_BATTERY_SAVING) {
          locationMode = "Battery saving. Uses Wi-Fi and mobile networks to determine location";
      }
    }

1
你的答案非常好,但它只适用于Android API 19及以上版本。有没有适用于低于19版本的方法? - Joshua
在 API 级别 28 中,设置常量已被弃用。 - Greg Dan

0

在 Android 引入位置模式后的工作解决方案

我们可以通过位置模式进行更精确的检查。

private boolean isGpsEnabled(Context context) {
            ContentResolver contentResolver = getContext().getContentResolver();
            // Find out what the settings say about which providers are enabled
            //  String locationMode = "Settings.Secure.LOCATION_MODE_OFF";
            int mode = Settings.Secure.getInt(
                    contentResolver, Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
            if (mode != Settings.Secure.LOCATION_MODE_OFF) {
                return true;
               /* if (mode == Settings.Secure.LOCATION_MODE_HIGH_ACCURACY) {
                    locationMode = "High accuracy. Uses GPS, Wi-Fi, and mobile networks to determine location";
                } else if (mode == Settings.Secure.LOCATION_MODE_SENSORS_ONLY) {
                    locationMode = "Device only. Uses GPS to determine location";
                } else if (mode == Settings.Secure.LOCATION_MODE_BATTERY_SAVING) {
                    locationMode = "Battery saving. Uses Wi-Fi and mobile networks to determine location";
                }*/
            } else {
                return false;
            }
        }

-3
你可以试试这个。

清单

<receiver android:name=".MyReceiver">
        <intent-filter>
            <action android:name="android.location.GPS_ENABLED_CHANGE" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>

MyReceiver

if (intent.getAction().matches("android.location.GPS_ENABLED_CHANGE"))
    {
        boolean enabled = intent.getBooleanExtra("enabled",false);

        Toast.makeText(context, "GPS : " + enabled,
                Toast.LENGTH_SHORT).show();
    }

Intent 总是为空。不包含任何类似于 enabled 的内容。 - Math10

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接