Android开发手记(15) 拨打电话和收发短信

1、Intent简介

  Android组价之间的通信,由Intent来协助完成。Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。

  Intent可以启动一个Activity,也可以启动一个Service,还可以发起一个广播Broadcasts。分别通过startActivity();startService();startBroadcasts();来执行操作。

  在使用Android的电话功能的时候,我们需要调用Intent的相关功能来实现拨打电话和收发短信。

2、URI

  URI是统一资源标识符(Uniform Resource Identifier)的缩写。是一个用于标识某一互联网资源名称的字符串。 该种标识允许用户对任何(包括本地和互联网)的资源通过特定的协议进行交互操作。URI由包括确定语法和相关协议的方案所定义。在Android中URI的意义非常重大,他是所有资源的标示符(ID),通过URI可找到一个对应的具体实体,如文件(file),数据库的表项(content)等,可以说贯穿整个Framework。 
  URI一般的格式为:[scheme:]schemeSpecificPart[#fragment]  ([...]表示可选) 

3、拨打电话

  直接拨打电话需要添加android.permission.CALL_PHONE权限,在AndroidManifest.xml中添加如下代码:

<uses-permission android:name="android.permission.CALL_PHONE"/>

  完整代码为:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3     package="com.example.doodle.button" >
 4 
 5     <application
 6         android:allowBackup="true"
 7         android:icon="@mipmap/ic_launcher"
 8         android:label="@string/app_name"
 9         android:theme="@style/AppTheme" >
10         <activity
11             android:name=".MainActivity"
12             android:label="@string/app_name" >
13             <intent-filter>
14                 <action android:name="android.intent.action.MAIN" />
15 
16                 <category android:name="android.intent.category.LAUNCHER" />
17             </intent-filter>
18         </activity>
19     </application>
20 
21     <uses-permission android:name="android.permission.CALL_PHONE"/>
22 
23 </manifest>
AndroidManifest.xml

  然后,我们实例化一个Uri,其内容为要拨打电话的命令。电话号码通过TextView获得。然后我们实例化一个Intent,设置Intent的行为为“直接拨打电话”,Intent的数据为“拨打XXX电话命令”。

1      Uri uri = Uri.parse("tel:" + tvPhone.getText());
2      Intent intent = new Intent();
3      intent.setAction(Intent.ACTION_CALL);
4      intent.setData(uri);    

  然后为拨打电话按钮添加此单击事件即可

 1        btnDriect.setOnClickListener(new View.OnClickListener() {
 2             @Override
 3             public void onClick(View view) {
 4                 Uri uri = Uri.parse("tel:" + tvPhone.getText());
 5                 Intent intent = new Intent();
 6                 intent.setAction(Intent.ACTION_CALL);
 7                 intent.setData(uri);
 8                 startActivity(intent);
 9             }
10         });

  同理,我们可以通过Intent来启动系统自带的拨号器。启动系统自带的拨号器是不需要android.permission.CALL_PHONE权限的。

1         btnSystem.setOnClickListener(new View.OnClickListener() {
2             @Override
3             public void onClick(View view) {
4                 Uri uri = Uri.parse("tel:" + tvPhone.getText());
5                 Intent intent = new Intent(Intent.ACTION_DIAL, uri);
6                 startActivity(intent);
7             }
8         });

 

4、发送短信

  同拨打电话一样,发送短信同样需要相应的权限。

<uses-permission android:name="android.permission.SEND_SMS"/>

  不同的是,我们在发送短信的时候是通过SmsManager来完成发送的。首先我们要实例化一个SmsManager。通过SmsManager.sendTextMessage()方法可以进行短信发送。其原型为:

1 sendTextMessage(String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent);
2 // destAddress 发送短信的地址(也就是号码)
3 // scAddress 短信服务中心,如果为null,就是用当前默认的短信服务中心
4 // text 短信内容
5 // sentIntent 如果不为null,当短信发送成功或者失败时,这个PendingIntent会被广播出去成功的结果代码是Activity.RESULT_OK
6 // deliveryIntent  如果不为null,当这个短信发送到接收者那里,这个PendtingIntent会被广播,状态报告生成的pdu(指对等层次之间传递的数据单位)会拓展到数据("pdu")

  这里我们需要实例化一个PendingIntent来协助SMSManger的工作。

SmsManager smsManager = SmsManager.getDefault();
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, new Intent(), 0);
smsManager.sendTextMessage(strAddr, null, strCont, pendingIntent, null);
 1        btnSend.setOnClickListener(new View.OnClickListener() {
 2             @Override
 3             public void onClick(View view) {
 4                 String strAddr = etPhone.getText().toString();
 5                 String strCont = etContent.getText().toString();
 6 
 7                 if (strAddr.equals("")) {
 8                     Toast.makeText(MainActivity.this, "收件人不能为空", Toast.LENGTH_SHORT).show();
 9                 }
10                 if (strCont.equals("")) {
11                     Toast.makeText(MainActivity.this, "短信内容不能为空", Toast.LENGTH_SHORT).show();
12                 }
13 
14                 SmsManager smsManager = SmsManager.getDefault();
15                 PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, new Intent(), 0);
16                 smsManager.sendTextMessage(strAddr, null, strCont, pendingIntent, null);
17                 Toast.makeText(MainActivity.this, "短信发送成功",Toast.LENGTH_LONG).show();
18             }
19         });    

  完整代码为:

 1 import android.app.PendingIntent;
 2 import android.content.Intent;
 3 import android.support.v7.app.AppCompatActivity;
 4 import android.os.Bundle;
 5 import android.telephony.SmsManager;
 6 import android.view.View;
 7 import android.widget.Button;
 8 import android.widget.EditText;
 9 import android.widget.Toast;
