如何保持应用程序在后台运行?继续收集数据? [英] how to keep application running in background? keep collecting data?
问题描述
更新于底部
我已经写,记录用户的位置,当前速度,平均速度和最高速度的应用程序。我想知道如何使应用程序做以下事情:
- prevent不关闭处于打开状态时,屏幕上的画面
- 如果用户打开另一个应用程序或返回到主屏幕,收到电话等,应用程序应该继续收集数据 (或会是最好只写的所有数据到每次的位置更新数据库?也许有一个按钮来表明何时开始和停止收集数据?)
下面是我写的code。 (随意使用它,如果你想,如果你对我怎么可能改善它的任何建议我建设性的批评非常开放:D)
包Hartford.gps;
进口的java.math.BigDecimal;
进口android.app.Activity;
进口android.content.Context;
进口android.location.Criteria;
进口android.location.Location;
进口android.location.LocationListener;
进口android.location.LocationManager;
进口android.os.Bundle;
进口android.widget.TextView;
公共类GPSMain扩展活动实现LocationListener的{
LocationManager locationManager;
LocationListener的LocationListener的;
//文本视图来显示经纬度
TextView的latituteField;
TextView的longitudeField;
TextView的currentSpeedField;
TextView的kmphSpeedField;
TextView的avgSpeedField;
TextView的avgKmphField;
//对象来存储位置信息
受保护的双重纬度;
受保护的双重LON;
//对象来存储值电流和平均车速
受保护的双重currentSpeed;
受保护的双重kmphSpeed;
受保护的双重avgSpeed;
受保护的双重avgKmph;
受保护的双重totalSpeed;
受保护的双重totalKmph;
//计数器,每接收到一个新的位置时递增,用于计算平均车速
INT计数器= 0;
/ **第一次创建活动时调用。 * /
@覆盖
公共无效的onCreate(包savedInstanceState){
super.onCreate(savedInstanceState);
的setContentView(R.layout.main);
跑();
}
@覆盖
公共无效onResume(){
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,1,本);
super.onResume();
}
@覆盖
公共无效的onPause(){
locationManager.removeUpdates(本);
super.onPause();
}
私人无效的run(){
最终标准标准=新标准();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setSpeedRequired(真正的);
criteria.setAltitudeRequired(假);
criteria.setBearingRequired(假);
criteria.setCostAllowed(真正的);
criteria.setPowerRequirement(Criteria.POWER_LOW);
//获取一个参考系统位置管理
locationManager =(LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
//定义一个监听器,响应位置更新
LocationListener的=新LocationListener的(){
公共无效onLocationChanged(位置newLocation){
反++;
//当前速度FO GPS设备
currentSpeed =圆(newLocation.getSpeed(),3,BigDecimal.ROUND_HALF_UP);
kmphSpeed = ROUND((currentSpeed * 3.6),3,BigDecimal.ROUND_HALF_UP);
//所有速度加在一起
totalSpeed = totalSpeed + currentSpeed;
totalKmph = totalKmph + kmphSpeed;
//计算平均速度
avgSpeed = ROUND(totalSpeed /计数器,3,BigDecimal.ROUND_HALF_UP);
avgKmph = ROUND(totalKmph /计数器,3,BigDecimal.ROUND_HALF_UP);
//获取位置
纬度= ROUND(((双)(newLocation.getLatitude())); 3,BigDecimal.ROUND_HALF_UP);
LON = ROUND(((双)(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(当前纬度:+将String.valueOf(LAT));
longitudeField.setText(当前经度:+将String.valueOf(LON));
currentSpeedField.setText(当前速度(m /秒):+将String.valueOf(currentSpeed));
kmphSpeedField.setText(Cuttent速度(KMPH):+将String.valueOf(kmphSpeed));
avgSpeedField.setText(平均速度(m /秒):+将String.valueOf(avgSpeed));
avgKmphField.setText(平均速度(KMPH):+将String.valueOf(avgKmph));
}
//并不完全知道这些干什么还
公共无效onStatusChanged(字符串商,INT地位,捆绑演员){}
公共无效onProviderEnabled(字符串提供商){}
公共无效onProviderDisabled(字符串提供商){}
};
//注册监听器的位置管理器来接收位置更新
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,1,LocationListener的);
}
//方法舍双打到最大的3位小数
公共静态双圆(双圆唇,诠释precision,INT则roundingMode)
{
BigDecimal的BD =新的BigDecimal(未取整);
BigDecimal的圆润= bd.setScale(precision,则roundingMode);
返回rounded.doubleValue();
}
@覆盖
公共无效onLocationChanged(位置定位){
// TODO自动生成方法存根
}
@覆盖
公共无效onProviderDisabled(字符串提供商){
// TODO自动生成方法存根
}
@覆盖
公共无效onProviderEnabled(字符串提供商){
// TODO自动生成方法存根
}
@覆盖
公共无效onStatusChanged(字符串商,INT地位,捆绑演员){
// TODO自动生成方法存根
}
}
新的code:
包Hartford.gps;
进口android.app.Activity;
进口android.content.Context;
进口android.content.Intent;
进口android.os.Bundle;
进口android.os.PowerManager;
进口android.widget.TextView;
公共类GPSMain延伸活动{
//文本视图来显示经纬度
静态的TextView latituteField;
静态的TextView longitudeField;
静态的TextView currentSpeedField;
静态的TextView kmphSpeedField;
静态的TextView avgSpeedField;
静态的TextView avgKmphField;
静态的TextView topSpeedField;
静态的TextView topKmphField;
//对象来存储位置信息
受保护的静态双重纬度;
受保护的静态双经度;
//对象来存储值电流和平均车速
受保护的静态双currentSpeed;
受保护的静态双kmphSpeed;
受保护的静态双avgSpeed;
受保护的静态双avgKmph;
受保护的静态双totalSpeed;
受保护的静态双totalKmph;
受保护的静态双极速= 0;
受保护的静态双topKmph = 0;
//计数器,每接收到一个新的位置时递增,用于计算平均车速
静态INT计数器= 0;
/ **第一次创建活动时调用。 * /
@覆盖
公共无效的onCreate(包savedInstanceState){
super.onCreate(savedInstanceState);
的setContentView(R.layout.main);
电源管理器电源管理器=(电源管理器)getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock器wL = powerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,我的标签);
wL.acquire();
startService(新意图(这一点,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);
}
静态无效的run(){
latituteField.setText(当前纬度:+将String.valueOf(LAT));
longitudeField.setText(当前经度:+将String.valueOf(LON));
currentSpeedField.setText(当前速度(m /秒):+将String.valueOf(currentSpeed));
kmphSpeedField.setText(Cuttent速度(KMPH):+将String.valueOf(kmphSpeed));
avgSpeedField.setText(平均速度(m /秒):+将String.valueOf(avgSpeed));
avgKmphField.setText(平均速度(KMPH):+将String.valueOf(avgKmph));
topSpeedField.setText(最高速度(米/秒):+将String.valueOf(极速));
topKmphField.setText(最高速度(KMPH):+将String.valueOf(topKmph));
}
}
和
包Hartford.gps;
进口的java.math.BigDecimal;
进口android.app.Service;
进口android.content.Context;
进口android.content.Intent;
进口android.location.Criteria;
进口android.location.Location;
进口android.location.LocationListener;
进口android.location.LocationManager;
进口android.os.Bundle;
进口android.os.IBinder;
进口android.util.Log;
进口android.widget.Toast;
公共类计算扩展服务实现LocationListener的{
静态LocationManager locationManager;
LocationListener的LocationListener的;
私有静态最后字符串变量=计算;
@覆盖
公众的IBinder onBind(意向意图){
// TODO自动生成方法存根
返回null;
}
@覆盖
公共无效的onCreate(){
Toast.makeText(这一点,我的服务创建,Toast.LENGTH_LONG).show();
Log.d(TAG的onCreate);
跑();
}
私人无效的run(){
最终标准标准=新标准();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setSpeedRequired(真正的);
criteria.setAltitudeRequired(假);
criteria.setBearingRequired(假);
criteria.setCostAllowed(真正的);
criteria.setPowerRequirement(Criteria.POWER_LOW);
//获取一个参考系统位置管理
locationManager =(LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
//定义一个监听器,响应位置更新
LocationListener的=新LocationListener的(){
公共无效onLocationChanged(位置newLocation){
GPSMain.counter ++;
//当前速度的GPS设备
GPSMain.currentSpeed =圆(newLocation.getSpeed(),3,BigDecimal.ROUND_HALF_UP);
GPSMain.kmphSpeed = ROUND((GPSMain.currentSpeed * 3.6),3,BigDecimal.ROUND_HALF_UP);
如果(GPSMain.currentSpeed> GPSMain.topSpeed){
GPSMain.topSpeed = GPSMain.currentSpeed;
}
如果(GPSMain.kmphSpeed> GPSMain.topKmph){
GPSMain.topKmph = GPSMain.kmphSpeed;
}
//所有速度加在一起
GPSMain.totalSpeed = GPSMain.totalSpeed + GPSMain.currentSpeed;
GPSMain.totalKmph = GPSMain.totalKmph + GPSMain.kmphSpeed;
//计算平均速度
GPSMain.avgSpeed = ROUND(GPSMain.totalSpeed / GPSMain.counter,3,BigDecimal.ROUND_HALF_UP);
GPSMain.avgKmph = ROUND(GPSMain.totalKmph / GPSMain.counter,3,BigDecimal.ROUND_HALF_UP);
//获取位置
GPSMain.lat = ROUND(((双)(newLocation.getLatitude())); 3,BigDecimal.ROUND_HALF_UP);
GPSMain.lon = ROUND(((双)(newLocation.getLongitude())); 3,BigDecimal.ROUND_HALF_UP);
GPSMain.run();
}
//并不完全知道这些干什么还
公共无效onStatusChanged(字符串商,INT地位,捆绑演员){}
公共无效onProviderEnabled(字符串提供商){}
公共无效onProviderDisabled(字符串提供商){}
};
//注册监听器的位置管理器来接收位置更新
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,1,LocationListener的);
}
//方法舍双打到最大的3位小数
公共静态双圆(双圆唇,诠释precision,INT则roundingMode)
{
BigDecimal的BD =新的BigDecimal(未取整);
BigDecimal的圆润= bd.setScale(precision,则roundingMode);
返回rounded.doubleValue();
}
公共无效onLocationChanged(位置定位){
// TODO自动生成方法存根
}
公共无效onProviderDisabled(字符串提供商){
// TODO自动生成方法存根
}
公共无效onProviderEnabled(字符串提供商){
// TODO自动生成方法存根
}
公共无效onStatusChanged(字符串商,INT地位,捆绑演员){
// TODO自动生成方法存根
}
}
更新shababhsiddique
进口java.math.BigDecimal的;
进口java.text.DecimalFormat中;
进口java.text.NumberFormat中;
进口android.app.Service;
进口android.content.Context;
进口android.content.Intent;
进口android.location.Criteria;
进口android.location.Location;
进口android.location.LocationListener;
进口android.location.LocationManager;
进口android.os.Bundle;
进口android.os.IBinder;
进口android.util.Log;
进口android.widget.Toast;
公共类计算延伸服务{
静态LocationManager locationManager;
静态LocationListener的LocationListener的;
私有静态长timerTime = 1;
私有静态浮动timerFloatValue = 1.0F;
私人上下文的背景下;
私人INT计数器= 0;
@覆盖
公众的IBinder onBind(意向意图){返回null;}
@覆盖
公共无效的onCreate(){
上下文=这一点;
更新();
}
保护无效更新(){
最终标准标准=新标准();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setSpeedRequired(真正的);
criteria.setAltitudeRequired(假);
criteria.setBearingRequired(假);
criteria.setCostAllowed(真正的);
criteria.setPowerRequirement(Criteria.POWER_LOW);
//获取一个参考系统位置管理
locationManager =(LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
//定义一个监听器,响应位置更新
LocationListener的=新LocationListener的(){
公共无效onLocationChanged(位置newLocation){
反++;
如果(GPSMain.GPSHasStarted == 0){
GPSMain previousLocation = newLocation。
//获取位置
GPSMain.lat = ROUND(((双)(GPSMain previousLocation.getLatitude())); 3,BigDecimal.ROUND_HALF_UP。);
GPSMain.lon = ROUND(((双)(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(背景下,全球定位系统已建立连接,Toast.LENGTH_LONG).show();
startService(新意图(背景下,AccelerometerReader.class));
Toast.makeText(上下文中,加速度计算,Toast.LENGTH_LONG).show();
Toast.makeText(背景下,!一路平安,Toast.LENGTH_LONG).show();
}
//获取位置
GPSMain.lat = ROUND(((双)(newLocation.getLatitude())); 3,BigDecimal.ROUND_HALF_UP);
GPSMain.lon = ROUND(((双)(newLocation.getLongitude())); 3,BigDecimal.ROUND_HALF_UP);
如果(newLocation.distanceTo(GPSMain previousLocation)> 2.0f){
GPSMain.distanceBetweenPoints = GPSMain.distanceBetweenPoints + newLocation.distanceTo(GPSMain previousLocation。);
}
//当前速度的GPS设备
GPSMain.mpsSpeed = newLocation.getSpeed();
如果(GPSMain.mpsSpeed> GPSMain.topMps){GPSMain.topMps = GPSMain.mpsSpeed;}
//为了下一次迭代中计算出的距离存储位置。
GPSMain previousLocation = newLocation。
如果(计数器%20 == 0){
GPSMain.routeLat.add(Double.toString(GPSMain previousLocation.getLatitude()));
GPSMain.routeLon.add(Double.toString(GPSMain previousLocation.getLongitude()));
}
}
//并不完全知道这些干什么还
公共无效onStatusChanged(字符串商,INT地位,捆绑演员){}
公共无效onProviderEnabled(字符串提供商){}
公共无效onProviderDisabled(字符串提供商){}
};
//注册监听器的位置管理器来接收位置更新
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,2000,20,LocationListener的);
}
//方法舍双打到最大的3位小数
公共静态双圆(双圆唇,诠释precision,诠释则roundingMode){
BigDecimal的BD =新的BigDecimal(未取整);
BigDecimal的圆润= bd.setScale(precision,则roundingMode);
返回rounded.doubleValue();
}
//格式以毫秒为单位考虑到时间分秒的时间
公共静态字符串getTimeTaken(长端,长开始){
@燮pressWarnings(未使用)
串formattedTime =,hourHour =,hourMin =:,MINSEC =:;
长timeTaken =年底启动,小时= 0,最小= 0,秒= 0;
timerTime = timeTaken;
timeTaken =(年底开始)/ 1000;
如果(timeTaken> 9){
hourHour =0;
hourMin =0;
如果(timeTaken> = 60){
如果(timeTaken> = 3200){
小时= timeTaken / 3200;
timeTaken = timeTaken%3200;
如果(小时> 9){
hourHour =;
}
}
分= timeTaken / 60;
timeTaken = timeTaken%60;
如果(分> 9){
hourMin =:;
}
}
秒= timeTaken;
如果(秒%60℃; 10){
MINSEC =0;
}
返回formattedTime =(hourHour +小时+ hourMin +分+ MINSEC +秒);
}
秒= timeTaken;
MINSEC =0;
hourMin =0;
hourHour =0;
返回formattedTime =(hourHour +小时+ hourMin +分+ MINSEC +秒);
}
公共静态双averageSpeed(){
//计算平均速度
如果(timerTime == 0){timerTime = 1;}
timerFloatValue =(浮点)timerTime;
timerFloatValue = timerFloatValue / 1000;
返回GPSMain.avgMps = GPSMain.distanceBetweenPoints / timerFloatValue;
}
//从加速度计舍入浮点值
静态字符串roundTwoDecimalFloat(浮起){
浮动B = A / 9.8f;
字符串formattedNum;
NumberFormat的NF =新的DecimalFormat();
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
formattedNum = nf.format(B);
返回formattedNum;
}
}
问题1:您必须获取的 WakeLock 。有多种类型wakelock的,这取决于如果你想只在CPU或同时在屏幕上。
问题2:你应该做你收集数据的东西里面服务并分离图形接口从收集的数据。该服务将继续下去,直到你停止它,如果你正确地执行它来收集数据。
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:
- prevent the screen from turning off while it is open on the screen
- if the user opens another app or returns to the home screen, gets a call etc, the app should keep collecting data (or would it be better to just write all data to a database everytime the location is updated? and maybe have a button to signify when to start and stop collecting data?)
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
}
}
BOTH PROBLEMS SOLVED THANKS TO ANSWERS FROM Marco Grassi AND Marcovena.
New Code:
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));
}
}
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
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;
}
}
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.
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屋!