首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与JobScheduler融合的定位提供者

与JobScheduler融合的定位提供者
EN

Stack Overflow用户
提问于 2017-09-11 05:38:56
回答 3查看 4.8K关注 0票数 2

我在MainActivity类中有一个提供纬度和经度值的融合位置提供程序代码,它使用persistableBundle传递给JobService类。当用户使用该应用程序时,它工作得很好。应用程序在前台)。一旦应用程序被删除或销毁,来自MainActivity的最后一个更新的值就会一直通过作业调度程序反复上传(即。作业调度程序总是获得相同的值,融合的位置提供程序无法工作)。即使应用程序不在前台,我该怎么做才能让它工作呢?(PS. )当应用程序最小化时,它就能工作了。即。它可以在最近的应用程序列表中看到,但一旦从列表中删除,问题就会发生)

MainActivity.class

代码语言:javascript
复制
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // JobScheduler starts
        btnStartJob = (Button)findViewById(R.id.startjob);

        jobScheduler = (JobScheduler)getSystemService(JOB_SCHEDULER_SERVICE);
        btnStartJob.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v) {

                ComponentName jobService =
                        new ComponentName(getPackageName(), MyJobService.class.getName());
                PersistableBundle bundle = new PersistableBundle();
                bundle.putString("lat", latitude+"");
                bundle.putString("lon", longitude+"");

                JobInfo jobInfo =
                        new JobInfo.Builder(MYJOBID, jobService).setPeriodic(10000).
                        setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY).
                        setRequiresCharging(false).
                        setRequiresDeviceIdle(false).
                        setPersisted(true).
                        setExtras(bundle).
                        build();

                int jobId = jobScheduler.schedule(jobInfo);
                if(jobScheduler.schedule(jobInfo)>0){
                }else{
                }
            }
        });
    }

    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
    }


    private boolean checkPlayServices() {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                GooglePlayServicesUtil.getErrorDialog(resultCode, this,
                        PLAY_SERVICES_RESOLUTION_REQUEST).show();
            } else {
                Toast.makeText(getApplicationContext(),
                        "This device is not supported.", Toast.LENGTH_LONG)
                        .show();
                finish();
            }
            return false;
        }
        return true;
    }

    @Override
    public void onConnected(Bundle bundle) {
        createLocationRequest(bundle);
    }

    protected void createLocationRequest(Bundle bundle) {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(10000);
        mLocationRequest.setFastestInterval(5000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, new LocationCallback() {
            @Override
            public void onLocationResult(final LocationResult locationResult) {
                latitude = locationResult.getLastLocation().getLatitude() + "";
                longitude = locationResult.getLastLocation().getLongitude() + "";
                Log.e("onLocationResult lat", latitude);
                Log.e("onLocationResult Lon", longitude);
            }

            @Override
            public void onLocationAvailability(LocationAvailability locationAvailability) {
            }
        }, null);
    }

    @Override
    public void onConnectionSuspended(int i) {
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
        Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = "
                + result.getErrorCode());
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        checkPlayServices();
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (mGoogleApiClient != null) {
            mGoogleApiClient.connect();
            Log.i(TAG, "mGoogleApiClient.connect()");
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}

MyJobService类

代码语言:javascript
复制
public class MyJobService extends JobService {

    @Override
    public boolean onStartJob(JobParameters jobParameters) {
        latitude = jobParameters.getExtras().getString("lat");
        longitude = jobParameters.getExtras().getString("lon");
        Log.e("service1",latitude + "");
        Log.e("service2",longitude + "");
        return true;
    }
}

更新1:

尝试在Jobservice中实现融合位置,但不起作用

代码语言:javascript
复制
public class MyJobService extends JobService implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener{

    String latitude = null;
    String longitude = null;


    public MyJobService() {
    }

    @Override
    public boolean onStartJob(JobParameters jobParameters) {
        Log.d("onStart", "onStartJob() :: ");
        return false;
    }

    @Override
    public boolean onStopJob(JobParameters jobParameters) {
        Toast.makeText(this,
                "MyJobService.onStopJob()",
                Toast.LENGTH_SHORT).show();
        return false;
    }

    //fused location provider starts

