简体   繁体   English

Android后台服务获取位置

[英]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.

相关问题 在后台服务中获取位置更新 - Android Studio - Get Location Updates in Background Service - Android Studio 如何在Android的后台服务中获取当前位置 - How to get current location in background service in android Android,位置服务在后台 - Android, location Service in the background android位置-应用程序处于后台状态时无法在服务中获取位置 - android location - cannot get location in service when app is background 使用Android中的后台服务获取当前位置的经度和纬度 - Get current location Latitude and Longitude using background service in android 如何使用Android中的后台服务每5分钟获取一次设备位置? - How to get device location every 5 minutes using background service in Android? 如何在Android中使用网络提供商的后台服务获取更新的位置? - How to get updated location using background service for Network provider in Android? Android - 如何在服务的后台获取位置更新 - Android - How do I get location updates in the background in a service 无需在Android中运行服务即可在后台获取位置更新 - Get Location updates in background without running Service in Android Android Xamarin 后台服务 - 每 x 分钟获取一次 GPS 位置? - Android Xamarin Background service - Get GPS Location every x minutes?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM