简体   繁体   English

android studio运行应用后台运行

[英]android studio running app background running

I'm working on an android app which tracks the distance you ran. 我正在开发一个可跟踪您跑步距离的android应用。 I want to be able to use another app ,like a music app, at the same time. 我希望能够同时使用另一个应用程序,例如音乐应用程序。 I didn't find any good tutorials on how to make the app run in the background, if anybody knows any good tutorials or an easy solution to make the app run in the background I would really apreciate if you would share it with me. 我没有找到任何有关如何使应用程序在后台运行的好的教程,如果有人知道任何好的教程或使该应用程序在后台运行的简单解决方案,那么如果您与我分享,我将不胜感激。

Application code: 应用代码:

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.common.SupportErrorDialogFragment;

import java.text.DateFormat;
import java.util.Date;

public class StepCounter extends FragmentActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {

// Request code to use when launching the resolution activity
private static final int REQUEST_RESOLVE_ERROR = 1001;
// Unique tag for the error dialog fragment
private static final String DIALOG_ERROR = "dialog_error";
// Bool to track whether the app is already resolving an error
private boolean mResolvingError = false;

//keys



GoogleApiClient mGoogleApiClient;
TextView mLatitudeText;
TextView mLongitudeText;
TextView mcLatitudeText;
TextView mcLongitudeText;
TextView mDistanceText;
Location mLastLocation;
Location mCurrentLocation;
double d=0.0;
double lat1;
double lat2;
double lon1;
double lon2;
double dlat;
double dlon;
double raz=6371000;
double a;
double c;

LocationRequest mLocationRequest;


protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_step_counter);
    mLatitudeText = (TextView) findViewById(R.id.lat);
    mLongitudeText = (TextView) findViewById(R.id.lon);
    mcLatitudeText = (TextView) findViewById(R.id.llat);
    mcLongitudeText = (TextView) findViewById(R.id.llon);
    mDistanceText = (TextView) findViewById(R.id.dist);

    mResolvingError = savedInstanceState != null
            && savedInstanceState.getBoolean(STATE_RESOLVING_ERROR, false);
    createLocationRequest();
    buildGoogleApiClient();

}

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

@Override
protected void onStart() {
    super.onStart();
    if(!mResolvingError)
        mGoogleApiClient.connect();
}

@Override
protected void onStop() {
    mGoogleApiClient.disconnect();
    super.onStop();
}

public void onConnected(Bundle connectionHint) {
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
            mGoogleApiClient);
    mCurrentLocation = mLastLocation;
    if (mLastLocation != null) {
        mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
        mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
    }
    //modified
    startLocationUpdates();
}

//pana aici merge de aici vine partea cu update

protected void startLocationUpdates() {
    LocationServices.FusedLocationApi.requestLocationUpdates(
            mGoogleApiClient, mLocationRequest, this);
}

protected void createLocationRequest() {
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(500);
    mLocationRequest.setFastestInterval(500);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}

@Override
public void onLocationChanged(Location location) {
    mLastLocation = mCurrentLocation;
    mCurrentLocation = location;
    updateDistance();
    updateUI();
}

public void updateUI()
{
    mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
    mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
    mcLatitudeText.setText(String.valueOf(mCurrentLocation.getLatitude()));
    mcLongitudeText.setText(String.valueOf(mCurrentLocation.getLongitude()));
}

public void updateDistance()
{
    lat1=Math.toRadians(mLastLocation.getLatitude());
    lat2=Math.toRadians(mCurrentLocation.getLatitude());
    lon1=Math.toRadians(mLastLocation.getLongitude());
    lon2=Math.toRadians(mCurrentLocation.getLongitude());
    dlat=Math.toRadians(lat2-lat1);
    dlon=Math.toRadians(lon2-lon1);
    a = Math.sin(dlat/2) * Math.sin(dlat/2) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dlon/2) * Math.sin(dlon/2);
    c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    d += raz * c;
    mDistanceText.setText(String.valueOf(d));
}
//@Override
protected void onPause() {
    super.onPause();
    stopLocationUpdates();
}

