[英]android background service get location
I have created an app where it is possible to start an background service. 我创建了一个可以启动后台服务的应用程序。 This service purpose is to monitor which app that is used on phone and save this data together with an timestamp and a coordinates to an SQLite on the phone.
此服务的目的是监视手机上使用的应用程序,并将此数据以及时间戳和坐标保存到手机上的SQLite。
The part which find the app and saves it with a time stamp works fine. 找到应用程序并用时间戳保存的部分效果很好。 But the part with the location doenst work.
但是具有位置的部分确实起作用。 I have worked with locationslisteners before, but after many hours and many attempts I give up.
我以前曾与locationlistener合作,但是经过许多小时和许多尝试之后,我放弃了。 Im not quit sure where to place my locationlistener?
我不确定是否将位置监听器放在哪里? right now I have created a new inner class, but when i run it I get an error saying that I need to run Looper.prepare() but that doenst help.
现在,我已经创建了一个新的内部类,但是当我运行它时,我收到一条错误消息,说我需要运行Looper.prepare(),但确实会有所帮助。 Then it says only one looper may be created per thread.
然后,它说每个线程只能创建一个循环程序。
I feel now that no matter what i try something else is wrong and therefore I hope some of you guys can help me. 我现在觉得无论我尝试其他什么事情都是错误的,因此我希望你们中的一些人能够帮助我。
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();
}
}
You make things too complicated, doInBackground is in a thread already, so the code below should be Ok. 您使事情变得过于复杂,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;
}
I have solved it now by using implements LocationListener on 'DoOnBackgroundTasK' and removed the other inner class MyLocationListener. 我现在通过在'DoOnBackgroundTasK'上使用实现LocationListener来解决它,并删除了另一个内部类MyLocationListener。 Though I had try that, but now it works.
虽然我已经尝试过了,但是现在可以了。 Though only using NETWORK_PROVIDER, if I use PASSIVE_PROVIDER i get an RuntimeException.
虽然仅使用NETWORK_PROVIDER,但如果我使用PASSIVE_PROVIDER,则会收到RuntimeException。 What is the explanation to that?
这有什么解释?
I have pasted the code 我已经粘贴了代码
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();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.