2011-06-20 7 views
0

LocalServiceActivities.javaBasics of Android : Part III – Android Servicesを使用して動作するローカルサービスサンプルを最終的に得ました。Androidサービスはゲッターを使用します

/************************************************************************************************** 
* Filename: Controller.java 
* Project name: Local Service Sample 
* Application name: Local Service 
* Description: This file contains the primary activity for this application 
**************************************************************************************************/ 
package com.marie.localservicesample; 

import android.app.Activity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.os.Messenger; 
import android.util.Log; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 

/* 
* Example of explicitly starting and stopping the local service. 
* This demonstrates the implementation of a service that runs in the same 
* process as the rest of the application, which is explicitly started and stopped 
* as desired. 
*/ 
//public static class Controller extends Activity { 
public class Controller extends Activity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.local_service_controller); 

     // Watch for button clicks. 
     Button button = (Button)findViewById(R.id.start); 
     button.setOnClickListener(mStartListener); 
     button = (Button)findViewById(R.id.stop); 
     button.setOnClickListener(mStopListener); 
    } 

    private OnClickListener mStartListener = new OnClickListener() { 
     public void onClick(View v) { 
      // Make sure the service is started. It will continue running 
      // until someone calls stopService(). The Intent we use to find 
      // the service explicitly specifies our service component, because 
      // we want it running in our own process and don't want other 
      // applications to replace it. 
      //startService(new Intent(Controller.this, LocalService.class)); 

      Intent startSvc = new Intent(Controller.this, LocalService.class); 
      startSvc.putExtra(LocalService.EXTRA_MESSENGER, new Messenger(handler)); 
      startSvc.putExtra(LocalService.EXTRA_SONG, 7); 
      startService(startSvc); 

      Intent binding = new Intent(Controller.this, Binding.class); 
      startActivity(binding); 
     } 
    }; 

    private OnClickListener mStopListener = new OnClickListener() { 
     public void onClick(View v) { 
      // Cancel a previous call to startService(). Note that the 
      // service will not actually stop at this point if there are 
      // still bound clients. 
      stopService(new Intent(Controller.this, 
        LocalService.class)); 
     } 
    }; 

    /* 
    * This is a handler to be passed to the Service via a Messenger. 
    */ 
    private Handler handler = new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 
      // simple handler test 
      String obj = (String) msg.obj; 
      Log.i("handleMessge", "obj: " + obj); 
     } 
    }; 
} 

/************************************************************************************************** 
* Filename: LocalService.java 
* Project name: Local Service Sample 
* Application name: Local Service 
* Description: This file contains a local service 
**************************************************************************************************/  
package com.marie.localservicesample; 

import android.app.Notification; 
import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.app.Service; 
import android.content.Intent; 
import android.os.Binder; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.os.Message; 
import android.os.Messenger; 
import android.os.RemoteException; 
import android.util.Log; 
import android.widget.Toast; 

public class LocalService extends Service { 
    private NotificationManager mNM; 

    // Unique Identification Number for the Notification. 
    // We use it on Notification start, and to cancel it. 
    //private int NOTIFICATION = R.string.local_service_started; 
    private int NOTIFICATION = R.string.local_service_started; 

    private int statusCode = 10; 

    // This is the object that receives interactions from clients. See 
    // RemoteService for a more complete example. 
    private final IBinder mBinder = new LocalBinder(); 

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

    /** 
    * Class for clients to access. Because we know this service always 
    * runs in the same process as its clients, we don't need to deal with 
    * IPC. 
    */ 
    public class LocalBinder extends Binder implements ILocalService { 
     LocalService getService() { 
      return LocalService.this; 
     } 

     @Override 
     public int getStatusCode() { 
      return statusCode; 
     } 
    } 

    public static final String EXTRA_MESSENGER = "com.marie.localservicesample.EXTRA_MESSENGER"; 
    private Messenger messenger; 

    public static final String EXTRA_SONG = "com.marie.localservicesample.EXTRA_SONG"; 
    private int song; 

    @Override 
    public void onCreate() { 
     mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); 

     // Display a notification about us starting. We put an icon in the status bar. 
     showNotification(); 