protected void stopLocationUpdates() {
    LocationServices.FusedLocationApi.removeLocationUpdates(
            mGoogleApiClient, this);
}

@Override
public void onResume() {
    super.onResume();
    if (mGoogleApiClient.isConnected()) {
        startLocationUpdates();
    }
}



// De aici partea cu rezolvatu problemei


@Override
public void onConnectionSuspended(int i) {
    //todo nust...
}

@Override
public void onConnectionFailed(ConnectionResult result) {
    if (mResolvingError) {
        // Already attempting to resolve an error.
        return;
    } else if (result.hasResolution()) {
        try {
            mResolvingError = true;
            result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
        } catch (IntentSender.SendIntentException e) {
            // There was an error with the resolution intent. Try again.
            mGoogleApiClient.connect();
        }
    } else {
        // Show dialog using GoogleApiAvailability.getErrorDialog()
        showErrorDialog(result.getErrorCode());
        mResolvingError = true;
    }
}

// The rest of this code is all about building the error dialog

/* Creates a dialog for an error message */
private void showErrorDialog(int errorCode) {
    // Create a fragment for the error dialog
    ErrorDialogFragment dialogFragment = new ErrorDialogFragment();
    // Pass the error that should be displayed
    Bundle args = new Bundle();
    args.putInt(DIALOG_ERROR, errorCode);
    dialogFragment.setArguments(args);
    dialogFragment.show(getFragmentManager(), "errordialog");
}

/* Called from ErrorDialogFragment when the dialog is dismissed. */
public void onDialogDismissed() {
    mResolvingError = false;
}


/* A fragment to display an error dialog */
public static class ErrorDialogFragment extends DialogFragment {
    public ErrorDialogFragment() { }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Get the error code and retrieve the appropriate dialog
        int errorCode = this.getArguments().getInt(DIALOG_ERROR);
        return GoogleApiAvailability.getInstance().getErrorDialog(
                this.getActivity(), errorCode, REQUEST_RESOLVE_ERROR);
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        ((StepCounter) getActivity()).onDialogDismissed();
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_RESOLVE_ERROR) {
        mResolvingError = false;
        if (resultCode == RESULT_OK) {
            // Make sure the app is not already connected or attempting to connect
            if (!mGoogleApiClient.isConnecting() &&
                    !mGoogleApiClient.isConnected()) {
                mGoogleApiClient.connect();
            }
        }
    }
}
private static final String STATE_RESOLVING_ERROR = "resolving_error";

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean(STATE_RESOLVING_ERROR, mResolvingError);
}

}

You can use Service for your requirement . 您可以根据需要使用Service

It's an application component that works for a long time in the background and does not display the user interface. 它是一个应用程序组件,可在后台长时间运行,并且不显示用户界面。 If another application component starts the service and the user switches to another application, the service can continue to run in the background. 如果另一个应用程序组件启动该服务,并且用户切换到另一个应用程序,则该服务可以继续在后台运行。

You can check sample demo android-service-example and android-service-example2 您可以查看示例演示android-service-exampleandroid-service-example2

You could use the wakefulintentservice which runs in different intervals as you set them. 您可以使用wakefulintentservice,该服务在设置它们时以不同的间隔运行。 There are some examples out there like here: http://www.programcreek.com/java-api-examples/index.php?api=com.commonsware.cwac.wakeful.WakefulIntentService 这里有一些示例,例如: http : //www.programcreek.com/java-api-examples/index.php?api=com.commonsware.cwac.wakeful.WakefulIntentService

This would be recommended, because its not save that your standard service keeps running when the screen is off while jogging. 建议这样做,因为在慢跑过程中关闭屏幕后,标准服务将继续运行,这并不能保存您的信息。

As for your comment above, you need to bind to the service from your UI and then you are able to call methods on the service. 至于上面的评论,您需要从UI绑定到该服务,然后才能在该服务上调用方法。 Read the documentation... 阅读文档...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM