啟動Service的方式通常是呼叫Context.startService()方法.
一個Activity中有兩個按鈕, 分別處理啟動GPS的啟動與停止, 而有一個文字介面呈現啟動的GPS所傳回相關的資訊. 當啟動按鈕按下之後, 將會由Activity呼叫startService()啟動一個Service的生命周期:
1. onCreate()
2. onStartCommand()
3. onDestroy()
通常會在onCreate()中進行相關的初始化的程序, 而onStartCommand()負責主要的服務程序, 當Activity呼叫了stopService(), 就會使該Service進入到onDestroy()的程序.
此時Service負責蒐集目前GPS相關資訊, 並且將資料以sendBroadcast()方法發送給Activity, Activity會預先一個BroadcastReceiver務件負責接收, 並且將資料呈現在文字介面.
1. onCreate()
2. onStartCommand()
3. onDestroy()
通常會在onCreate()中進行相關的初始化的程序, 而onStartCommand()負責主要的服務程序, 當Activity呼叫了stopService(), 就會使該Service進入到onDestroy()的程序.
此時Service負責蒐集目前GPS相關資訊, 並且將資料以sendBroadcast()方法發送給Activity, Activity會預先一個BroadcastReceiver務件負責接收, 並且將資料呈現在文字介面.
首先, 先簡單處理顯示的版面配置:
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:id="@+id/service" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Service" /> <Button android:id="@+id/stop" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Stop" /> <TextView android:id="@+id/info" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
接著在Activity中加上一個自訂的BroadcastReceiver:
private class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { double Lat = intent.getDoubleExtra("Lat", 0.0); double Long = intent.getDoubleExtra("Long", 0.0); float Accuracy = intent.getFloatExtra("Accuracy", 0.0f); float Bearing = intent.getFloatExtra("Bearing", 0.0f); float Speed = intent.getFloatExtra("Speed", 0.0f); long Time = intent.getLongExtra("Time", 0); info.setText("Lat: " + Lat + "\n" + "Long" + Long + "\n" + "Accuracy" + Accuracy + "\n" + "Bearing" + Bearing + "\n" + "Speed" + Speed + "\n" + "Time" + Time + "\n" ); } }
上段程式重點如下:
- 繼承 extends BroadcastReceiver, 並Override onReceive()方法
- 假設將會收到一個Intent物件, 其內含地理位置資訊資料.
- 取出資料後, 呈現在 info 的TextView物件中.
回到Activity中:
MyReceiver receiver = new MyReceiver(); IntentFilter filter = new IntentFilter("MyFilter"); registerReceiver(receiver, filter);
上段程式重點如下:
- 建構出前段程式中自訂的 MyReceive 物件
- 建構特定的 IntentFilter 物件, 只處理 "MyFilter" 的 Intent.
- 註冊 Receiver, 之後只要收到 Broadcast 後, 觸發 onReceive() 方法
將按鈕及其他部份處理上去:
package tw.brad.android.test.ServiceTest; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class ServiceTest extends Activity { private Button service,stop; private TextView info; private MyReceiver receiver; private IntentFilter filter; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); service = (Button)findViewById(R.id.service); stop = (Button)findViewById(R.id.stop); info = (TextView)findViewById(R.id.info); info.setText("Stop Service"); receiver = new MyReceiver(); filter = new IntentFilter("MyFilter"); registerReceiver(receiver, filter); service.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { Intent intent = new Intent(); intent.putExtra("mode", true); intent.setClass(ServiceTest.this, MyService.class); startService(intent); } }); stop.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { Intent intent = new Intent(); intent.putExtra("mode", false); intent.setClass(ServiceTest.this, MyService.class); startService(intent); info.setText("Stop Service"); } }); } private class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { double Lat = intent.getDoubleExtra("Lat", 0.0); double Long = intent.getDoubleExtra("Long", 0.0); float Accuracy = intent.getFloatExtra("Accuracy", 0.0f); float Bearing = intent.getFloatExtra("Bearing", 0.0f); float Speed = intent.getFloatExtra("Speed", 0.0f); long Time = intent.getLongExtra("Time", 0); info.setText("Lat: " + Lat + "\n" + "Long" + Long + "\n" + "Accuracy" + Accuracy + "\n" + "Bearing" + Bearing + "\n" + "Speed" + Speed + "\n" + "Time" + Time + "\n" ); } } }
接下來將重點放在 Service:
package tw.brad.android.test.ServiceTest; import android.app.Service; import android.content.Intent; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.os.IBinder; public class MyService extends Service { private LocationManager lm; private MyLocationListener mll; @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub return null; } @Override public void onCreate() { super.onCreate(); lm = (LocationManager)getSystemService(LOCATION_SERVICE); mll = new MyLocationListener(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { boolean mode = intent.getBooleanExtra("mode", true); if (mode){ lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10, 0, mll); }else { lm.removeUpdates(mll); } return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); lm.removeUpdates(mll); } private class MyLocationListener implements LocationListener { @Override public void onLocationChanged(Location location) { Intent intent = new Intent("MyFilter"); intent.putExtra("Lat", location.getLatitude()); intent.putExtra("Long", location.getLongitude()); intent.putExtra("Accuracy", location.getAccuracy()); intent.putExtra("Bearing", location.getBearing()); intent.putExtra("Speed", location.getSpeed()); intent.putExtra("Time", location.getTime()); sendBroadcast(intent); } @Override public void onProviderDisabled(String provider) { // TODO Auto-generated method stub } @Override public void onProviderEnabled(String provider) { // TODO Auto-generated method stub } @Override public void onStatusChanged(String provider, int status, Bundle extras) { // TODO Auto-generated method stub } } }
不要忘記 AndroidManifest.xml 中處理權限及Service:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="tw.brad.android.test.ServiceTest" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".ServiceTest" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="MyService"></service> </application> <uses-sdk android:minSdkVersion="7" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission> </manifest>
沒有留言:
張貼留言