     Thread thr = new Thread(null, new ServiceWorker(), "BackgroundService"); 
     thr.start();   
    } 

    /* 
    * This is the ServiceWorker thread that passes messages to the handler defined in 
    * the MainActivity class. 
    * NOTE: Instead of passing messages to a handler in MainActivity I would like 
    * it to pass messages to a handler defined in the RcvMessages activity. 
    */ 
    class ServiceWorker implements Runnable 
    { 
     public void run() { 
      // do background processing here... something simple 

      while (messenger == null); 

      // send a message to the handler 
      try { 
       Message msg = Message.obtain(); 
       msg.obj = "Hello " + "Song " + song; 
       msg.arg1 = song; 
       messenger.send(msg); 
      } catch (RemoteException e) { 
       e.printStackTrace(); 
      } catch (NullPointerException e) { 
       e.printStackTrace(); 
      } 

      // stop the service when done... 
      // LocalService.this.stopSelf(); 
      // Or use the unbindBtn in the MainActivity class. 
     } 
    } 


    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     Log.i("LocalService", "Received start id " + startId + ": " + intent); 

     Bundle extras = intent.getExtras(); 

     messenger = (Messenger)extras.get(EXTRA_MESSENGER); 
     try { 
      song = (Integer) extras.get(EXTRA_SONG); 
     } catch (NullPointerException e) { 
      e.printStackTrace(); 
      song = 0; 
     } 

     // We want this service to continue running until it is explicitly 
     // stopped, so return sticky. 
     return START_STICKY; 
    } 

    @Override 
    public void onDestroy() { 
     // Cancel the persistent notification. 
     mNM.cancel(NOTIFICATION); 

     // Tell the user we stopped. 
     Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show(); 
    } 

    /** 
    * Show a notification while this service is running. 
    */ 
    private void showNotification() { 
     // In this sample, we'll use the same text for the ticker and the expanded notification 
     CharSequence text = getText(R.string.local_service_started); 

     // Set the icon, scrolling text and timestamp 
     Notification notification = new Notification(R.drawable.stat_sample, text, 
       System.currentTimeMillis()); 

     // The PendingIntent to launch our activity if the user selects this notification 
     //PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, LocalServiceActivities.Controller.class), 0); 
     PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, Controller.class), 0); 

     // Set the info for the views that show in the notification panel. 
     notification.setLatestEventInfo(this, getText(R.string.local_service_label), 
         text, contentIntent); 

     // Send the notification. 
     mNM.notify(NOTIFICATION, notification); 
    } 

    /* Duplicate added by Eclipse 
    @Override 
    public IBinder onBind(Intent intent) { 
     // TODO Auto-generated method stub 
     return null; 
    } 
    */ 
} 

/************************************************************************************************** 
* Filename: Binding.java 
* Project name: Local Service Sample 
* Application name: Local Service 
* Description: This file contains the binding for this application 
**************************************************************************************************/ 
package com.marie.localservicesample; 

import android.app.Activity; 
import android.content.ComponentName; 
import android.content.Context; 
import android.content.Intent; 
import android.content.ServiceConnection; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.util.Log; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.Toast; 

/* 
* Example of binding and unbinding to the local service. 
* This demonstrates the implementation of a service which the client will 
* bind to, receiving an object through which it can communicate with the service. 
*/ 
public class Binding extends Activity { 
    private boolean mIsBound; 

    private LocalService mBoundService; 

    private ServiceConnection mConnection = new ServiceConnection() { 
     public void onServiceConnected(ComponentName className, IBinder service) { 
      // This is called when the connection with the service has been 
      // established, giving us the service object we can use to 
      // interact with the service. Because we have bound to a explicit 
      // service that we know is running in our own process, we can 
      // cast its IBinder to a concrete class and directly access it. 
      mBoundService = ((LocalService.LocalBinder)service).getService(); 

      ILocalService localService = (ILocalService)service; 
      int statusCode = localService.getStatusCode(); 

      Log.d("Binding","called onServiceConnected. statusCode: " + statusCode); 

      Toast.makeText(Binding.this, R.string.local_service_connected, 
        Toast.LENGTH_SHORT).show(); 
     } 

     public void onServiceDisconnected(ComponentName className) { 
      // This is called when the connection with the service has been 
      // unexpectedly disconnected -- that is, its process crashed. 
      // Because it is running in our same process, we should never 
      // see this happen. 
      mBoundService = null; 

      Log.d("Binding", "called onServiceDisconnected"); 

      Toast.makeText(Binding.this, R.string.local_service_disconnected, 
        Toast.LENGTH_SHORT).show(); 
     } 
    }; 

