有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Cordova 安卓后台插件在5分钟后被杀死

我正在开发一款带有位置跟踪功能的Cordova Android/iOS应用程序。 为了不断更新位置,我使用了一个后台地理位置插件(https://github.com/mauron85/cordova-plugin-background-geolocation

这个插件创建了一个服务来监听system LocationManager。 当系统得到位置更新时,插件触发事件链/一些计算,直到到达我在cordova应用程序中使用的最后一个JavaScript回调

它在iOS上运行得很好,从来不会被杀死,但我在安卓系统上遇到了麻烦,当你将手机置于睡眠状态(锁定屏幕)而应用程序不在前台时(假设你在锁定前切换到另一个应用程序)。 如果您移动(从而获得位置更新),该过程将保持运行。但是,如果您静止超过5分钟,后台位置服务将停止,不再向我的JS回调传递更多位置。 在此之后,如果您再次移动,服务将保持停止状态,直到您解锁屏幕并将应用程序带到前台

这很烦人,因为我的应用程序完全基于这种“走走停停”模式,需要在锁定的屏幕下运行(手机在口袋里),我的服务器会检查位置的时间戳,以筛选哪些位置被认为是在线的,哪些位置是新位置,哪些位置不是。 因此,我基本上需要两件事:当用户再次移动时,能够重新启动位置跟踪,如果用户空闲,则继续向我的服务器发送几个位置

根据我的研究,我最终创建了一个线程,该线程休眠60秒并循环返回,每分钟调用后台服务的handle position函数(该函数将位置发送到前台JS)。 不幸的是,我是新的科尔多瓦插件,并没有设法让它的工作。尝试访问应用程序上下文的systemService时出现空指针异常:

E/AndroidRuntime( 4627): java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object 安卓.content.Context.getSystemService(java.lang.String)' on a null object reference
E/AndroidRuntime( 4627):        at 安卓.content.ContextWrapper.getSystemService(ContextWrapper.java:583)
E/AndroidRuntime( 4627):        at com.tenforwardconsulting.cordova.bgloc.ForcedUpdateLocation.handleLocationFromOutside(ForcedUpdateLocation.java:12)
E/AndroidRuntime( 4627):        at com.tenforwardconsulting.cordova.bgloc.BackgroundGeolocationPlugin$3.run(BackgroundGeolocationPlugin.java:266)
E/AndroidRuntime( 4627):        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
E/AndroidRuntime( 4627):        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
E/AndroidRuntime( 4627):        at java.lang.Thread.run(Thread.java:818)

插件的启动功能:

public ComponentName startBackgroundService () {
    if (isEnabled) { return null; }
    Class serviceProviderClass = null;

    try {
        serviceProviderClass = ServiceProvider.getClass(config.getServiceProvider());
    } catch (ClassNotFoundException e) {
        callbackContext.error("Configuration error: provider not found");
        return null;
    }

    Activity activity = this.cordova.getActivity();
    Log.d(TAG, "Starting bg service");

    registerActionReceiver();
    locationServiceIntent = new Intent(activity, serviceProviderClass);
    locationServiceIntent.addFlags(Intent.FLAG_FROM_BACKGROUND);
    // locationServiceIntent.putExtra("config", config.toParcel().marshall());
    locationServiceIntent.putExtra("config", config);
    isEnabled = true;


    //Start a thread to send a position every 60s
    final ForcedUpdateLocation ful = new ForcedUpdateLocation();

    cordova.getThreadPool().execute(new Runnable(){
        public void run(){
            try {
                while(isEnabled){
                    Thread.sleep(3000);
                    Log.d(TAG, "Force location sent");

                    ful.handleLocationFromOutside();

                }
            } catch (InterruptedException e){
                Log.d(TAG, "EXCEPTION ! Force location sent", e);
            }
        }
    });


    return activity.startService(locationServiceIntent);
}

我的存根“ForcedUpdateLocation”服务扩展插件的LocationService(调用handleLocation):

package com.tenforwardconsulting.cordova.bgloc;

import 安卓.location.Location;
import 安卓.content.Context;
import 安卓.location.LocationManager;


public class ForcedUpdateLocation extends com.tenforwardconsulting.cordova.bgloc.AbstractLocationService {

    public void handleLocationFromOutside (){

        LocationManager locationMangerWakeThread = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        Location location = locationMangerWakeThread.getLastKnownLocation(locationMangerWakeThread.GPS_PROVIDER);

        handleLocation(location);
    }

    @Override
    protected void cleanUp(){
        //Stub
    };

    @Override
    protected void startRecording(){
        //Duh
    };

    @Override
    protected void stopRecording(){
        //Wouf ?
    };
}

除此之外,我发现这个解决方案真的很难看

那么,保持此服务运行的最佳方法是什么?是否有在后台保持长时间运行的空闲进程的最佳实践

非常感谢


共 (1) 个答案

  1. # 1 楼答案

    尝试使用此插件的“stopOnTerminate”和“startOnBoot”选项。 这将帮助你在后台不断获得更新,即使应用程序被操作系统杀死

    还请记住,您的callbk函数不会始终执行,因为如果您的应用程序被系统终止,这将终止您的活动和callbk。 因此,尝试使用插件的url选项,即使在后台也可以将您的位置发布到服务器上