如何保持应用程序在后台运行?继续收集数据? [英] how to keep application running in background? keep collecting data?

查看:160
本文介绍了如何保持应用程序在后台运行?继续收集数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

UPDATED AT BOTTOM

UPDATED AT BOTTOM

我写了一个记录用户位置,当前速度,平均速度和最高速度的应用程序。我想知道如何让应用程序执行以下操作:

I have written an application that logs the users position, current speed, average speed and top speed. I would like to know how to make the application do the following things:


  1. 防止屏幕在屏幕上打开时关闭

  2. 如果用户打开另一个应用程序或返回主屏幕,获取呼叫等,则应用程序应继续收集数据
    (或者最好只写入所有数据到每个位置更新的数据库?并且可能有一个按钮来表示何时开始和停止收集数据?)

我写的代码。 (如果你愿意可以随意使用它,如果你有任何建议我如何改进它我非常开放建设性的批评:D)

here is the code that I have written. (feel free to use it if you want and if you have any recommendations on how I might improve it I am very open to constructive criticism :D )

package Hartford.gps;

import java.math.BigDecimal;

import android.app.Activity;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;

public class GPSMain extends Activity implements LocationListener {

LocationManager locationManager;
LocationListener locationListener;

//text views to display latitude and longitude
TextView latituteField;
TextView longitudeField;
TextView currentSpeedField;
TextView kmphSpeedField;
TextView avgSpeedField;
TextView avgKmphField;

//objects to store positional information
protected double lat;
protected double lon;

//objects to store values for current and average speed
protected double currentSpeed;
protected double kmphSpeed;
protected double avgSpeed;
protected double avgKmph;
protected double totalSpeed;
protected double totalKmph;

//counter that is incremented every time a new position is received, used to calculate average speed
int counter = 0;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    run();
}

@Override
public void onResume() {
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 1, this);
    super.onResume();
}

@Override
public void onPause() {
    locationManager.removeUpdates(this);
    super.onPause();
}

private void run(){

    final Criteria criteria = new Criteria();

    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    criteria.setSpeedRequired(true);
    criteria.setAltitudeRequired(false);
    criteria.setBearingRequired(false);
    criteria.setCostAllowed(true);
    criteria.setPowerRequirement(Criteria.POWER_LOW);
    //Acquire a reference to the system Location Manager

    locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

    // Define a listener that responds to location updates
    locationListener = new LocationListener() {

        public void onLocationChanged(Location newLocation) {

            counter++;

            //current speed fo the gps device
            currentSpeed = round(newLocation.getSpeed(),3,BigDecimal.ROUND_HALF_UP);
            kmphSpeed = round((currentSpeed*3.6),3,BigDecimal.ROUND_HALF_UP);

            //all speeds added together
            totalSpeed = totalSpeed + currentSpeed;
            totalKmph = totalKmph + kmphSpeed;

            //calculates average speed
            avgSpeed = round(totalSpeed/counter,3,BigDecimal.ROUND_HALF_UP);
            avgKmph = round(totalKmph/counter,3,BigDecimal.ROUND_HALF_UP);

            //gets position
            lat = round(((double) (newLocation.getLatitude())),3,BigDecimal.ROUND_HALF_UP);
            lon = round(((double) (newLocation.getLongitude())),3,BigDecimal.ROUND_HALF_UP);

            latituteField = (TextView) findViewById(R.id.lat);
            longitudeField = (TextView) findViewById(R.id.lon);             
            currentSpeedField = (TextView) findViewById(R.id.speed);
            kmphSpeedField = (TextView) findViewById(R.id.kmph);
            avgSpeedField = (TextView) findViewById(R.id.avgspeed);
            avgKmphField = (TextView) findViewById(R.id.avgkmph);

            latituteField.setText("Current Latitude:        "+String.valueOf(lat));
            longitudeField.setText("Current Longitude:      "+String.valueOf(lon));
            currentSpeedField.setText("Current Speed (m/s):     "+String.valueOf(currentSpeed));
            kmphSpeedField.setText("Cuttent Speed (kmph):       "+String.valueOf(kmphSpeed));
            avgSpeedField.setText("Average Speed (m/s):     "+String.valueOf(avgSpeed));
            avgKmphField.setText("Average Speed (kmph):     "+String.valueOf(avgKmph));

        }

        //not entirely sure what these do yet
        public void onStatusChanged(String provider, int status, Bundle extras) {}
        public void onProviderEnabled(String provider) {}
        public void onProviderDisabled(String provider) {}

    };

    // Register the listener with the Location Manager to receive location updates
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 1, locationListener);
}

