2013-03-14 89 views
3

我實現了一個機器人的服務,開機啓動: MyService.java的Android服務LocationListener的未激活

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. (也是最重要的):引導時的服務負載,但即使我看到t他GPS圖標閃爍,它永遠不會返回座標!我做錯了什麼?
  2. 我想在預定義的時間間隔內獲取座標(例如,每天從08:00至18:00每15分鐘一次)。我怎樣才能實現呢?
  3. 即使我提高了100000毫秒和500的距離來激活requestLocationUpdates,它有時會每隔2-5秒運行一次,即使我保持靜止!我怎樣才能克服?

非常感謝您的幫助!

回答

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分鐘與警報管理器安排一次喚醒警報,當警報熄滅時,您可以立即請求位置更新(儘管您可能需要一些時間才能獲取它們)。

希望我已經爲您提供了足夠的材料,以便您可以在此取得一些進展。如果您需要更多幫助,請隨時添加評論。

1

確保任一一個被添加到清單的基礎上,你需要什麼:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>