    private GoogleApiClient mGoogleApiClient;
    private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
    private LocationRequest mLocationRequest;
    private static final String TAG = "zzzz";

    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }


    private boolean checkPlayServices() {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
//                GooglePlayServicesUtil.getErrorDialog(resultCode, this,
//                        PLAY_SERVICES_RESOLUTION_REQUEST).show();
                Log.e("GooglePlayServices", resultCode + "");
            } else {
                Toast.makeText(getApplicationContext(),
                        "This device is not supported.", Toast.LENGTH_LONG)
                        .show();
                stopSelf();
            }
            return false;
        }
        return true;
    }

    @Override
    public void onConnected(Bundle bundle) {
        createLocationRequest(bundle);
    }

    protected void createLocationRequest(Bundle bundle) {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(5000);
        mLocationRequest.setFastestInterval(5000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            return;
        }

        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, new LocationCallback() {
            @Override
            public void onLocationResult(final LocationResult locationResult) {
                latitude = locationResult.getLastLocation().getLatitude() + "";
                longitude = locationResult.getLastLocation().getLongitude() + "";
                Log.e("onLocationResult lat", latitude);
                Log.e("onLocationResult Lon", longitude);
            }

            @Override
            public void onLocationAvailability(LocationAvailability locationAvailability) {
            }
        }, null);
    }

    @Override
    public void onConnectionSuspended(int i) {
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
        Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = "
                + result.getErrorCode());
    }
// fused location provider ends
}
EN

回答 3

Stack Overflow用户

发布于 2019-03-18 10:23:26

我不知道你是否还在试图解决这个问题,但问题是,当应用程序被销毁时,作业调度程序总是得到错误的数据(旧数据)。解决方案可能是在您的手机上缓冲sqlite数据库。因为数据库在销毁应用程序时不会被删除,所以您可以将最新的GPS数据放到数据库中,然后让调度程序从中获取它。它应该能正常工作。

请仁慈一点,这是我第一次尝试帮忙;)

票数 3
EN

Stack Overflow用户

发布于 2017-09-11 06:02:20

您需要将您的融合位置服务逻辑放在作业服务中,因为当您关闭您的应用程序时,您的位置侦听器也被破坏,所以当您的应用程序在前景或背景中不可用时,您需要在作业服务中获得新的位置,当您的作业服务调用您确定的时间时,您需要实现获取位置的逻辑,以及更新位置的逻辑,

您可以使用最后一个已知的位置来获得位置。

票数 2
EN

Stack Overflow用户

发布于 2019-11-22 05:05:23

在更新和先前答案的基础上,我终于能够让它发挥作用。

通过调用fusedLocationProvider到作业调度程序的onStartJob中的getLastKnownLocation

请参阅以下代码

代码语言:javascript
复制
ComponentName jobServiceComponent = new ComponentName(context, LocationJobService.class);
    JobInfo.Builder jobInfoBuilder = new JobInfo.Builder(0, jobServiceComponent);
    jobInfoBuilder.setPeriodic(Constants.JOB_SERVICE_INTERVAL);
    jobInfoBuilder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
    jobInfoBuilder.setRequiresCharging(false);
    jobInfoBuilder.setRequiresDeviceIdle(false);
    jobInfoBuilder.setPersisted(true);

    JobScheduler scheduler = (JobScheduler) context.getSystemService(JOB_SCHEDULER_SERVICE);
    int resultCode = scheduler.schedule(jobInfoBuilder.build());

并启动此作业调度程序

代码语言:javascript
复制
@Override
public boolean onStartJob(JobParameters params) {
    updateBackgroundLocation(params);
    return true;
}

private void updateBackgroundLocation(JobParameters params) {

    if (jobCancelled) { return; }
    new Thread(new Runnable() {
        @Override
        public void run() {
            updateLocation(params);
        }
    }).start();

}

private void updateLocation(JobParameters params) {

    LocationServices.getFusedLocationProviderClient(getApplicationContext())
            .getLastLocation().addOnSuccessListener(location -> {
                //perform your update here with last known location.

    }).addOnFailureListener(e -> {
        e.printStackTrace();
    });
    jobFinished(params, true);
}

@Override
public boolean onStopJob(JobParameters params) {
    jobCancelled = true;
    return false;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46148844

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档