10 
11 public class MainActivity extends AppCompatActivity {
12 
13     private EditText etPhone;
14     private EditText etContent;
15     private Button btnSend;
16 
17     @Override
18     protected void onCreate(Bundle savedInstanceState) {
19         super.onCreate(savedInstanceState);
20         setContentView(R.layout.activity_main);
21 
22         etPhone = (EditText) findViewById(R.id.etPhone);
23         etContent = (EditText) findViewById(R.id.etContent);
24         btnSend = (Button) findViewById(R.id.btnSend);
25 
26         btnSend.setOnClickListener(new View.OnClickListener() {
27             @Override
28             public void onClick(View view) {
29                 String strAddr = etPhone.getText().toString();
30                 String strCont = etContent.getText().toString();
31 
32                 if (strAddr.equals("")) {
33                     Toast.makeText(MainActivity.this, "收件人不能为空", Toast.LENGTH_SHORT).show();
34                 }
35                 if (strCont.equals("")) {
36                     Toast.makeText(MainActivity.this, "短信内容不能为空", Toast.LENGTH_SHORT).show();
37                 }
38 
39                 SmsManager smsManager = SmsManager.getDefault();
40                 PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, new Intent(), 0);
41                 smsManager.sendTextMessage(strAddr, null, strCont, pendingIntent, null);
42                 Toast.makeText(MainActivity.this, "短信发送成功",Toast.LENGTH_LONG).show();
43             }
44         });
45     }
46 }
MainActivity.java

5、接收短信

  同拨打电话一样,发送短信同样需要相应的权限。接收短信需要

<uses-permission android:name="android.permission.RECEIVE_SMS"/>

  接收短信的原理是,首先新建一个BroadcastReceiver来监听短信信息,然后根据监听到的广播信息中的短信进行捕捉,然后呈现出来。

  首先,新建一个Receiver类,然后重载其onReceive方法。

 1 public class Receiver extends BroadcastReceiver {
 2 
 3     @Override
 4     public void onReceive(Context context, Intent intent) {
 5         if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
 6 
 7          
 8         }
 9     }
10 }

  然后,我们新建一个Budle来接收信息,我们知道,短信信息的关键字为"pdus",所以通过一个Object[]来接收此信息,然后再将其转化为SmsMessage即可。

  由于接收到的短信由于长度原因,可能被分割成若干条信息,所以,我们通过一个for循环来处理此短信。

 1        if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
 2             StringBuilder str = new StringBuilder();
 3             Bundle bundle = intent.getExtras();
 4             if (bundle != null) {
 5                 Object[] pdus = (Object[]) bundle.get("pdus");
 6                 SmsMessage[] msg = new SmsMessage[pdus.length];
 7                 for (int i = 0; i < pdus.length; i++) {
 8                     msg[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
 9                 }
10                 for (SmsMessage m : msg) {
11                     str.append("发件人:");
12                     str.append(m.getDisplayOriginatingAddress());
13                     str.append("\n内容:");
14                     str.append(m.getDisplayMessageBody());
15                 }
16                 Toast.makeText(context, "收到消息:\n" + str, Toast.LENGTH_LONG);
17             }
18         }

  最后在AndroidManifest.xml中处理一下新建的Receiver类即可。

  完整代码:

AndroidMainfest.xml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3     package="com.example.doodle.button" >
 4 
 5     <application
 6         android:allowBackup="true"
 7         android:icon="@mipmap/ic_launcher"
 8         android:label="@string/app_name"
 9         android:theme="@style/AppTheme" >
10         <activity
11             android:name=".MainActivity"
12             android:label="@string/app_name" >
13             <intent-filter>
14                 <action android:name="android.intent.action.MAIN" />
15                 <category android:name="android.intent.category.LAUNCHER" />
16             </intent-filter>
17         </activity>
18 
19         <receiver android:name=".Receiver" android:enabled="true">
20             <intent-filter>
21                 <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
22             </intent-filter>
23         </receiver>
24 
25     </application>
26 
27     <uses-permission android:name="android.permission.SEND_SMS"/>
28     <uses-permission android:name="android.permission.RECEIVE_SMS"/>
29 
30 </manifest>
View Code

MainActivity.java

 1 import android.support.v7.app.AppCompatActivity;
 2 import android.os.Bundle;
 3 
 4 public class MainActivity extends AppCompatActivity {
 5 
 6     @Override
 7     protected void onCreate(Bundle savedInstanceState) {
 8         super.onCreate(savedInstanceState);
 9         setContentView(R.layout.activity_main);
10 
11     }
12 }
View Code

Receiver.java

 1 import android.content.BroadcastReceiver;
 2 import android.content.Context;
 3 import android.content.Intent;
 4 import android.os.Bundle;
 5 import android.telephony.SmsMessage;
 6 import android.widget.Toast;
 7 
 8 public class Receiver extends BroadcastReceiver {
 9 
10     @Override
11     public void onReceive(Context context, Intent intent) {
12         if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
13             StringBuilder str = new StringBuilder();
14             Bundle bundle = intent.getExtras();
15             if (bundle != null) {
16                 Object[] pdus = (Object[]) bundle.get("pdus");
17                 SmsMessage[] msg = new SmsMessage[pdus.length];
18                 for (int i = 0; i < pdus.length; i++) {
19                     msg[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
20                 }
21                 for (SmsMessage m : msg) {
22                     str.append("发件人:");
23                     str.append(m.getDisplayOriginatingAddress());
24                     str.append("\n内容:");
25                     str.append(m.getDisplayMessageBody());
26                 }
27                 Toast.makeText(context, "收到消息:\n" + str, Toast.LENGTH_LONG);
28             }
29         }
30     }
31 }
View Code

 

posted @ 2015-10-26 19:35  doodle777  阅读(713)  评论(0编辑  收藏  举报