对于android中的作业调度或服务这样的后台工作,哪一个是最好的选择?

对于android中的作业调度或服务这样的后台工作,哪一个是最好的选择?,android,service,android-jobscheduler,Android,Service,Android Jobscheduler,我想从后台获取位置,并将其提交到服务器,这样,像作业调度程序或服务一样,哪一个是执行相同操作的最佳选项。为什么?。我还想知道,在我们不断制作网页时,作业调度器节省了多少电池 这是我的实现,我不使用作业调度程序或服务,因为它不是必需的。我使用应用程序类,这样您就可以在所有应用程序中获取用户的位置 首先,您需要创建一个LocationHelper类,它将为您完成所有工作: public class LocationHelper implements GoogleApiClient.Connectio

我想从后台获取位置,并将其提交到服务器,这样,像作业调度程序或服务一样,哪一个是执行相同操作的最佳选项。为什么?。我还想知道,在我们不断制作网页时,作业调度器节省了多少电池

这是我的实现,我不使用作业调度程序或服务,因为它不是必需的。我使用应用程序类,这样您就可以在所有应用程序中获取用户的位置

首先,您需要创建一个LocationHelper类,它将为您完成所有工作:

public class LocationHelper implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener, LocationListener {

    private static final int REQUEST_LOCATION_PERMISSION = 0;
    private static final int REQUEST_RESOLVE_ERROR = 1;

    private static GoogleApiClient mGoogleApiClient;
    private Fragment mFragment;
    private final Activity mActivity;
    private final Callback mCallback;

    private Location mLastLocation;
    private boolean mResolvingError;
    private LocationRequest mLocationRequest;
    private boolean mRegisterLocationUpdates;

    public interface Callback {
        void onLastLocation(Location userLocation);
    }

    public LocationHelper(Fragment fragment, Callback callback) {
        this(fragment.getActivity(), callback);
        mFragment = fragment;
    }

    public LocationHelper(Activity activity, Callback callback) {
        mActivity = activity;
        mCallback = callback;

        mLocationRequest = new LocationRequest();

        mGoogleApiClient = new GoogleApiClient.Builder(mActivity)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }


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

    private void obtainLastLocation() {

        // Verifies if user give us permission to obtain its suggestionLocationV2.
        if (ActivityCompat.checkSelfPermission(mActivity,
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(mActivity,
                Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity,
                    Manifest.permission.ACCESS_COARSE_LOCATION)) {

                // Show an explanation to the user why we need its suggestionLocationV2.
                requestPermissionRationale();

            } else {

                requestPermission();
            }

            // We don't have user permission to get its geo suggestionLocationV2, abort mission.
            return;
        }

        if (!mGoogleApiClient.isConnected()) {
            mGoogleApiClient.connect();
            return;
        }

        Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if (lastLocation != null) {
            onLocationChanged(lastLocation);
        } else {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
            mRegisterLocationUpdates = true;
        }
    }

    @Override
    public void onLocationChanged(Location location) {
        if (location == null) return;

        removeLocationUpdatesIfNeed();

        mLastLocation = location;
        DirectoryApp.getInstance().setLastLocation(mLastLocation);

        if (mCallback != null) {
            mCallback.onLastLocation(mLastLocation);
        }
    }

    private void removeLocationUpdatesIfNeed() {
        if (mRegisterLocationUpdates && mGoogleApiClient.isConnected()) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
            mRegisterLocationUpdates = false;
        }
    }

    private void requestPermission() {
        // Lets ask suggestionLocationV2 permission to user.
        if (mFragment != null) {
            mFragment.requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                    REQUEST_LOCATION_PERMISSION);
        } else {
            ActivityCompat.requestPermissions(mActivity,
                    new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                    REQUEST_LOCATION_PERMISSION);
        }
    }

    private void requestPermissionRationale() {
        new AlertDialog.Builder(mActivity)
                .setMessage("We need the suggestionLocationV2 to provide you best results.")
                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        requestPermission();
                    }
                })
                .show();
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult result) {

        // If not already attempting to resolve an error.
        if (!mResolvingError) {

            if (result.hasResolution()) {

                try {
                    mResolvingError = true;
                    result.startResolutionForResult(mActivity, REQUEST_RESOLVE_ERROR);
                } catch (IntentSender.SendIntentException e) {
                    // There was an error with the resolution intent. Try again.
                    mGoogleApiClient.connect();
                }

            } else {
                GooglePlayServicesUtil.showErrorDialogFragment(result.getErrorCode(), mActivity,
                        null, REQUEST_RESOLVE_ERROR, null);
                mResolvingError = true;
            }
        }
    }


    // The follow methods should be called in Activity or Fragment.
    public void onStart() {
        mGoogleApiClient.connect();
    }

    public void onStop() {
        removeLocationUpdatesIfNeed();
        mGoogleApiClient.disconnect();
    }

    public void onRequestPermissionResult(int requestCode, String[] permissions,
                                          int[] grantResults) {
        if (requestCode == REQUEST_LOCATION_PERMISSION
                && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            // Permission granted. Uhull lets get its suggestionLocationV2 now.
            obtainLastLocation();
        }
    }
}
请注意,当位置发生更改时,我们调用应用程序类来设置新位置,因此在应用程序类中,您必须创建以下方法:

public class Application extends MultiDexApplication {

    private static App instance;

    private Location mLastLocation;

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
   }

    public void setLastLocation(Location lastLocation) {
        mLastLocation = lastLocation;
    }

    public Location getLastLocation() {
        return mLastLocation;
   }
最后,当您必须在片段或活动上使用位置时,只需使用正确的方法启动和停止它

  @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        locationHelper = new LocationHelper(this, this);
    }

    @Override
    public void onStart() {
        super.onStart();
        locationHelper.onStart();
    }

    @Override
    public void onStop() {
        super.onStop();
        locationHelper.onStop();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        locationHelper.onRequestPermissionResult(requestCode, permissions, grantResults);
    }

如果您将最佳选项定义为最节省电池的方式:尽量减少主动连接互联网以读取或传输数据的呼叫

相反,实现一个广播接收器,告诉你的应用程序已经有互联网流量在进行。当您的应用程序收到广播通知时,它可以添加自己的互联网流量。通过这种方式,你的应用程序可以避免连接到互联网的电池开销,这是非常昂贵的电池


有关详细信息,请参阅

上的捆绑传输您想从用户的设备获取位置吗?@Luiz Fernando Salvatera-Yes。如果您持续监听位置的变化,则无论是作业计划程序还是服务,您的应用程序都会耗尽电池。@Mohammed Atif:是,你是对的,但我想知道如何节省电池,以及服务和作业调度器之间的区别