Workmanager(定期)获取位置并上传数据(Asynctask)被杀死

Posted

技术标签:

【中文标题】Workmanager(定期)获取位置并上传数据(Asynctask)被杀死【英文标题】:Workmanager (periodic) get location and upload data (Asynctask ) get killed 【发布时间】:2019-12-02 12:21:53 【问题描述】:

当手机处于睡眠模式时,Workmanager 不会将坐标发送到我的服务器。异步任务被杀死?

我使用 Workmanager (PeriodicWorkRequest) 每 15 分钟获取一次坐标。要获取坐标,我使用 FusedLocationClient。这很好......但我也想将它们发送到我的服务器。

如果我开始发送“public void onComplete”(参见代码),我必须使用 AsyncTask(其他解决方案??)。当我的手机未处于睡眠模式时,它可以工作。目的是发送继续运行。我该如何解决这个问题(新手,例子让我很高兴:))

MainActivity 启动 Workmanager

 public static void scheduleWork(String tag) 
        PeriodicWorkRequest.Builder SendLocation =
                new PeriodicWorkRequest.Builder(LocationWorker.class, 15,
                        TimeUnit.MINUTES);
        PeriodicWorkRequest locationCheckWork = SendLocation.build();
        WorkManager instance = WorkManager.getInstance();
        instance.enqueueUniquePeriodicWork(tag, ExistingPeriodicWorkPolicy.KEEP , locationCheckWork);
    

LocationWorker

@NonNull
    @Override
    public Result doWork() 
        Log.d(TAG, "onStartJob: STARTING JOB..");

        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(mContext);
        mLocationCallback = new LocationCallback() 
            @Override
            public void onLocationResult(LocationResult locationResult) 
                super.onLocationResult(locationResult);
            
        ;

        LocationRequest mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        try 
            mFusedLocationClient
                    .getLastLocation()
                    .addOnCompleteListener(new OnCompleteListener<Location>() 
                        @Override
                        public void onComplete(@NonNull Task<Location> task) 
                            if (task.isSuccessful() && task.getResult() != null) 
                                mLocation = task.getResult();
                                Log.d(TAG, "Location : " + mLocation);

                                double latitude = mLocation.getLatitude();
                                double longitude = mLocation.getLongitude();
                                // SEND TO SERVER
                                AsyncTask.execute(new Runnable()
                                
                                    @Override
                                    public void run() 
                                        HttpURLConnection connection;
                                        try 
                                            //Open a new URL connection
                                            connection = (HttpURLConnection) new URL(myurl)
                                                    .openConnection();

                                            //Defines a HTTP request type
                                            connection.setRequestMethod("POST");

                                            //Sets headers: Content-Type, Authorization
                                            connection.setRequestProperty("Content-Type", "application/json");
                                            connection.setRequestProperty("Accept", "application/json");
                                            connection.setRequestProperty("Authorization", "Token fab11c9b6bd4215a989c5bf57eb678");

                                            String userid= Prefs.getUserid(getApplicationContext());
                                            String compid= Prefs.getCompid(getApplicationContext());


                                            //Add POST data in JSON format
                                            JSONObject jsonParam = new JSONObject();
                                            try 
                                                jsonParam.put("latitude", latitude);
                                                jsonParam.put("longitude", longitude);
                                                jsonParam.put("userid", userid);
                                                jsonParam.put("compid", compid);
                                             catch (JSONException e) 
                                                e.printStackTrace();
                                            

                                            //Create a writer object and make the request
                                            OutputStreamWriter outputStream = new OutputStreamWriter(connection.getOutputStream());
                                            outputStream.write(jsonParam.toString());
                                            outputStream.flush();
                                            outputStream.close();

                                            //Get the Response code for the request

                                            BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                                            String responseBody = null;
                                            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) 
                                                responseBody = br.lines().collect(Collectors.joining());
                                            
                                            Log.i(TAG, "responseBody: "+responseBody);


                                            //return connection.getResponseCode();
                                         catch (IOException e) 
                                            e.printStackTrace();
                                        
                                    


                                );

                                mFusedLocationClient.removeLocationUpdates(mLocationCallback);
                             else 
                                Log.w(TAG, "Failed to get location.");
                            
                        
                    );
         catch (SecurityException unlikely) 
            Log.e(TAG, "Lost location permission." + unlikely);
        

        try 
            mFusedLocationClient.requestLocationUpdates(mLocationRequest, null);
         catch (SecurityException unlikely) 
            //Utils.setRequestingLocationUpdates(this, false);
            Log.e(TAG, "Lost location permission. Could not request updates. " + unlikely);
        

        return Result.SUCCESS;
    

【问题讨论】:

如果它仅在睡眠模式下不起作用,您确定它与应用程序进入睡眠以节省电池的 Android 打盹模式无关。尝试在您的设备上为您的应用关闭电池优化,看看您是否遇到同样的问题 【参考方案1】:

PeriodicWorkRequests 在打盹模式下会被延迟。您的工作保证每 15 分钟运行一次。 JobScheduler 可以决定它想在维护间隔期间运行您的工作。

【讨论】:

【参考方案2】:

您正在使用同步 Worker 执行异步操作。如果您打算等待回调在您的工作人员中执行某些操作,则需要使用 ListenableWorker:https://developer.android.com/topic/libraries/architecture/workmanager/advanced/threading

【讨论】:

以上是关于Workmanager(定期)获取位置并上传数据(Asynctask)被杀死的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Flutter Workmanager 插件和 Location 插件一起工作

使用 WorkManager 的定期日常工作请求

Android WorkManager - 我可以将输入数据传递给定期运行的 Worker 吗?

定期后台获取

定期获取位置并绘制标记以映射

WorkManager 在应用关闭后停止调度周期性 Worker