在底部更新
我编写了一个记录用户位置,当前速度,平均速度和最高速度的应用程序.我想知道如何使应用程序执行以下操作:
>防止屏幕在屏幕上打开时关闭
>如果用户打开另一个应用程序或返回主屏幕,接到电话等,应用程序应继续收集数据
(或者每次更新位置时将所有数据写入数据库会更好吗?并且可能有一个按钮来表示何时开始和停止收集数据?)
这是我写的代码. (如果你愿意,可以随意使用它,如果你对我如何改进它有任何建议,我会对建设性的批评持开放态度: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;
}
}
解决方法
问题1:您必须获得
WakeLock.有多种类型的唤醒锁,取决于您是否只需要cpu或屏幕.
问题2:您应该在Service中收集数据,并将图形界面与收集数据分开.如果您正确实施数据,服务将继续收集数据,直到您停止它为止.