Можно ли выбрать местоположение пользователя из класса Worker? - PullRequest
0 голосов
/ 18 января 2019

Мне нужно запланировать работу для получения текущего местоположения пользователя и обновления на сервере через заданный интервал (даже приложение не запущено).

Я пытаюсь WorkManagerAPI реализовать функциональность. Можно ли получить текущее местоположение пользователя из метода doWork()?

locationManager.requestLocationUpdates(
    provider, timeInterval, travelDistance, locationListener
);

Когда я запрашиваю обновления местоположения от doWork(), выдается ошибка ниже.

java.lang.RuntimeException: невозможно создать обработчик внутри потока, который не вызвал Looper.prepare ()

1 Ответ

0 голосов
/ 29 апреля 2019

Насколько я понимаю, при реализации LocationManager.requestLocationUpdates () в рабочем потоке, вызов выполняется в фоновом потоке, не являющемся пользовательским интерфейсом, созданным WorkManager. LocationManager.requestLocationUpdates () - это асинхронный вызов, возможно, в другом фоновом потоке. Для обработки обратных вызовов, определенных LocationListener, вызывающий поток должен остаться в живых. Вот почему исключение говорит:

Невозможно создать обработчик внутри потока, который не вызвал Looper.prepare ()

Проверьте фрагмент кода ниже. Пожалуйста, рассмотрите это как псевдокод, я не тестировал этот кусок кода.

public class LocationWorker extends Worker {

    String LOG_TAG = "LocationWorker";
    private Context mContext;
    private MyHandlerThread mHandlerThread;

    public LocationWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
        mContext = context;
    }

    @NonNull
    @Override
    public Result doWork() {
        Log.d(LOG_TAG, "doWork");

        mHandlerThread = new MyHandlerThread("MY_THREAD");
        mHandlerThread.start();

        Runnable runnable = new Runnable() {
            @Override
            public void run() {

                LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
                String bestProvider = locationManager.getBestProvider(new Criteria(), true);

                boolean permission = false;
                if (PermissionChecker.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
                        PermissionChecker.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                    Log.e(LOG_TAG, "This app requires ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION permissions.");
                    permission = true;
                }

                Log.d(LOG_TAG, "permission: "+permission);
                Log.d(LOG_TAG, "bestProvider: "+bestProvider);

                if (permission && bestProvider != null) {

                    MyLocationListener locListener = new MyLocationListener();
                    locationManager.requestLocationUpdates(bestProvider, 500, 1, locListener, mHandlerThread.getLooper());
                }
            }
        };

        mHandlerThread.post(runnable);

        return Result.success();
    }


    class MyHandlerThread extends HandlerThread {

        Handler mHandler;

        MyHandlerThread(String name) {
            super(name);
        }

        @Override
        protected void onLooperPrepared() {
            Looper looper = getLooper();
            if (looper != null)
                mHandler = new Handler(looper);
        }

        void post(Runnable runnable) {
            if (mHandler != null)
                mHandler.post(runnable);
        }
    }

    class MyLocationListener implements LocationListener
    {
        @Override
        public void onLocationChanged(final Location loc)
        {
            Log.d(LOG_TAG, "Location changed: " + loc.getLatitude() +","+ loc.getLongitude());
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras)
        {
            Log.d(LOG_TAG, "onStatusChanged");
        }

        @Override
        public void onProviderDisabled(String provider)
        {
            Log.d(LOG_TAG, "onProviderDisabled");
        }

        @Override
        public void onProviderEnabled(String provider)
        {
            Log.d(LOG_TAG, "onProviderEnabled");
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...