在没有后台位置权限的情况下检测 Android AppWidget 的位置

Detect location for Android AppWidget without background location permission

我有一个应用程序可以提供所选位置的天气预报,其中包括一个小部件。作为一个选项,用户可以选择应用程序和小部件来显示设备所在位置的天气,这显然对用户来说是一个有用的功能。

为此,需要位置权限(至少 ACCESS_COARSE_LOCATION)。对于小部件,因为它(可选)更新每个,例如在后台运行一个小时,没有在前台打开应用程序,这需要授予后台位置权限 (ACCESS_BACKGROUND_LOCATION),以便在小部件更新时获取最新的设备位置。

但是由于 tightening of policy 生效,我的应用更新现在被 Google 拒绝了。显然我必须删除后台位置权限。这很遗憾,因为它 (a) 从用户的角度来看显然是一个有用的功能; (b) 完全可选……如果用户不想,则不必授予它……用户不会被迫进入它,并且有关于为什么小部件需要后台位置权限的解释。 .. 应用程序本身仍然可用(检测到位置)而无需授予后台位置权限。

有没有办法在没有 ACCESS_BACKGROUND_LOCATION 许可的情况下获取设备的位置以用于小部件?目前我正在使用以下方法获取 FusedLocationProviderClient 的位置:

FusedLocationProviderClient mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context);
mFusedLocationClient.getLastLocation().addOnCompleteListener(new LocationOnCompleteListener(context, listener, appWidgetId));

您是否尝试过在 Google Play 控制台中填写位置权限的权限声明表?

这是我的回答:(a) 在没有后台许可的情况下,无法获取设备的位置以用于小部件; (b) Google 正在失去其大量新政策的阴谋。

根据我从与 Google 的令人沮丧的电子邮件往来中收集到的信息,结果是任何具有 小部件 的应用程序都提供“使用设备位置”作为选项的功能(即完全可选...用户选择等等),否则使用用户选择的固定位置,现在必须将“使用设备位置”作为默认值,这样应用审核者就可以看到弹出的“显着披露”而无需进入菜单(启用该选项)...这样他们就可以在他们的审核清单中勾选这个特定的复选框。

显然,后台位置的使用也必须“对应用程序的主要目的至关重要”。因为它是一个 选项 (它可以打开或关闭),我想这意味着它不是“对应用程序的主要目的至关重要”。所以也许结果是这个有用的 选项 需要完全删除。或者我可能需要要求用户启用后台位置,即使他们不想要或不需要它?

用户选择发生了什么变化?相信用户会利用他们的智慧做出明智的选择?走了。

可选的解决方法(用户体验下降):

如果您为小部件内的内容提​​供 PendingIntentsetOnClickPendingIntent

remoteViews.setOnClickPendingIntent(R.id.button, createRefreshIntent(context, appWidgetId));

private static @NonNull PendingIntent createRefreshIntent(@NonNull Context context, int appWidgetId) {
    Intent intent = createUpdateIntent(context, appWidgetId);
    @SuppressLint("InlinedApi") // New flag shouldn't cause a problem in older versions.
    int flags = PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE;
    return PendingIntent.getBroadcast(context, appWidgetId, intent, flags);
}

private static @NonNull Intent createUpdateIntent(@NonNull Context context, @NonNull int... appWidgetIds) {
    Intent intent = new Intent(context, MyWidgetProvider.class);
    intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
    return intent;
}

这被认为是前台操作,您获得可以使用的权限。

所以如果用户一直点击“刷新”,那是前景,但如果你想每 30 分钟自动刷新一次,那是背景,这取决于用户是否碰巧盯着启动器屏幕。