SMS Messaging in Android(1)

SMS Messaging in Android(1)

 

转自:http://jakielong.javaeye.com/blog/732328

 

可以安全的说,在过去的近 20 年里卖的每一款移动电话都拥有 SMS 消息功能。事实上, SMS 消息是移动手机中一个杀手级的应用程序,它为移动运营商创造了稳定的收入源。理解如何在你的应用程序中使用 SMS 消息能帮助你产生灵感来创建下一个杀手级程序。

 

在这篇文章里,我将一览如何在你的 Android 应用程序中发送和接收 SMS 消息。对 Android 开发者来说,有个好消息是你不需要一款真实的设备来测试 SMS 消息——免费的 Android 模拟器提供这一功能。

 

发送SMS消息

 

开始,先启动 Eclipse 并创建一个新的 Android 工程。命名工程如图 1 所示。

1 使用 Eclipse 创建一个新的 Android 工程

Android 使用一种基于权限的策略,应用程序所需的所有权限需要在 AndroidManifest.xml 文件中指定。通过这样做,当应用程序安装后,用户就能清楚地知晓应用程序需要哪些特定的访问权限。举个例子,发送 SMS 消息会引起用户的额外费用,在 AndroidManifest.xml 文件中指明 SMS 权限能让用户决定应用程序是否安装。

 

AndroidManifest.xml 文件中,添加两个权限—— SEND_SMS RECEIVE_SMS

 

<?xml version = "1.0" encoding = "utf-8" ?>
<manifest xmlns:android = "http://schemas.android.com/apk/res/android"
     
package = "net.learn2develop.SMSMessaging"
     
android:versionCode = "1"
     
android:versionName = "1.0.0" >
    <application android:icon = "@drawable/icon" android:label = "@string/app_name" >
        <activity android:name = ".SMS"
                 
android:label = "@string/app_name" >
            <intent-filter>
                <action android:name = "android.intent.action.MAIN" />
                <category android:name = "android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name = "android.permission.SEND_SMS" >
    </uses-permission>
    <uses-permission android:name = "android.permission.RECEIVE_SMS" >
    </uses-permission>
</manifest>

 

res/layout 文件夹下的 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"
   
>
    <TextView  
       
android:layout_width = "fill_parent"
       
android:layout_height = "wrap_content"
       
android:text = "Enter the phone number of recipient"
       
/>     
    <EditText
       
android:id = "@+id/txtPhoneNo"  
       
android:layout_width = "fill_parent"
       
android:layout_height = "wrap_content"        
       
/>
    <TextView  
       
android:layout_width = "fill_parent"
       
android:layout_height = "wrap_content"         
       
android:text = "Message"
       
/>     
    <EditText
       
android:id = "@+id/txtMessage"  
       
android:layout_width = "fill_parent"
       
android:layout_height = "150px"
       
android:gravity = "top"         
       
/>          
    <Button
       
android:id = "@+id/btnSendSMS"  
       
android:layout_width = "fill_parent"
       
android:layout_height = "wrap_content"
       
android:text = "Send SMS"
       
/>    
</LinearLayout>

 

上面的代码创建的 UI 如图 2 所示。

 

2 创建发送 SMS 消息的 UI

接下来,在 SMS Activity 中,我们连接 Button View ,这样当用户点击它时,我们可以检查接收者的电话号码和输入的消息,然后使用 sendSMS 函数来发送消息。

 

package net.learn2develop .SMSMessaging ;
 
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.gsm.SmsManager;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
 
public class SMS extends Activity
{
    Button btnSendSMS;
    EditText txtPhoneNo ;
    EditText txtMessage ;
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate( Bundle savedInstanceState)
    {
        super .onCreate ( savedInstanceState);
        setContentView ( R.layout .main );        
 
        btnSendSMS = ( Button ) findViewById( R.id .btnSendSMS );
        txtPhoneNo = ( EditText) findViewById( R.id .txtPhoneNo );
        txtMessage = ( EditText) findViewById( R.id .txtMessage );
 
        btnSendSMS. setOnClickListener ( new View .OnClickListener ()
        {
            public void onClick( View v)
            {                
                String phoneNo = txtPhoneNo.getText () .toString ();
                String message = txtMessage.getText () .toString ();                 
                if ( phoneNo.length ()> 0 && message.length ()> 0 )                
                    sendSMS ( phoneNo, message);                
                else
                    Toast. makeText ( getBaseContext() ,
                        "Please enter both phone number and message." ,
                        Toast. LENGTH_SHORT ) .show ();
            }
        });        
    }    
}

 

