2016-10-24 7 views
1

私のAndroidアプリケーションでは、「サービス」クラス内で「LocationService」を使用しています。 にアクティビティ間で永続的なロケーションチェックを持たせるために、この練習をいくつかのチュートリアルでお勧めします。しかし、そこにいくつかの良い文書があるにもかかわらず、私はまだ活動と私のサービス間の通信についての に関する質問があります。Androidサービス:活動の良い実践 - サービスコミュニケーション

これは私のLocationServiceクラスです:

... 
@Override 
public void onCreate() { 
    super.onCreate(); 

    if(!LocationService.isRunning()) { 
     Intent intent = new Intent(this, LocationService.class); 
     startService(intent); 
    } 
} 
... 

そして、これは私のActivityクラスです:

public class LocationService extends Service { 

    public static LocationManager locationManager; 
    public static LocationListener listener; 
    private static Location currentLocation = null; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
    } 

    @Override 
    public void onStart(Intent intent, int startId) { 

     locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
     listener = new LocationListener() { 

      @Override 
      public void onLocationChanged(Location location) { 
       currentLocation = location; 
       System.out.println("Current Location: " + currentLocation); 
      } 

      @Override 
      public void onStatusChanged(String s, int i, Bundle bundle) { 
      } 

      @Override 
      public void onProviderEnabled(String s) { 
      } 

      @Override 
      public void onProviderDisabled(String s) { 
      } 
     }; 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public void onDestroy() { 
     locationManager.removeUpdates(listener); 
    } 

    public static Location getCurrentLocation() { 
     return currentLocation; 
    } 

は、これは私の世界クラスの一部である

public class ScreenActivity extends FragmentActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.screen); 
    } 

    if (usesPosition) { 
     Location tLoc = LocationService.getCurrentLocation(); 
     TextView t = (TextView) findViewById(R.id.tv); 
     t.setText(tLoc.toString()); 
    } 
} 

私はこのように感じますエレガントな方法ではなく、間違っている可能性もあります。私は良い場所を取得するが、私はサービスにアクセスしないように感じるが、 ではなく静的クラスのように扱う。私はまだアクティビティをバインディングするというコンセプトに精通していないので、実際にそれを行うには が必要かどうかと思います。最初の答えを

EDIT 1

ありがとう!それは私をもう少し助けてくれました。

myBinder
private ServiceConnection locationServiceConnection = new ServiceConnection() { 
    @Override 
    public void onServiceDisconnected(ComponentName name) { 
     locationServiceBound = false; 
     System.out.println("Service disconnected"); 
    } 

    @Override 
    public void onServiceConnected(ComponentName name, IBinder service) { 
     com.ma.sainz.geoobserver.Tools.Services.LocationService.MyBinder myBinder = (com.ma.sainz.geoobserver.Tools.Services.LocationService.MyBinder) service; 
     locationService = myBinder.getService(); 
     locationServiceBound = true; 
     System.out.println("Service bound"); 
    } 
}; 

LocationServiceで定義されたクラスである:これは今私のActivityクラスの一部です。 そして、それは私の新しいONSTART(ある) - 私の活動の方法:

@Override 
protected void onStart() { 
    super.onStart(); 

    Intent locationServiceIntent = new Intent(this, com.ma.sainz.geoobserver.Tools.Services.LocationService.class); 
    bindService(locationServiceIntent, locationServiceConnection, Context.BIND_AUTO_CREATE); 
    locationService.requestBackgroundLocation(); 
    System.out.println("onStart"); 
} 

startService(locationServiceIntent)は、前のアクティビティで行われます。

ただし、locationServiceはしばらくの間nullです。サービスの接続には時間がかかります。サービスがいつ接続されたかを知るには?

LocalBroadcastを実装したいと仮定すると、それはサービスの実装に追加されますか?あなたはそれをどのように始めるべきかについてヒントを持っていますか? locationUpdatesをすぐに送信すると、サービスが接続するのを待つことに気をつけることはないので、

+0

SOに関する質問は単一のトピックに関するものでなければならないので、ここではバインドされたサービスについては回答した​​くありません。一般に、 'onServiceConnected()'コールバックが呼び出されるまでサービスを使用しないでください。あなたのケースでは、 'onServiceConnected()'に 'locationService.requestBackgroundLocation();'を置き、何が起こるかを見ることができます。 – Vasiliy

+0

大丈夫です。私はonServiceConnected()関数の依存関係を見ていませんでした。うん、そんなにいいね。私はもう一回Broadcastsを気にします。今のところそれは私が望むように働いています。ありがとう! – s4inz

答えて

1

あなたが持っているものは、本当に良いデザインではありません。これについて考えてみましょう。通常、場所を取得するだけでなく、更新しておきたいと考えています。つまり、更新が発生したときにアクティビティに通知する必要があります。ここ

あなたが得たいくつかのオプション:

  1. バインドサービスと行う通常の方法は、(/登録、登録解除をリスナーに場所を得る)、それを呼び出し
  2. 使用LocalBroadcastManagerサービスから位置更新をブロードキャストするために、活動
  3. にはいくつかのイベントバス(私のお気に入り - GreenRobotのEventBus)を使用し
  4. サービスから位置情報の更新をブロードキャストするために、活動へ

私は個人的に後者の方法を使用します。サービスは場所の更新時にイベントバスに「スティッキー」イベントを投稿し、アクティビティはonResume()でこれらのイベントを照会し、更新を購読します。この方法では、Serviceは常に実行する必要はありません。場所が必要なときに起動し、希望する精度で場所を取得し、バッテリを消費しないようにサービスを停止します。

+0

ありがとう、それはスタートでした。私はサービスに縛られましたが、接続されるまで私のサービスはnullになりました。私は私の質問を編集し、私はいくつかのヒントに感謝するだろう:) – s4inz

0

はい、そうしないでください。これは賢明ではありませんが、メモリリークの原因にもなります。 Androidサービスを他のコンポーネントにバインドするには、https://developer.android.com/guide/components/bound-services.htmlを参照してください。 あなたのactvityまたは別のサービスは、あなたのロケーションサービスにバインドされ、インターフェイスthise ServiceProvidesを使用します。少なくとも1つの接続が残っていると、サービスが実行されていることに注意してください。サービスを開始してサービスにバインドし、サービスを停止するまで実行され、バインダーによってそのサービスからの明示的なインターフェイスを使用できるようになります。 もう1つの良いテクニック - EventBus(greenRobot)を使用して、アクティビティとサービスの間でスティッキーイベントを渡します。イベントは、別のコンポーネントが初期化され、そのイベントを受信するまで待機します。 onPauseおよびonResumeメソッドで、そのイベントを購読して購読を解除することができます。

関連する問題