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. requestLocationUpdates を有効にするために最大 100000 ミリ秒と距離を 500 上げても、静止していても 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に指定したパラメーターは非常に小さいです。minTimeの6000は6秒で、minDistanceは5メートルです。これにより、GPSが常にバッテリーを消耗しているため、これらのパラメーターを再検討することをお勧めします。

それを試して、ログを追加して何が起こるかを確認することをお勧めします。トーストを使用する代わりに、ロギングフレームワーク(つまり、:Log.v()Log.e()など)を使用してlogcatを確認することをお勧めします。トーストは、デバッグにはかなり信頼性がありません。

また、位置情報サービスの実装はすべてのデバイスで異なります。各メーカーは独自の実装を提供しており、信頼性、堅牢性、運用特性が大きく異なります。特定の間隔または特定の時間に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 に答える