3

我已经实现了一个启动时启动的 android 服务: MyService.java

package com.example.testservicelogging;

import com.example.testservicelogging.MyBroadcastReceiver;

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.os.Bundle;
import android.os.IBinder;
import android.widget.Toast;


public class MyService extends Service implements LocationListener {

    LocationManager lm;
    PendingIntent pendingIntent;
    LocationListener locationListener;

    public MyService() {
    }

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
      public int onStartCommand(Intent intent, int flags, int startId) {
        //TODO do something useful
        //Toast.makeText(getBaseContext(), "Got in!!!", Toast.LENGTH_SHORT).show();
        System.out.println("Got in");

         Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();        

            //---use the LocationManager class to obtain locations data---
            lm = (LocationManager)
                    getSystemService(Context.LOCATION_SERVICE);


            Intent i = new Intent(this, MyBroadcastReceiver.class);
            pendingIntent = PendingIntent.getBroadcast(
                    this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);

          //---request for location updates using GPS---
            lm.requestLocationUpdates(
                    LocationManager.GPS_PROVIDER,
                    6000,
                    5,
                    pendingIntent);     

        return START_STICKY;
      }


    @Override
    public void onDestroy() {
        //---remove the pending intent---
        lm.removeUpdates(pendingIntent);

        super.onDestroy();
        Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();        
    }

    @Override
    public void onLocationChanged(Location arg0) {
        // TODO Auto-generated method stub
        Toast.makeText(this, "onLocationChanged", Toast.LENGTH_LONG).show();   

    }

    @Override
    public void onProviderDisabled(String arg0) {
        // TODO Auto-generated method stub
        Toast.makeText(this, "onProviderDisabled", Toast.LENGTH_LONG).show();   

    }

    @Override
    public void onProviderEnabled(String arg0) {
        // TODO Auto-generated method stub
        Toast.makeText(this, "onProviderEnabled", Toast.LENGTH_LONG).show();   

    }

    @Override
    public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
        // TODO Auto-generated method stub
        Toast.makeText(this, "onStatusChanged", Toast.LENGTH_LONG).show();   

    }


}

也是一个BroadcastReceiver类:

package com.example.testservicelogging;

import java.io.IOException;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.util.Log;
import android.widget.Toast;


public class MyBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {


        Intent t=new Intent(context, MyService.class);
        t.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startService(t);

        String locationKey = LocationManager.KEY_LOCATION_CHANGED;
        String providerEnabledKey = LocationManager.KEY_PROVIDER_ENABLED;

        //Toast.makeText(context, "INSIDE!!!", Toast.LENGTH_SHORT).show(); 
        System.out.println("INSIDE");

        if (intent.hasExtra(providerEnabledKey)) {
            if (!intent.getBooleanExtra(providerEnabledKey, true)) {
                Toast.makeText(context,
                        "Provider disabled",
                        Toast.LENGTH_SHORT).show();              
            } else {
                Toast.makeText(context,
                        "Provider enabled",
                        Toast.LENGTH_SHORT).show();
            }
        }

        if (intent.hasExtra(locationKey)) {
            Location loc = (Location)intent.getExtras().get(locationKey);
            Toast.makeText(context,
                    "Location changed : Lat: " + loc.getLatitude() +
                    " Lng: " + loc.getLongitude(),
                    Toast.LENGTH_SHORT).show();



            //do something with the coordinates returned


        }

    }


}

我面临一些问题:

  1. (也是最重要的):启动时加载服务,但即使我看到 GPS 图标闪烁,它也永远不会返回坐标!!!我做错了什么??
  2. 我想以预定义的时间间隔获取坐标(例如,每天从 08:00 到 18:00 每 15 分钟一次)。我该如何实施?
  3. 即使我提高了 100000 毫秒和 500 距离来激活 requestLocationUpdates,即使我保持不动,它有时也会每 2-5 秒运行一次!!!我该如何克服呢?

非常感谢你的帮助 !!!

4

2 回答 2

1

您正在请求位置更新并提供PendingIntent在位置更新发生时应广播的内容。但是,您的服务也是implements LocationListener如此,看起来您可能有点困惑。我不确定您到底想在这里做什么,但首先我会让您的服务直接获取回调。在这种情况下,您不需要BroadcastReceiver并且您应该更改它:

//---request for location updates using GPS---
lm.requestLocationUpdates(
    LocationManager.GPS_PROVIDER, 6000, 5, pendingIntent);

对此:

//---request for location updates using GPS---
lm.requestLocationUpdates(
    LocationManager.GPS_PROVIDER, 6000, 5, this);

这将导致位置服务定期回调您已经在服务类( , 等)中实现onLocationChanged()onProviderEnabled()方法

此外,您为 minTime 和 minDistance 提供的参数非常小。6000 的 minTime 是 6 秒,minDistance 是 5 米。这将导致 GPS 不断消耗电池电量,因此您可能需要重新考虑这些参数。

我建议您尝试一下并添加一些日志记录以查看会发生什么。我建议使用日志框架(即:Log.v()andLog.e()等)并查看 logcat 而不是尝试使用 toast。Toast 对于调试来说是非常不可靠的。

此外,所有设备上的位置服务实现方式都不同。每个制造商都提供自己的实施方案,它们在可靠性、稳健性和操作特性方面差异很大。没有办法可靠地坚持以特定间隔或特定时间进行 GPS 更新。您所能做的就是向操作系统提供有关您想要的内容的适当提示。无论您指定的参数如何,位置框架都会随时给您回电。您只需要了解这一点并相应地编写代码。

如果您想每 15 分钟获取一次更新,您可以指定 15 分钟 minTime(其值为 15 * 60 * 1000),或者您可以每 15 分钟使用警报管理器安排一次唤醒警报,并在警报响起时关闭后,您可以立即请求位置更新(尽管您可能需要一些时间才能获得它们)。

希望我已经为您提供了足够的材料,以便您可以在这里取得一些进展。如果您需要更多帮助,请随时添加评论。

于 2013-03-14T21:06:35.850 回答
1

根据您的需要,确保将其中任何一个添加到清单中:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
于 2013-03-14T21:06:47.270 回答