在底部更新
我编写了一个记录用户位置,当前速度,平均速度和最高速度的应用程序.我想知道如何使应用程序执行以下操作:
>防止屏幕在屏幕上打开时关闭
>如果用户打开另一个应用程序或返回主屏幕,接到电话等,应用程序应继续收集数据
(或者每次更新位置时将所有数据写入数据库会更好吗?并且可能有一个按钮来表示何时开始和停止收集数据?)
这是我写的代码. (如果你愿意,可以随意使用它,如果你对我如何改进它有任何建议,我会对建设性的批评持开放态度: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,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),BigDecimal.ROUND_HALF_UP); //all speeds added together totalSpeed = totalSpeed + currentSpeed; totalKmph = totalKmph + kmphSpeed; //calculates average speed avgSpeed = round(totalSpeed/counter,BigDecimal.ROUND_HALF_UP); avgKmph = round(totalKmph/counter,BigDecimal.ROUND_HALF_UP); //gets position lat = round(((double) (newLocation.getLatitude())),BigDecimal.ROUND_HALF_UP); lon = round(((double) (newLocation.getLongitude())),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,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,Bundle extras) { // TODO Auto-generated method stub } }
从Marco Grassi和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)); } }
和
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(),BigDecimal.ROUND_HALF_UP); GPSMain.kmphSpeed = round((GPSMain.currentSpeed*3.6),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,BigDecimal.ROUND_HALF_UP); GPSMain.avgKmph = round(GPSMain.totalKmph/GPSMain.counter,BigDecimal.ROUND_HALF_UP); //gets position GPSMain.lat = round(((double) (newLocation.getLatitude())),BigDecimal.ROUND_HALF_UP); GPSMain.lon = round(((double) (newLocation.getLongitude())),BigDecimal.ROUND_HALF_UP); GPSMain.run(); } //not entirely sure what these do yet public void onStatusChanged(String provider,locationListener); } //Method to round the doubles to a max of 3 decimal places public static double round(double unrounded,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,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())),BigDecimal.ROUND_HALF_UP); GPSMain.lon = round(((double) (GPSMain.prevIoUsLocation.getLongitude())),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())),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,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,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; } }