sendSMS 函数定义如下:

 

public class SMS extends Activity
{
    //...
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate( Bundle savedInstanceState)
    {
        //...
    }
 
    //---sends an SMS message to another device---
    private void sendSMS( String phoneNumber, String message)
    {        
        PendingIntent pi = PendingIntent. getActivity ( this , 0 ,
            new Intent( this , SMS.class ) , 0 );                
        SmsManager sms = SmsManager. getDefault ();
        sms. sendTextMessage ( phoneNumber, null , message, pi, null );        
    }    
}

 

为了发送一个 SMS 消息,你需要使用 SmsManager 类。不同于其它的类,你不需要直接实例化这个类;取而代之的是调用 getDefault() 静态方法来获取一个 SmsManager 对象。sendTextMessage () 方法发送 SMS 消息和一个 PendingIntent PendingIntent 对象用于在以后的时间识别触发的目标。例如,发送消息后,你可以使用 PendingIntent 对象来显示其它的 Activity 。在这里, PendingIntent 对象( pi )简单指向相同的 Activity SMS.java ),所以,当 SMS 发送后,什么事情也不会发生。

 

如果你需要监视 SMS 消息的发送过程状况,你可以使用两个 PendingIntent 对象以及两个 BroadcastReceiver 对象,像这样:

 

    //---sends an SMS message to another device---
    private void sendSMS( String phoneNumber, String message)
    {        
        String SENT = "SMS_SENT" ;
        String DELIVERED = "SMS_DELIVERED" ;
 
        PendingIntent sentPI = PendingIntent. getBroadcast ( this , 0 ,
            new Intent( SENT) , 0 );
 
        PendingIntent deliveredPI = PendingIntent. getBroadcast ( this , 0 ,
            new Intent( DELIVERED) , 0 );
 
        //---when the SMS has been sent---
        registerReceiver ( new BroadcastReceiver(){
            @Override
            public void onReceive( Context arg0, Intent arg1) {
                switch ( getResultCode())
                {
                    case Activity.RESULT_OK :
                        Toast. makeText ( getBaseContext() , "SMS sent" ,
                                Toast. LENGTH_SHORT ) .show ();
                        break ;
                    case SmsManager.RESULT_ERROR_GENERIC_FAILURE :
                        Toast. makeText ( getBaseContext() , "Generic failure" ,
                                Toast. LENGTH_SHORT ) .show ();
                        break ;
                    case SmsManager.RESULT_ERROR_NO_SERVICE :
                        Toast. makeText ( getBaseContext() , "No service" ,
                                Toast. LENGTH_SHORT ) .show ();
                        break ;
                    case SmsManager.RESULT_ERROR_NULL_PDU :
                        Toast. makeText ( getBaseContext() , "Null PDU" ,
                                Toast. LENGTH_SHORT ) .show ();
                        break ;
                    case SmsManager.RESULT_ERROR_RADIO_OFF :
                        Toast. makeText ( getBaseContext() , "Radio off" ,
                                Toast. LENGTH_SHORT ) .show ();
                        break ;
                }
            }
        } , new IntentFilter( SENT));
 
        //---when the SMS has been delivered---
        registerReceiver ( new BroadcastReceiver(){
            @Override
            public void onReceive( Context arg0, Intent arg1) {
                switch ( getResultCode())
                {
                    case Activity.RESULT_OK :
                        Toast. makeText ( getBaseContext() , "SMS delivered" ,
                                Toast. LENGTH_SHORT ) .show ();
                        break ;
                    case Activity.RESULT_CANCELED :
                        Toast. makeText ( getBaseContext() , "SMS not delivered" ,
                                Toast. LENGTH_SHORT ) .show ();
                        break ;                        
                }
            }
        } , new IntentFilter( DELIVERED));        
 
        SmsManager sms = SmsManager. getDefault ();
        sms. sendTextMessage ( phoneNumber, null , message, sentPI, deliveredPI);        
    }

 

上面的代码使用一个 PendingIntent 对象( sendPI )来监视发送过程。当 SMS 消息发送后,第一个 BroadcastReceiver onReceive 事件会触发。在这里你可以检查发送过程的状态。第二个 PendingIntent 对象( deliveredPI )监视传送过程。当 SMS 消息成功送达时会触发第二个 BroadcastReceiver onReceive 事件。

 

现在,你可以按下 F11 来测试应用程序了。为了从一个模拟器实例发送 SMS 消息到另一个实例,进入 SDK Tools 文件夹并运行 Emulator.exe 来简单启动另一个 Android 模拟器实例。

