android后台服务获取位置
我已经创建了一个可以启动后台服务的应用程序。此服务的目的是监视手机上使用的应用程序,并将此数据连同时间戳和坐标一起保存到手机上的SQLite 找到应用程序并用时间戳保存的部分工作正常。但是有位置的零件不起作用。我以前曾与locationslisteners合作过,但经过许多小时和多次尝试后,我放弃了。 我不知道我的位置在哪里?现在我已经创建了一个新的内部类,但是当我运行它时,我得到一个错误,说我需要运行Looper.prepare(),但这没有帮助。然后它说每个线程只能创建一个循环器 我现在觉得无论我尝试什么,其他的东西都是错误的,因此我希望你们中的一些人能帮助我android后台服务获取位置,android,service,android-asynctask,location,Android,Service,Android Asynctask,Location,我已经创建了一个可以启动后台服务的应用程序。此服务的目的是监视手机上使用的应用程序,并将此数据连同时间戳和坐标一起保存到手机上的SQLite 找到应用程序并用时间戳保存的部分工作正常。但是有位置的零件不起作用。我以前曾与locationslisteners合作过,但经过许多小时和多次尝试后,我放弃了。 我不知道我的位置在哪里?现在我已经创建了一个新的内部类,但是当我运行它时,我得到一个错误,说我需要运行Looper.prepare(),但这没有帮助。然后它说每个线程只能创建一个循环器 我现在觉得
package com.dtu.applogger;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
public class loggerService extends Service{
DBAdapter dbadapter;
public MyLocationListener mMyLocationListener;
private NotificationManager mNM;
private int NOTIFICATION = 10002; //Any unique number for this notification
protected String latitude;
protected String longitude;
int counter= 0;
static final int UPDATE_INTERVAL= 5000;
private Timer timer= new Timer();
public loggerService() {
// TODO Auto-generated constructor stub
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
private void showNotification() {
// In this sample, we'll use the same text for the ticker and the expanded notification
CharSequence text = "TITLE";
// Set the icon, scrolling text and timestamp
Notification notification = new Notification(R.drawable.call_log, text, System.currentTimeMillis());
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this, "Service is running", text, contentIntent);
// Send the notification.
mNM.notify(NOTIFICATION, notification);
}
public int onStartCommand(Intent intent, int flags, int startId){
//showNotification();
new DoBackgroundTask().execute();
Toast.makeText(this, "Service started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
private class DoBackgroundTask extends AsyncTask{
String oldPackageName = "com.dtu.applogger";
DBAdapter dbadapter = new DBAdapter(loggerService.this);
public DoBackgroundTask() {
}
protected String findApp(){
final LocationManager lm = (LocationManager) loggerService.this.getSystemService(Context.LOCATION_SERVICE);
ActivityManager am = (ActivityManager) loggerService.this.getSystemService(Activity.ACTIVITY_SERVICE);
String packageName = am.getRunningTasks(1).get(0).topActivity.getPackageName();
if(!packageName.equals(oldPackageName) && !packageName.equals("com.dtu.applogger")){
//save oldPackageName and packageName in DB
mMyLocationListener = new MyLocationListener();
lm.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, mMyLocationListener);
String lat = latitude;
String lng = longitude;
String mydate = java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime());
String txt = packageName + " : " + mydate;
dbadapter.open();
if(packageName.equals("com.android.launcher")){
dbadapter.saveLog(mydate, oldPackageName, lat, lng);
}else{
dbadapter.saveLog(mydate, packageName, lat, lng);
}
dbadapter.close();
oldPackageName = packageName;
return txt;
}
if(packageName.equals(oldPackageName)){
return null;
}
return null;
}
@Override
protected Object doInBackground(Object... params) {
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
String txt = findApp();
if(txt != null){
Log.d("APP OPEN", "===== " + txt.toString());
}
Log.d("loggerService", String.valueOf(++counter));
}
}, 0, UPDATE_INTERVAL);
// TODO Auto-generated method stub
return null;
}
}
private class MyLocationListener implements android.location.LocationListener{
@Override
public void onLocationChanged(Location location) {
int lat = (int) (location.getLatitude()*1E6);
int lng = (int) (location.getLongitude()*1E6);
latitude = Integer.toString(lat);
longitude = Integer.toString(lng);
// 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
}
}
public void onDestroy(){
super.onDestroy();
timer.cancel();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
你把事情弄得太复杂了,doInBackground已经在一个线程中了,所以下面的代码应该可以
@Override
protected Object doInBackground(Object... params)
{
while (!isCancelled())
{
String txt = findApp();
if(txt != null)
{
Log.d("APP OPEN", "===== " + txt.toString());
}
Log.d("loggerService", String.valueOf(++counter));
try
{
Thread.sleep(UPDATE_INTERVAL);
}
catch (InterruptedException e1)
{
}
}
return null;
}
我现在已经通过在“DoOnBackgroundTasK”上使用implements LocationListener解决了这个问题,并删除了另一个内部类MyLocationListener。虽然我试过,但现在它起作用了。虽然只使用网络\u提供程序,但如果使用被动\u提供程序,则会出现运行时异常。对此有何解释 我已经粘贴了代码
public class loggerService extends Service{
DBAdapter dbadapter;
private NotificationManager mNM;
private int NOTIFICATION = 10002; //Any unique number for this notification
protected String latitude;
protected String longitude;
int counter= 0;
static final int UPDATE_INTERVAL= 5000;
private Timer timer= new Timer();
public loggerService() {
// TODO Auto-generated constructor stub
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
private void showNotification() {
// In this sample, we'll use the same text for the ticker and the expanded notification
CharSequence text = "TITLE";
// Set the icon, scrolling text and timestamp
Notification notification = new Notification(R.drawable.call_log, text, System.currentTimeMillis());
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this, "Service is running", text, contentIntent);
// Send the notification.
mNM.notify(NOTIFICATION, notification);
}
public int onStartCommand(Intent intent, int flags, int startId){
//showNotification();
new DoBackgroundTask().execute();
Toast.makeText(this, "Service started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
private class DoBackgroundTask extends AsyncTask implements LocationListener{
String oldPackageName = "com.dtu.applogger";
DBAdapter dbadapter = new DBAdapter(loggerService.this);
public DoBackgroundTask() {
}
protected String findApp(){
ActivityManager am = (ActivityManager) loggerService.this.getSystemService(Activity.ACTIVITY_SERVICE);
String packageName = am.getRunningTasks(1).get(0).topActivity.getPackageName();
if(!packageName.equals(oldPackageName) && !packageName.equals("com.dtu.applogger")){
//save oldPackageName and packageName in DB
String lat = latitude;
String lng = longitude;
String mydate = java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime());
String txt = packageName + " : " + mydate;
dbadapter.open();
if(packageName.equals("com.android.launcher")){
dbadapter.saveLog(mydate, oldPackageName, lat, lng);
Log.d("LATITUDE ", lat.toString());
Log.d("LONGITUDE ", lng.toString());
}else{
dbadapter.saveLog(mydate, packageName, lat, lng);
}
dbadapter.close();
oldPackageName = packageName;
return txt;
}
if(packageName.equals(oldPackageName) || packageName.equals("com.dtu.applogger")){
return null;
}
return null;
}
protected void onPreExecute()
{
final LocationManager lm = (LocationManager) loggerService.this.getSystemService(Context.LOCATION_SERVICE);
//
//REQUEST LOCATION UPDATE WORKS WITH NETWORK BUT NOT WITH PASSIVE???
//
lm.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, this);
}
@Override
protected Object doInBackground(Object... params) {
while (!isCancelled()){
String txt = findApp();
if(txt != null){
Log.d("APP OPEN", "===== " + txt.toString());
}
Log.d("loggerService", String.valueOf(++counter));
try
{
Thread.sleep(UPDATE_INTERVAL);
}
catch (InterruptedException e1){
}
}
// TODO Auto-generated method stub
return null;
}
@Override
public void onLocationChanged(Location location) {
latitude = String.valueOf(location.getLatitude());
longitude = String.valueOf(location.getLongitude());
}
@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
}
}
public void onDestroy(){
super.onDestroy();
timer.cancel();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
Thx,但这并不能解决我在本例中运行另一个内部类“MyLocationListener”的问题