如何将android webview保持在后台(使用位置)

Posted

技术标签:

【中文标题】如何将android webview保持在后台(使用位置)【英文标题】:How to keep android webview in the background (using the location) 【发布时间】:2021-11-02 16:35:28 【问题描述】:

我在 android Studio 中制作的 webview 中有一个 PWA,只要用户有互联网、gps 和前台应用程序,它就可以完美地获取用户的位置。

我的问题是当他们最小化或关闭应用程序时。我需要继续收集用户的位置。

我的 webview 有什么方法可以让我的 PWA 在后台或应用关闭时继续收集位置?

【问题讨论】:

一般来说,在 Android 上,您需要用户同意后台位置收集。当您请求位置权限时,用户可以选择仅在应用处于前台时授予它,并且无法覆盖它。 【参考方案1】:

您应该使用带有部分唤醒锁的前台服务,以防止手机进入休眠状态。 下面是实现唤醒锁的前台服务类示例:

public class ICService extends Service 
    
    private static final int ID = 1;                        // The id of the notification
    
    private NotificationCompat.Builder builder;
    private NotificationManager mNotificationManager;
    private PowerManager.WakeLock wakeLock;                 // PARTIAL_WAKELOCK
    
    /**
     * Returns the instance of the service
     */
    public class LocalBinder extends Binder 
        public ICService getServiceInstance()
            return ICService.this;
        
    
    private final IBinder mBinder = new LocalBinder();      // IBinder
    
    @Override
    public void onCreate() 
        super.onCreate();
        // PARTIAL_WAKELOCK
        PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"INSERT_YOUR_APP_NAME:wakelock");
    
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) 
        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        startForeground(ID, getNotification());
        return START_NOT_STICKY;
    
    
    @SuppressLint("WakelockTimeout")
    @Override
    public IBinder onBind(Intent intent) 
        if (wakeLock != null && !wakeLock.isHeld()) 
            wakeLock.acquire();
        
        return mBinder;
    
    
    @Override
    public void onDestroy() 
        // PARTIAL_WAKELOCK
        if (wakeLock != null && wakeLock.isHeld()) 
            wakeLock.release();
        
        super.onDestroy();
    

    private Notification getNotification() 
        final String CHANNEL_ID = "YOUR_SERVICE_CHANNEL";

        builder = new NotificationCompat.Builder(this, CHANNEL_ID);
        //builder.setSmallIcon(R.drawable.ic_notification_24dp)
        builder.setSmallIcon(R.mipmap.YOUR_RESOURCE_ICON)
            .setColor(getResources().getColor(R.color.colorPrimaryLight))
            .setContentTitle(getString(R.string.app_name))
            .setShowWhen(false)
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .setCategory(NotificationCompat.CATEGORY_SERVICE)
            .setOngoing(true)
            .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
            .setContentText(composeContentText());

        final Intent startIntent = new Intent(getApplicationContext(), ICActivity.class);
        startIntent.setAction(Intent.ACTION_MAIN);
        startIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        startIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
        PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 1, startIntent, 0);
        builder.setContentIntent(contentIntent);
        return builder.build();
    

显然,您还必须为您的应用禁用电池优化。 您可以浏览此服务的真实工作示例here。

不要忘记在您的AndroidManifest.xml 中将您的服务类型声明为“位置”,以便在后台运行时出现瞬间信号丢失后,该服务也可以接收 GPS 更新:

<!-- Recommended for Android 9 (API level 28) and lower. -->
<!-- Required for Android 10 (API level 29) and higher. -->
<service
    android:name="MyGPSService"
    android:foregroundServiceType="location" ... >
    <!-- Any inner elements would go here. -->
</service>

请注意,一旦在前台访问 GPS,则无需请求android.permission.ACCESS_BACKGROUND_LOCATION 权限以继续在后台接收位置:android.permission.ACCESS_FINE_LOCATION(如果您使用 API31+,则还需要android.permission.ACCESS_COARSE_LOCATION)够你用了。

【讨论】:

以上是关于如何将android webview保持在后台(使用位置)的主要内容,如果未能解决你的问题,请参考以下文章

使WKWebView在后台保持不变,同时显示另一个视图

软键盘出现时如何保持Android webview中的固定页脚不覆盖输入字段?

Webview从android后台加载数据?

JavaFX WebView:透明WebView保持绘制旧内容

Android 后台任务执行

如何在 Android O 中保持服务在后台运行?