編輯:初級開發
---------首屆Google暑期大學生博客分享大賽——2010 Andriod篇
接觸android也有半年了,小作品也發布了幾個,但是其中都沒有用到ServcIE,在這一點覺得自己還是有所不足的。目前正在做的這個應用要使用到Service,所以就當是補補課了。
應用的目標很簡單,用戶設定一個時間,到時後停止音樂的播放。所以我們需要使用Service來保持在Activity結束後繼續維持計時。當用戶設定某一時間後啟動一個Service,之後所有操作由Service驅動,Activity界面就可以關閉了,在Service中我們要使用 AlarmService來實現計時,當時間到時AlarmManager會發送一個廣播,你需要一個BroadcastReceiver來處理這個廣播完成時間到時時要完成的操作。
如果說正在看這篇文章的你還不知道什麼是Service或BroadcastReceiver的話,您需要自己另找資料學習一下了,我只能簡單說 Service是一個後台的應用程序,它沒有顯示的界面所以也就不能與用戶交互,但是它還是能夠通信的。Service有兩種啟動的方式一個使用 Context.startService()啟動,另一個則是使用Context.bindService()來啟動,兩者存在這區別。而 BroadCastReceiver就是一個收音機,這個BroadCastReceiver會響應一個有特定標識的消息。我也只能簡單的說這一點,更多的內容你可以自己在Google上搜索一些關於Service和BroadcastReceiver的資料吧。
首先是要做的是一個Service,你需要繼承Service類並實現它的onCreate(),onStart(),onDestroy(),onBind()方法,其中onBind()方法是必須實現的。
實例代碼如下
package com.shinestudio.sleepMusic.service;
import Java.util.Calendar;
//......
import com.shinestudio.sleepMusic.AlarmReceiver;
import com.shinestudio.sleepMusic.StartActivity;
public class SleepMusicService extends Service {
private static String TAG = "sleepMusicService";
private static SleepMusicService sms = null;
private static int NOTIFICATION_ID = 0x1209;
private String settingTime;
public static Service getService() {
return sms;
}
/*
這裡有個小方法有必要說一下,在Service或Activity中我們可以寫一個靜態的方法來保留自己的實體。這樣在其他的地方就可以獲取到了。
private static SleepMusicService sms = null; 用來存儲自己的實體
在onCreate()中 使用sms = this;來存儲實體
編寫一個靜態的getService()來返回實體就行了。
*/
@Override
public void onCreate() {
super.onCreate();
sms = this;
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.d(TAG, "Service onStart");
//獲取AlarmManager
AlarmManager am = (AlarmManager) getSystemService(Service.ALARM_SERVICE);
//獲取當前的時間
Calendar c = Calendar.getInstance();
c.setTimeInMillis(System.currentTimeMillis());
// 只對秒 做修改
// c.set(Calendar.HOUR_OF_DAY, hourOfDay);
// c.set(Calendar.MINUTE, c.get(Calendar.MINUTE));
c.set(Calendar.SECOND, c.get(Calendar.SECOND) + 5); //定時5秒
//c.set(Calendar.MILLISECOND, 0);
//設置消息的響應
Intent ii = new Intent(this, AlarmReceiver.class);
PendingIntent pii = PendingIntent.getBroadcast(this, 0, ii, 0);
am.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pii);
//使用Toast提示用戶
Toast.makeText(this, "AlarmSet Finish", Toast.LENGTH_SHORT).show();
}
@Override
public void onDestroy() {
AlarmManager am = (AlarmManager) getSystemService(Service.ALARM_SERVICE);
Intent i = new Intent(this, StartActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0);
am.cancel(pi);
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
完成了Service,之後就是寫一個Activity來啟動這個Service,其中為了保證在應用退出後ServcIE繼續運行,所以要使用startService()來啟動Service。一般關於Service的資料上都是有的。
package com.shinestudio.sleepMusic;
import Java.util.Iterator;
import Java.util.List;
//......
import com.shinestudio.sleepMusic.service.ISleepMusicService;
import com.shinestudio.sleepMusic.service.SleepMusicService;
import com.shinestudio.sleepMusic.unit.TimerPickerUIStruct;
public class StartActivity extends Activity {
private static String TAG = "sleepMusic - StartActivity";
private ListVIEw timerlist;
private TimerPicker timerPicker;
private TimerPickerUIStruct tpui;
private Button startButton;
private Button cancelButton;
private Button restartButton;
//當點擊開始按鈕
private OnClickListener startButtonClickListener = new OnClickListener() {
@Override
public void onClick(VIEw v) {
Intent isleepMusicService = new Intent(StartActivity.this,
SleepMusicService.class);
/*
在Service啟動之前可以使用Intent來傳遞參數給Service ,方法如下
目前的代碼只是演示,與功能無關
*/
Bundle setting = new Bundle();
setting.putString(“TIME_SETTING”, "5s");
// 在Service中使用“TIME_SETTING”這個標簽就可以從Intent取出5s 這個字符串了
isleepMusicService.putExtras(setting);
startService(isleepMusicService);
}
};
//點擊取消按鈕
private OnClickListener cancelButtonClickListener = new OnClickListener() {
@Override
public void onClick(VIEw v) {
Intent sleepMusicService = new Intent(StartActivity.this,
SleepMusicService.class);
//停止服務
stopService(sleepMusicService);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentVIEw(R.layout.main);
// ...... 代碼省略
// 獲取Layout中的按鈕
startButton = (Button) findVIEwById(R.id.b_start);
cancelButton = (Button) findVIEwById(R.id.b_cancel);
startButton.setOnClickListener(startButtonClickListener);
cancelButton.setOnClickListener(cancelButtonClickListener);
restartButton = (Button) findVIEwById(R.id.b_restart);
restartButton.setOnClickListener(restartButtonClickListener);
}
}
完成了這個Activity之後,就容易的多了,剩下的就是BroadcastReceiver了,新建一個類繼承BroadcastReceiver
並且實現onReceive()方法
package com.shinestudio.sleepMusic;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "時間到", Toast.LENGTH_SHORT).show();
}
}
當Service中的AlarmManager完成計時後將廣播消息給AlarmReceiver,這樣就會顯示Toast給用戶了。
在androidManifest.XML中添加activity、service、和receiver的設置
package="com.shinestudio.sleepMusic" android:versionCode="1"
android:versionName="1.0">
android:theme="@android:style/Theme.Black.NoTitleBar">
附加提供的一點點代碼片
打開HTC HERO 自帶的HTC Music Player
public void openMusicPlayer(){
Open Music Player
Intent musicPlayer = new Intent();
musicPlayer.setAction(Intent.ACTION_MAIN);
musicPlayer.setPackage("com.htc.music");
StartActivity.this.startActivity(musicPlayer);
}
//獲得所有運行的service
public static String getRunningServicesInfo(Context context) {
StringBuffer serviceInfo = new StringBuffer();
final ActivityManager activityManager = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
List services = activityManager.getRunningServices(100);
Iterator l = services.iterator();
while (l.hasNext()) {
RunningServiceInfo si = (RunningServiceInfo) l.next();
serviceInfo.append("pid: ").append(si.pid);
serviceInfo.append(" process: ").append(si.process);
serviceInfo.append(" service: ").append(si.service);
serviceInfo.append(" crashCount: ").append(si.crashCount);
serviceInfo.append(" clientCount: ").append(si.clIEntCount);
serviceInfo.append(" ");
}
return serviceInfo.toString();
}
在看完這堆代碼之後,請您看看這個,這些是android所提供給用戶的的一下系統的Service
像NotificationManager Vebrator AlarmManager 都是比較常用的。
WINDOW_SERVICE WindowManager 管理打開的窗口程序
LAYOUT_INFLATER_SERVICE LayoutInflater 取得XML裡定義的vIEw
ACTIVITY_SERVICE ActivityManager 管理應用程序的系統狀態
POWER_SERVICE PowerManger 電源的服務
ALARM_SERVICE AlarmManager 鬧鐘的服務
NOTIFICATION_SERVICE NotificationManager 狀態欄的服務
KEYGUARD_SERVICE KeyguardManager 鍵盤鎖的服務
LOCATION_SERVICE LocationManager 位置的服務,如GPS
SEARCH_SERVICE SearchManager 搜索的服務
VEBRATOR_SERVICE Vebrator 手機震動的服務
CONNECTIVITY_SERVICE Connectivity 網絡連接的服務
WIFI_SERVICE WifiManager Wi-Fi服務
TELEPHONY_SERVICE TeleponyManager 電話服務
三、範例程式:Activity與Service間之溝通先執行ac01:這個ac01立即啟動myService,定時連續傳來數字,如下:數字連續增加下去。其程式碼為:/*
以Windows平台的SDK為例,這裡Android開發網的模擬器配置路徑為 C:\Users\Administrator\.android\avd\2.3.3.avd
android SDK提供了一個強大的類Drawable,Drawable這個抽象類到底代表了什麼,如何使用?Drawable是個很抽象的概念,通過簡單的例子程序來學習
最近幾天由於項目的需要研究了一下listVIEw的滑動數據動態的更新顯示,其中需要在數據加載過程有圓形進度條的顯示,遇到的問題是進度條的顏色設置,在網上查了一些資料結合