【问题标题】:android background service get locationandroid后台服务获取位置
【发布时间】:2013-03-14 03:53:20
【问题描述】:

我创建了一个可以启动后台服务的应用程序。此服务的目的是监控手机上使用的应用程序,并将此数据与时间戳和坐标一起保存到手机上的 SQLite。

找到应用程序并使用时间戳保存的部分工作正常。但是该位置的部分不起作用。我以前曾与 locationlisteners 合作过,但经过数小时和多次尝试后,我放弃了。 我不确定在哪里放置我的位置监听器?现在我已经创建了一个新的内部类,但是当我运行它时,我得到一个错误,说我需要运行 Looper.prepare() 但这没有帮助。然后它说每个线程只能创建一个looper。

我现在觉得无论我尝试什么其他方法都是错误的,因此我希望你们中的一些人可以帮助我。

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();

}

}

【问题讨论】:

    标签: android service android-asynctask location


    【解决方案1】:

    你把事情弄得太复杂了,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;
    }
    

    【讨论】:

    • 谢谢,但这并不能解决我在这种情况下运行另一个内部类“MyLocationListener”的问题
    【解决方案2】:

    我现在已经通过在“DoOnBackgroundTasK”上使用实现 LocationListener 并删除了另一个内部类 MyLocationListener 来解决它。虽然我曾尝试过,但现在它可以工作了。虽然只使用 NETWORK_PROVIDER,但如果我使用 PASSIVE_PROVIDER,我会得到一个 RuntimeException。对此有何解释?

    我已经粘贴了代码

     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();
    
    }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2013-12-30
      • 2013-05-06
      • 1970-01-01
      • 1970-01-01
      • 2021-01-17
      • 2020-03-12
      • 1970-01-01
      • 2015-07-28
      • 1970-01-01
      相关资源
      最近更新 更多