//Method to round the doubles to a max of 3 decimal places
public static double round(double unrounded, int precision, int roundingMode)
{
    BigDecimal bd = new BigDecimal(unrounded);
    BigDecimal rounded = bd.setScale(precision, roundingMode);
    return rounded.doubleValue();
}


@Override
public void onLocationChanged(Location location) {
    // TODO Auto-generated method stub

}

@Override
public void onProviderDisabled(String provider) {
    // TODO Auto-generated method stub

}

@Override
public void onProviderEnabled(String provider) {
    // TODO Auto-generated method stub

}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
    // TODO Auto-generated method stub

}

}

两个问题解答了解答 Marco Grassi Marcovena

BOTH PROBLEMS SOLVED THANKS TO ANSWERS FROM Marco Grassi AND Marcovena.

新代码:

package Hartford.gps;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.PowerManager;
import android.widget.TextView;

public class GPSMain extends Activity   {

//text views to display latitude and longitude
static TextView latituteField;
static TextView longitudeField;
static TextView currentSpeedField;
static TextView kmphSpeedField;
static TextView avgSpeedField;
static TextView avgKmphField;
static TextView topSpeedField;
static TextView topKmphField;

//objects to store positional information
protected static double lat;
protected static double lon;

//objects to store values for current and average speed
protected static double currentSpeed;
protected static double kmphSpeed;
protected static double avgSpeed;
protected static double avgKmph;
protected static double totalSpeed;
protected static double totalKmph;
protected static double topSpeed=0;
protected static double topKmph=0;

//counter that is incremented every time a new position is received, used to calculate average speed
static int counter = 0;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    PowerManager powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock wL = powerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,"My Tag");

    wL.acquire();

    startService(new Intent(this, Calculations.class));

    latituteField = (TextView) findViewById(R.id.lat);
    longitudeField = (TextView) findViewById(R.id.lon);             
    currentSpeedField = (TextView) findViewById(R.id.speed);
    kmphSpeedField = (TextView) findViewById(R.id.kmph);
    avgSpeedField = (TextView) findViewById(R.id.avgspeed);
    avgKmphField = (TextView) findViewById(R.id.avgkmph);
    topSpeedField = (TextView) findViewById(R.id.topspeed);
    topKmphField = (TextView) findViewById(R.id.topkmph);

}

static void run(){

    latituteField.setText("Current Latitude:        "+String.valueOf(lat));
    longitudeField.setText("Current Longitude:      "+String.valueOf(lon));
    currentSpeedField.setText("Current Speed (m/s):     "+String.valueOf(currentSpeed));
    kmphSpeedField.setText("Cuttent Speed (kmph):       "+String.valueOf(kmphSpeed));
    avgSpeedField.setText("Average Speed (m/s):     "+String.valueOf(avgSpeed));
    avgKmphField.setText("Average Speed (kmph):     "+String.valueOf(avgKmph));
    topSpeedField.setText("Top Speed (m/s):     "+String.valueOf(topSpeed));
    topKmphField.setText("Top Speed (kmph):     "+String.valueOf(topKmph));

}

}

p>

and

package Hartford.gps;

import java.math.BigDecimal;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

