如何让应用程序在后台运行?继续收集数据?

时间:2011-06-09 11:00:28

标签: android database gps

在底部更新

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

  1. 防止屏幕在屏幕上打开时关闭
  2. 如果用户打开另一个应用程序或返回主屏幕,接到电话等,应用程序应继续收集数据 (或者每次更新位置时将所有数据写入数据库会更好吗?并且可能有一个按钮来表示何时开始和停止收集数据?)
  3. 这是我写的代码。 (如果你愿意,可以随意使用它,如果你对我如何改进它有任何建议,我会对建设性的批评持开放态度: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 GrassiMarcovena的答案,我们已经解决了两个问题。

    新守则:

    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));
    
    }
    
    }
    

    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
    
    }
    
    }
    

    更新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 个答案:

答案 0 :(得分:7)

问题1:您必须获得WakeLock。有多种类型的唤醒锁,取决于您是否只需要cpu或屏幕。

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