2012年4月8日 星期日

[Android] 使用 custom action strings 判斷簡訊發送狀態 Use SmsManager, PendingIntent





BroadcastReceiver的使用有兩種方法 , 之前文章所使用的技巧是動態的註冊和註銷 : [TQC+ Android] 3-7 判斷髮送簡訊狀態 Use registerReceiver, SmsManager, PendingIntent , 而這篇要使用的是在 AndroidManifest.xml 中靜態註冊 , 並在<intent-filter> tag 宣告使用我們自訂的action strings , 以下是程式碼。


package COM.TQC.GDD03;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class GDD03 extends Activity
{
  private Button mButton1;
  private EditText mEditText1, mEditText2;
  
  PendingIntent sentIntent;
  SmsManager smsManager;  
    
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    
    /* Phone No. */
    mEditText1 = (EditText) findViewById(R.id.myEditText1);
    
    /* SMS BODY */
    mEditText2 = (EditText) findViewById(R.id.myEditText2);
    mButton1 = (Button) findViewById(R.id.myButton1);
    
    mEditText1.setText("5556");
    mEditText2.setText("DAVID_SEND");
    
    smsManager = SmsManager.getDefault();
    //SmsManager 類別可以協助我們送出簡訊 , 我們可以透過 這個static method getDefault()來取得 SmsManager預設的instance
    
    Intent smsIntent = new Intent("COM.TQC.GDD03.Send_Message");
 //替這個Intent 設定我們自訂的action : COM.TQC.GDD03.Send_Message
    //通常在action前我們會附加上 application package name
    
    smsIntent.putExtra("Data", "Hello!");
    //順便附加個字串
    
 sentIntent = PendingIntent.getBroadcast(GDD03.this, 0, smsIntent, PendingIntent.FLAG_CANCEL_CURRENT);
 //public static PendingIntent getBroadcast (Context context, int requestCode, Intent intent, int flags)
 //使用這個static method 我們會接收到一個具有像Context.sendBroadcast()行為的PendingIntent instance.
 //我們使用 FLAG_CANCEL_CURRENT , 用意是在產生一個新的 PendingIntent之前 , 會把舊的先cancel掉
 
    
    mButton1.setOnClickListener(new Button.OnClickListener()
    {
      @Override
      public void onClick(View v)
      {
        // TODO Auto-generated method stub
     smsManager.sendTextMessage(mEditText1.getText().toString(), null, mEditText2.getText().toString(), sentIntent, null);
     //送出簡訊 , 並附加一個 PendingIntent sentIntent , 用意是等它回報傳送結果(result code)
     //並且可以從sentIntent中取得相關資訊 , 例如一些額外的錯誤提示 , 或是我們預先加入的資訊如之前的"Data" 
      
      }
    });
  } 
  
  public static class mServiceReceiver extends BroadcastReceiver
  {
   @Override
      public void onReceive(Context context, Intent intent)
      {
        // TODO Auto-generated method stub
       
       Log.d("Test","Data:"+intent.getStringExtra("Data"));
       //顯示之前擺入sentIntent的附加資訊
       
       if(intent.getAction().equals("COM.TQC.GDD03.Send_Message"))
       { 
        switch(getResultCode()) //取得回傳的result code
        {
         case Activity.RESULT_OK:       
         Toast.makeText(context, "SMS sent", Toast.LENGTH_LONG).show();
         break;
        
         case SmsManager.RESULT_ERROR_RADIO_OFF:
         Toast.makeText(context, "RADIO OFF", Toast.LENGTH_LONG).show();
            break;
         
         case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
         //如果是這個"一般錯誤"的case , 那麼 sentIntent 也許會附帶一組 "errorCode" 來記錄錯誤資訊
         break;
         
         case SmsManager.RESULT_ERROR_NULL_PDU:
            //Failed because no pdu provided 
            break;
            
         case SmsManager.RESULT_ERROR_NO_SERVICE:
            //Failed because service is currently unavailable
            break;
        
         default:       
         Toast.makeText(context, "NO SERVICE", Toast.LENGTH_LONG).show();
            break;
        }      
       }
      }
  }
}


程式的處理流程在註解中已經有提到了 , 不清楚的可以搭配之前的文章。

我們將 custom BroadcastReceiver 定義為 public static 一個內部靜態類別 , 又或者可以另外 custom BroadcastReceiver 單獨分開擺在另一個 Java 檔中 , 以上兩個不同的方式在AndroidManifest.xml 中也搭配不一樣的宣告內容。

    
        
            
                
                
            
        
        
            
                
            
               
    
    

 
注意 <receiver android:name="GDD03$mServiceReceiver"> , 因為我們將 mServiceReceiver 定義為內部靜態類別 , 而  GDD03$mServiceReceiver  是一個標準的方法 , 可以協助我們取用內部類別。


沒有留言:

張貼留言

Google Analytics