public class Calculations extends Service implements LocationListener  {

static LocationManager locationManager;
LocationListener locationListener;

private static final String TAG = "Calculations";

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void onCreate() {
    Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
    Log.d(TAG, "onCreate");

    run();

}

private void run(){

    final Criteria criteria = new Criteria();

    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    criteria.setSpeedRequired(true);
    criteria.setAltitudeRequired(false);
    criteria.setBearingRequired(false);
    criteria.setCostAllowed(true);
    criteria.setPowerRequirement(Criteria.POWER_LOW);
    //Acquire a reference to the system Location Manager

    locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

    // Define a listener that responds to location updates
    locationListener = new LocationListener() {

        public void onLocationChanged(Location newLocation) {

            GPSMain.counter++;

            //current speed for the GPS device
            GPSMain.currentSpeed = round(newLocation.getSpeed(),3,BigDecimal.ROUND_HALF_UP);
            GPSMain.kmphSpeed = round((GPSMain.currentSpeed*3.6),3,BigDecimal.ROUND_HALF_UP);

            if (GPSMain.currentSpeed>GPSMain.topSpeed) {
                GPSMain.topSpeed=GPSMain.currentSpeed;
            }
            if (GPSMain.kmphSpeed>GPSMain.topKmph) {
                GPSMain.topKmph=GPSMain.kmphSpeed;
            }

            //all speeds added together
            GPSMain.totalSpeed = GPSMain.totalSpeed + GPSMain.currentSpeed;
            GPSMain.totalKmph = GPSMain.totalKmph + GPSMain.kmphSpeed;

            //calculates average speed
            GPSMain.avgSpeed = round(GPSMain.totalSpeed/GPSMain.counter,3,BigDecimal.ROUND_HALF_UP);
            GPSMain.avgKmph = round(GPSMain.totalKmph/GPSMain.counter,3,BigDecimal.ROUND_HALF_UP);

            //gets position
            GPSMain.lat = round(((double) (newLocation.getLatitude())),3,BigDecimal.ROUND_HALF_UP);
            GPSMain.lon = round(((double) (newLocation.getLongitude())),3,BigDecimal.ROUND_HALF_UP);

            GPSMain.run();
        }

        //not entirely sure what these do yet
        public void onStatusChanged(String provider, int status, Bundle extras) {}
        public void onProviderEnabled(String provider) {}
        public void onProviderDisabled(String provider) {}

    };

    // Register the listener with the Location Manager to receive location updates
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 1, locationListener);

}



//Method to round the doubles to a max of 3 decimal places
public static double round(double unrounded, int precision, int roundingMode)
{
    BigDecimal bd = new BigDecimal(unrounded);
    BigDecimal rounded = bd.setScale(precision, roundingMode);
    return rounded.doubleValue();
}


public void onLocationChanged(Location location) {
    // TODO Auto-generated method stub

}

public void onProviderDisabled(String provider) {
    // TODO Auto-generated method stub

}

public void onProviderEnabled(String provider) {
    // TODO Auto-generated method stub

}

public void onStatusChanged(String provider, int status, Bundle extras) {
    // TODO Auto-generated method stub

}

}

UPDATE FOR shababhsiddique

UPDATE FOR shababhsiddique

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

public class Calculations extends Service{
static LocationManager locationManager;
static LocationListener locationListener;
private static long timerTime = 1;
private static float timerFloatValue = 1.0f;
private Context context;
private int counter = 0;

@Override
public IBinder onBind(Intent intent) {return null;}

@Override
public void onCreate() {
    context = this;
    update();
}

protected void update(){        
    final Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    criteria.setSpeedRequired(true);
    criteria.setAltitudeRequired(false);
    criteria.setBearingRequired(false);
    criteria.setCostAllowed(true);
    criteria.setPowerRequirement(Criteria.POWER_LOW);

    //Acquire a reference to the system Location Manager
    locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

    // Define a listener that responds to location updates
    locationListener = new LocationListener() {
        public void onLocationChanged(Location newLocation) {
            counter++;
            if(GPSMain.GPSHasStarted==0){
                GPSMain.previousLocation = newLocation;
                //gets position
                GPSMain.lat = round(((double) (GPSMain.previousLocation.getLatitude())),3,BigDecimal.ROUND_HALF_UP);
                GPSMain.lon = round(((double) (GPSMain.previousLocation.getLongitude())),3,BigDecimal.ROUND_HALF_UP);
                GPSMain.startingLocation = GPSMain.previousLocation;
                GPSMain.routeLat.add(Double.toString(GPSMain.startingLocation.getLatitude()));
                GPSMain.routeLon.add(Double.toString(GPSMain.startingLocation.getLongitude()));
                GPSMain.startTime = System.currentTimeMillis();
                GPSMain.GPSHasStarted++;
                Toast.makeText(context, "GPS Connection Established", Toast.LENGTH_LONG).show();
                startService(new Intent(context, AccelerometerReader.class));
                Toast.makeText(context, "Accelerometer Calculating", Toast.LENGTH_LONG).show();
                Toast.makeText(context, "Have A Safe Trip!", Toast.LENGTH_LONG).show();
            }
            //gets position
            GPSMain.lat = round(((double) (newLocation.getLatitude())),3,BigDecimal.ROUND_HALF_UP);
            GPSMain.lon = round(((double) (newLocation.getLongitude())),3,BigDecimal.ROUND_HALF_UP);
            if (newLocation.distanceTo(GPSMain.previousLocation)>2.0f){
                GPSMain.distanceBetweenPoints = GPSMain.distanceBetweenPoints + newLocation.distanceTo(GPSMain.previousLocation);
            }

            //current speed for the GPS device
            GPSMain.mpsSpeed = newLocation.getSpeed();
            if (GPSMain.mpsSpeed>GPSMain.topMps) {GPSMain.topMps=GPSMain.mpsSpeed;}

            //store location in order to calculate distance during next iteration.
            GPSMain.previousLocation = newLocation;

            if (counter % 20 == 0){
                GPSMain.routeLat.add(Double.toString(GPSMain.previousLocation.getLatitude()));
                GPSMain.routeLon.add(Double.toString(GPSMain.previousLocation.getLongitude()));
            }
        }

        //not entirely sure what these do yet
        public void onStatusChanged(String provider, int status, Bundle extras) {}
        public void onProviderEnabled(String provider) {}
        public void onProviderDisabled(String provider) {}
    };

    // Register the listener with the Location Manager to receive location updates
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 20, locationListener);
}