    void doBindService() { 
     // Establish a connection with the service. We use an explicit 
     // class name because we want a specific service implementation that 
     // we know will be running in our own process (and thus won't be 
     // supporting component replacement by other applications). 
     bindService(new Intent(Binding.this, 
       LocalService.class), mConnection, Context.BIND_AUTO_CREATE); 
     mIsBound = true; 
    } 

    void doUnbindService() { 
     if (mIsBound) { 
      // Detach our existing connection. 
      unbindService(mConnection); 
      mIsBound = false; 
     } 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     doUnbindService(); 
    } 

    private OnClickListener mBindListener = new OnClickListener() { 
     public void onClick(View v) { 
      doBindService(); 
     } 
    }; 

    private OnClickListener mUnbindListener = new OnClickListener() { 
     public void onClick(View v) { 
      doUnbindService(); 
     } 
    }; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.local_service_binding); 

     // Watch for button clicks. 
     Button button = (Button)findViewById(R.id.bind); 
     button.setOnClickListener(mBindListener); 
     button = (Button)findViewById(R.id.unbind); 
     button.setOnClickListener(mUnbindListener); 
    } 
} 

/************************************************************************************************** 
* Filename: ILocalService.java 
* Project name: Local Service Sample 
* Application name: Local Service 
* Description: This file contains an example interface for LocalService 
**************************************************************************************************/ 

package com.marie.localservicesample; 

public interface ILocalService { 

    // An example method for ILocalService 
    public int getStatusCode(); 

} 

私の質問は、なぜ誰もが提供したいです:ここでは

は私のコードController.java、LocalService.java、Binding.java、およびILocalService.javaはすべて一緒にコメントヘッダで区切って次々と焼きますILocalService.javaは既にスレッドとハンドラを持つstartService()を持っていればいいですか?私のILocalService.javaは、statusCodeを求める簡単なデモです。私の知る限りでは、ILocalService.javaはステータスのゲッターとセッターなしで構成されます。だから私は私のローカルサービスのステータス情報を求めているだけですか?私のローカルサービスへのセッターの例は何ですか?

答えて

1

あなたのバインダーは、次のようになります。興味のある

public class LocalBinder extends Binder implements ILocalService { 
     LocalService getService() { 
      return LocalService.this; 
     } 

     @Override 
     public int getStatusCode() { 
      return statusCode; 
     } 
    } 

キー部分がgetServiceです。つまり、サービスにバインドするアクティビティ(ローカルサービスであるため)は実際にサービスオブジェクトを取得し、ゲッターだけでなくそのサービス関数でANY関数を呼び出すことができます。 startServiceIntentという狭い通信チャネルだけに限定されず、サービスオブジェクトの完全なメソッドインタフェースがあります。過去に私はBluetoothDeviceのインスタンス、Handlerのインスタンス、および他の複雑なJavaオブジェクトをサービスオブジェクトに渡しました。

+0

@フェミ、まだ混乱しています。 "bindService(new Intent(Binding.this、LocalService.class)、mConnection、Context.BIND_AUTO_CREATE);"というように、しかし、私はどのようにしてサービスオブジェクトを入手し、それを使用してそのサービス機能上の任意の機能を呼び出すのか分かりません。私ができることは「ILocalService localSvc =(ILocalService)サービス; int statusCode = localSvc.getStatusCode();」です。 onServiceConnected()内にあります。 "mBoundService =((LocalService.LocalBinder)サービス).getService();"とは何ですか?私はもう少し助けてください。 – Marie

+0

@フェミあなたは私の質問の元の意図に答えたので、私はあなたの答えを受け入れます。しかし、私の前のコメントを見てください。私は新しい質問をするべきですか? – Marie

+0

@Marie、 'mBoundService'は、実際にAndroidプラットフォームによって開始されたサービスのコピーです。これを使用して、Serviceクラスで定義されているJavaメソッドにアクセスすることができます(たとえば、実際には 'stopSelf();'を呼び出してアクティビティから直接サービスを停止することもできますし、独自のメソッドを作成して呼び出すそれら)。私は同じパターンを使用して、Sservice上でログを記録するなどの方法を開始/停止します。 – Femi

関連する問題