Android Wakelock for GPS Service



我正在开发一个应用程序,它每十分钟获取一次GPS定位并将其发送到服务器,为此我使用了Timer、requestLocationUpdates和Android异步Http客户端库。这些位置需要每十分钟保存12个小时。

为了保持应用程序的活力,我在服务内的onCreate中使用唤醒锁定

    PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
    wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "whatever");
    wl.acquire();

和onDestroy()

    wl.release();

服务由MainActivity中的按钮启动和停止。我的主要问题是,如果用户按下主页按钮并将应用程序向后移动,我只会得到两次位置(开始时和10分钟后,20分钟后没有位置更新)。只要我在应用程序上锁定屏幕,这似乎是可以的,但当我锁定主屏幕时,这个过程似乎在几分钟后就结束了。

这是我的GPS服务的全部代码:

public class UpdatePositionService extends Service {
    private PowerManager.WakeLock wl;
    private Handler mHandler = new Handler(Looper.getMainLooper());
    private AsyncHttpClient client = new AsyncHttpClient();
    private SharedPreferences preferences;
    public static final String USER_PREFERENCES = "userPreferences";
    private Timer updatingTimer;
    private TimerTask task = new TimerTask() {
        @Override
        public void run() {
            mHandler.post(new Runnable() {
                public void run() {
                    preferences = getSharedPreferences(USER_PREFERENCES, MODE_PRIVATE);
                    final String uid = preferences.getString("userid", "");
                    final String pause = readFromFile("pause.txt");
                    final String userState = readFromFile("user.txt");
                    final String workid = readFromFile("work.txt");
                    final String consid = readFromFile("cons.txt");
                    if (!pause.equals("1") && !userState.equals("0")) {
                        Log.e("mmd:test:123", "dochodzi  " + userState);
                        final LocationManager[] lm = {(LocationManager)
                            getSystemService(Context.LOCATION_SERVICE)};
                        Criteria criteria = new Criteria();
                        criteria.setAccuracy(Criteria.ACCURACY_FINE);
                        criteria.setPowerRequirement(Criteria.POWER_HIGH);
                        _if();
                        lm[0].requestLocationUpdates(LocationManager
                            .GPS_PROVIDER, 6000, 10, new LocationListener() {
                            @Override
                            public void onLocationChanged(Location location) {
                                String updatedPause = readFromFile("pause.txt");
                                _if();
                                lm[0].removeUpdates(this);
                                lm[0] = null;
                                if (!updatedPause.equals("1")) {
                                    RequestParams params = new RequestParams();
                                    params.put("uid", uid);
                                    params.put("lat", location.getLatitude());
                                    params.put("long", location.getLongitude());
                                    params.put("workid", workid);
                                    params.put("type", userState);
                                    params.put("cons", consid);
                                    String url = "http://example.com/api/event/add";
                                    client.post(url, params,
                                      new AsyncHttpResponseHandler() {
                                        @Override
                                        public void onSuccess(int statusCode,
                                        Header[] headers, byte[] responseBody) {
                                            String response = new String(
                                                responseBody);
                                            if (!response.equals("ERROR")) {
                                            } else {
                                            }
                                        }
                                        @Override
                                        public void onFailure(
                                            int statusCode, Header[] headers,
                                            byte[] responseBody,
                                            Throwable error) {}
                                    });
                                }
                            }
                            @Override
                            public void onStatusChanged(String provider, int
                                status, Bundle extras) {}
                            @Override
                            public void onProviderEnabled(String provider) {}
                            @Override
                            public void onProviderDisabled(String provider) {}
                        });
                    }
                }
            });
        }
    };
    private void _if() {
        if (ActivityCompat.checkSelfPermission(UpdatePositionService.this,
            Manifest.permission.ACCESS_FINE_LOCATION) !=
            PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(UpdatePositionService.this,
                Manifest.permission.ACCESS_COARSE_LOCATION) !=
                PackageManager.PERMISSION_GRANTED) {}
    }
    @Override
    public void onCreate() {
        super.onCreate();
        updatingTimer = new Timer();
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager
            .ACQUIRE_CAUSES_WAKEUP, "whatever");
        wl.acquire();
    }
    @Override
    public void onDestroy() {
        updatingTimer.cancel();
        mHandler.removeCallbacksAndMessages(null);
        wl.release();
        super.onDestroy();
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        int time = 1000 * 60 * 10; // 10 mins
        updatingTimer.scheduleAtFixedRate(task, 3000, time);
        return START_NOT_STICKY;
    }
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
    private String readFromFile(String filename) {
        String ret = "";
        try {
            InputStream inputStream = openFileInput(filename);
            if (inputStream != null) {
                InputStreamReader inputStreamReader = new InputStreamReader
                    (inputStream);
                BufferedReader bufferedReader = new BufferedReader
                    (inputStreamReader);
                String receiveString = "";
                StringBuilder stringBuilder = new StringBuilder();
                while ((receiveString = bufferedReader.readLine()) != null) {
                    stringBuilder.append(receiveString);
                }
                inputStream.close();
                ret = stringBuilder.toString();
            }
        } catch (FileNotFoundException e) {
            Log.e("login activity", "File not found: " + e.toString());
        } catch (IOException e) {
            Log.e("login activity", "Can not read file: " + e.toString());
        }
        return ret;
    }
}