//Method to round the doubles to a max of 3 decimal places
public static double round(double unrounded, int precision, int roundingMode){
    BigDecimal bd = new BigDecimal(unrounded);
    BigDecimal rounded = bd.setScale(precision, roundingMode);
    return rounded.doubleValue();
}

//formats the time taken in milliseconds into hours minutes and seconds
public static String getTimeTaken(long end, long start){
    @SuppressWarnings("unused")
    String formattedTime = "", hourHour = "", hourMin = ":", minSec = ":";
    long timeTaken = end-start, hour = 0, min = 0, sec = 0;
    timerTime = timeTaken;
    timeTaken = (end-start)/1000;
    if (timeTaken>9 ){
        hourHour = "0";
        hourMin = ":0";
        if (timeTaken>=60){
            if (timeTaken>= 3200){
                hour = timeTaken/3200;
                timeTaken = timeTaken%3200;
                if (hour>9){
                    hourHour = "";
                }
            }
            min = timeTaken/60;
            timeTaken = timeTaken%60;
            if (min >9){
                hourMin = ":";
            }
        }
        sec = timeTaken;
        if(sec%60<10){
            minSec = ":0";
        }
        return formattedTime = (hourHour+hour+hourMin+min+minSec+sec);
    }
    sec = timeTaken;
    minSec = ":0";
    hourMin = ":0";
    hourHour = "0";
    return formattedTime = (hourHour+hour+hourMin+min+minSec+sec);
}

public static double averageSpeed(){

    //calculates average speed
    if (timerTime==0){timerTime=1;}
    timerFloatValue = (float) timerTime;
    timerFloatValue =  timerFloatValue/1000;
    return GPSMain.avgMps = GPSMain.distanceBetweenPoints/timerFloatValue;
}

//rounds the float values from the accelerometer
static String roundTwoDecimalFloat(float a){
    float b = a/9.8f;
    String formattedNum;
    NumberFormat nf = new DecimalFormat();
    nf.setMaximumFractionDigits(2);
    nf.setMinimumFractionDigits(2);
    formattedNum = nf.format(b);
    return formattedNum;
}
}


推荐答案

1:您必须获取 WakeLock 。有多种类型的wakelock,取决于你是否只需要cpu或屏幕。

Question 1: You must acquire a WakeLock . There are multiple types of wakelock, depending if you want only the cpu on or also the screen.

问题2:你应该在服务,并将图形界面与收集数据分开。如果您正确实施,服务将继续收集数据,直到您停止为止。

Question 2: You should do your collecting data stuff inside a Service and separate the graphical interface from the collecting data. The Service will continue to collect the data until you stop it if you implement it correctly.

这篇关于如何保持应用程序在后台运行?继续收集数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