2013年10月21日

Android─Service啟動方式

當我們在使用Smartphone時,所看到的畫面都是在前端執行的程式,但還是有許多工作需要在背景執行,例如:撥放mp4下載檔案
這種需要在背景執行的功能,Android提供了一種方法─Service
讓開發者可以在Service撰寫要提供使用者在背景執行的功能。

要創立一個Service首先我們現在Manifest宣告
test_service為一個Service
程式碼如下
<service android:name=".test_service"/>

呼叫Service有兩種方式

1.Activiy透過startService去執行Service,我們將所需要在Service執行的功能寫在Service的onStartCommand裡 

2.Activity透過bindService來執行Service,我們需要在Service內加入ibinder物件,如此Activity則可透過ibinder物件使用Service裡public的method

下面的範例,我們將丟一個正整數,透過Service去幫我們做加總的動作

1.使用startService

Activity程式碼
Intent intent = new Intent(this, test_service.class);
intent.putExtra("number",10);
startService(intent);

Service程式碼
public class Uninstall_Service extends Service {
  private int getnum,total=0;
  @Override
  public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);
    Log.i("service", "enter the service");
    getnum=intent.getExtras().getInt("number");  
      for(int a=1; a<=getnum; a++)
      {
        total=total+a;    
      } 
    Log.i("service","the answer is" +total);  
  }
}

Service會在onStart裡面去做整數加總的動作

2. bind service的使用方式
小弟才疏學淺,怕解說的不詳細
此連結有對bind service使用有詳細的解說,大家可以參考


最後來簡述一下Service destory的狀況
1.使用startService,activity與service是處在獨立的狀態,所以當activity destory,service並不會跟著destory,還是會持續在背景執行;直到service自己停止,或者可由任一個activity使用stopService()。

2. 使用bind service,service與activity的ibind object是有關連的,所以當activity destory時,service也會跟著destory。 另外有一點需要注意的是,當activity進入pause 或 stop,要先unbind service,當resume時,再重新bind service。

參考連結1
參考連結2
參考連結3
參考連結4



2013年10月15日

Android─指定apk安裝位置

在Android 2.2以上的版本,支援apk可以搬移到外部的儲存空間,
例如手機儲存空間或者SD card。
Programmer也可以在撰寫app時,指定apk安裝在內部或者外部的儲存空間。 

我們只需要在manifest 加入 android:installLocation 
此宣告有三個選項

  • internalOnly:指定apk安裝在內部儲存空間
  • auto:根據系統預設值決定安裝的位置
  • preferExternal:指定apk安裝在外部的儲存空間
如果想知道系統的預設值,可以去android 的framework底下的DefaultContainerService.java
 trace source code

在android官方的文件有寫到
如果app裡面包含了以下的項目,apk是需要放在internal storage,否則無法正常運行
  • Services
  • Alarm Services
  • Input Method Engines
  • Live Wallpapers
  • Account Managers
  • Sync Adapters
  • Device Administrators
  • Broadcast Receivers listening for "boot completed"
如果想要知道更詳細的資訊,請參考下面網頁

2013年10月1日

Android ─ Service建立Dialog對話框

根據Android的文件,Service本身並沒有介面,假如我們在Service上有需要使用到對話框。
若我們使用在Activity建立對話框的方式套用在Service裡,則會產生錯誤。

會產生錯誤的原因是,在Android系統規定,正在運作的Activity UI只能被該Activity的主thread做更改。
當Service企圖更改正在執行的Activity的UI,則會導致錯誤產生。

上網搜尋找到的解決方法:將Service所顯示的對話框設定為系統的提示框。

首先必須在Manifest增加權限



程式碼如下:
public void showDialog(int title,String message){
    Log.i("service","show dialog function");
    TextView errmsg = (TextView) layout.findViewById(R.id.errmsg);
    Log.i("service", "dialog error msg:"+message);  
    errmsg.setText(Html.fromHtml(message));
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(title);
    builder.setMessage(message); 
    builder.setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            dialog.dismiss();
        }
    });
    AlertDialog alert = builder.create();
    alert.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);//設定提示框為系統提示框
    alert.show();
}

參考網址