展开@CommonsWare注释。为此设置服务是个坏主意,而且正如您所看到的那样也不起作用。安卓杀死了它,派对结束了。要执行任何定期任务,您必须使用报警管理器设置报警。要做到这一点,注册一个警报-在一些设置为在启动时接收的接收器中更好-因为当重新启动时,所有的警报都会消失:

private void setupAlarm(Context context, boolean setup) {
    am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    pi = PendingIntent.getBroadcast(context, NOT_USED, yourIntent,
                                    PendingIntent.FLAG_UPDATE_CURRENT);
    if (setup) { // setup the alarms
        try {
            am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                SystemClock.elapsedRealtime() + SOME_DELAY, THE_INTERVAL_BETWEEN_ALARMS, pi);
        } catch (InstantiationException e) {
            // should not happen
            throw new RuntimeException(UNABLE_TO_SET_ALARMS, e);
        } catch (IllegalAccessException e) {
            // should not happen
            throw new RuntimeException(UNABLE_TO_SET_ALARMS, e);
        }
    } else { // teardown the alarms
        // send message to the monitors that the party is over
        Intent i = new Intent(YOUR_ABORTING_ACTION, Uri.EMPTY, context, YOUR_SERVICE_CLASS);
        WakefulIntentService.sendWakefulWork(context, i);
        // cancel the alarms
        am.cancel(pi);
    }
    d("alarms " + (setup ? "enabled" : "disabled"));
}

然后,在注册接收来自AlarmManager的广播的接收器的onReceive中(它们为您保留永远不会失败的唤醒锁),委托WakefulIntentService

@Override
final public void onReceive(Context context, Intent intent) {
    final String action = intent.getAction();
    if (ac_setup_alarm.equals(action) || ac_cancel_alarm.equals(action)) {
        monitoringIntent = new Intent(context, this.getClass());
        monitoringIntent.setAction(ac_monitor.toString());
        final boolean enable = ac_setup_alarm.equals(action);
        setupAlarm(context, enable);
    } else if (ac_monitor.equals(action)) {
        // monitoring - got broadcast from ALARM
        WakefulIntentService.sendWakefulWork(context, YOUR_SERVICE_CLASS);
    } else if (ac_reschedule_alarm.equals(action)) {
        monitoringIntent = new Intent(context, this.getClass());
        monitoringIntent.setAction(ac_monitor.toString());
        rescheduleAlarm(context);
    } else {
        w("Received bogus intent : " + intent);
    }
}

或者,要使用唤醒意图服务,您可以使用WakefulBroadcastReceiver,但您必须编写该服务。(我的)代码在这里-有效!

相关内容

  • 没有找到相关文章

最新更新