3 发送 SMS 消息

3 演示了如何从一个模拟器发送 SMS 消息到另一个模拟器;使用目标模拟器的端口号(显示在窗口的左上角)作为它的电话号码。当 SMS 发送成功时,它会显示一个“ SMS sent ”消息。当它成功送达时,它会显示一个“ SMS delivered ”消息。注意,使用模拟器进行测试时,当 SMS 成功送达时,“ SMS delivered ”消息不会显示;它仅在真机上工作。

 

4 显示了接收模拟器中 SMS 消息接收后的样子。消息一开始显示在通知条上(屏幕的上方)。往下拖拽通知条,显示出接收到的消息。查看完整的消息,点击那个消息。

4 Android 模拟器接收 SMS 消息

如果你不想触及发送 SMS 消息的所有麻烦,你可以使用一个 Intent 对象来帮助你发送 SMS 消息。下面的代码就演示了如何引发内建的 SMS 程序来帮助你发送 SMS 消息:

 

        Intent sendIntent = new Intent( Intent.ACTION_VIEW );
        sendIntent.putExtra ( "sms_body" , "Content of the SMS goes here..." );
        sendIntent.setType ( "vnd.android-dir/mms-sms" );
        startActivity( sendIntent);

 

5 显示了内建的 SMS 应用程序发送 SMS 消息。

5 引发内建的 SMS 程序

接收SMS消息

 

除了可以程序化的发送 SMS 消息,你还可以使用一个 BroadcastReceiver 对象来拦截新的 SMS 消息。

 

想看如何在 Android 应用程序中接收 SMS 消息的话,可以在 AndroidManifest.xml 文件中添加 <receiver> 元素,这样,新来的 SMS 消息就能被 SmsReceiver 类拦截:

 

<?xml version = "1.0" encoding = "utf-8" ?>
<manifest xmlns:android = "http://schemas.android.com/apk/res/android"
     
package = "net.learn2develop.SMSMessaging"
     
android:versionCode = "1"
     
android:versionName = "1.0.0" >
    <application android:icon = "@drawable/icon" android:label = "@string/app_name" >
        <activity android:name = ".SMS"
                 
android:label = "@string/app_name" >
            <intent-filter>
                <action android:name = "android.intent.action.MAIN" />
                <category android:name = "android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>        
 
        <receiver android:name = ".SmsReceiver" >
            <intent-filter>
                <action android:name =
                   
"android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>
 
    </application>
    <uses-permission android:name = "android.permission.SEND_SMS" >
    </uses-permission>
    <uses-permission android:name = "android.permission.RECEIVE_SMS" >
    </uses-permission>
</manifest>

 

添加一个新的类文件并命名为 SmsReceiver.java (如图 6 )。

6 添加 SmsReceiver.java 文件到工程中

SmsReceiver 类中,扩展 BroadcastReceiver 类,并重写 onReceive 方法:

 

package net.learn2develop .SMSMessaging ;
 
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
 
public class SmsReceiver extends BroadcastReceiver
{
        @Override
         public void onReceive( Context context, Intent intent)
       {         
         }
}

 

SMS 消息接收后, onReceive() 方法会触发。 SMS 消息附着在 Intent 对象上( onReceive 方法的第二个参数, intent )的 Bundle 对象里。消息以 PDU 格式储存在一个对象数组里。要提取每个消息,可以使用 SmsMessage 类的 createFromPdu ()静态方法。然后,使用 Toast 类显示 SMS 消息:

 

package net.learn2develop .SMSMessaging ;
 
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.gsm.SmsMessage;
import android.widget.Toast;
 
public class SmsReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive( Context context, Intent intent)
    {
        //---get the SMS message passed in---
        Bundle bundle = intent. getExtras ();        
        SmsMessage [] msgs = null ;
        String str = "" ;            
        if ( bundle ! = null )
        {
            //---retrieve the SMS message received---
            Object [] pdus = ( Object []) bundle.get ( "pdus" );
            msgs = new SmsMessage[ pdus.length ];            
            for ( int i=0 ; i< msgs.length ; i++){
                msgs [ i] = SmsMessage.createFromPdu (( byte []) pdus[ i]);                
                str += "SMS from " + msgs [ i] .getOriginatingAddress ();                     
                str += " :" ;
                str += msgs [ i] .getMessageBody () .toString ();
                str += " /n " ;        
            }
            //---display the new SMS message---
            Toast. makeText ( context, str, Toast.LENGTH_SHORT ) .show ();
        }                         
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值