1. 程式人生 > >Android6.0下的簡訊接收與傳送功能的實現

Android6.0下的簡訊接收與傳送功能的實現

   最近學習了android6.0下的簡訊功能,發現《第一行程式碼》一書中的實現程式碼中使用的(byte[] pdu)函式,在API23中已經被棄用,取而代之的是(byte[] pdu, String format)(檢視)。看起來區別不大,但是為了找這個format引數的使用方法,還是費了挺大功夫的。接下來介紹具體用法。

  當我們需要使用createFromPdu函式時,其中的format引數可以使用以下方法賦值:

<pre name="code" class="java"><span style="font-size:14px;">    String format = intent.getStringExtra("format");</span>

下面是完整程式碼(已通過測試,已上傳github

MainActivity.java:

<span style="font-size:14px;">package com.example.administrator.smstest;

import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private TextView sender;
    private TextView content;
    private IntentFilter receiveFilter;
    private MessageReceiver messageReceiver;
    private EditText to;
    private EditText msgInput;
    private Button send;
    final private int REQUEST_CODE_ASK_PERMISSIONS = 123;
    private static final String TAG = "MainActivity";
    //測試github
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        sender = (TextView) findViewById(R.id.sender);
        content = (TextView) findViewById(R.id.content);
        to = (EditText) findViewById(R.id.to);
        msgInput = (EditText) findViewById(R.id.msg_input);
        //傳送簡訊
        send = (Button) findViewById(R.id.send);
        send.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v) {
                SmsManager smsManager = SmsManager.getDefault();
                smsManager.sendTextMessage(to.getText().toString(),null,msgInput.getText().toString(),null,null);
                to.setText("");
                msgInput.setText("");
            }
        });
        //查詢許可權,包含了接收簡訊
        queryAuthority();
        //監控簡訊傳送狀態的監聽器

    }

    protected void onDestroy(){
        super.onDestroy();
        //取消註冊
        unregisterReceiver(messageReceiver);
    }

    //查詢許可權
    private void queryAuthority() {
        int hasReadContactsPermission = 0;
        //Android Marshmallow
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            hasReadContactsPermission = checkSelfPermission(Manifest.permission.RECEIVE_SMS);
        }

        if (hasReadContactsPermission != PackageManager.PERMISSION_GRANTED) {

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//                請求授權對話方塊
                requestPermissions(new String[] {Manifest.permission.RECEIVE_SMS},
                        REQUEST_CODE_ASK_PERMISSIONS);
            }
            return;
        }
        //執行查詢操作
        registerReceiver();
    }
    //為簡訊監聽器註冊(動態)
    public void registerReceiver(){
        receiveFilter = new IntentFilter();
        receiveFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
        messageReceiver = new MessageReceiver();
        registerReceiver(messageReceiver,receiveFilter);
    }

    //回撥函式,不論使用者在授權對話方塊同意還是拒絕,activity的onRequestPermissionsResult會被回撥來通知結果(通過第三個引數)
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case REQUEST_CODE_ASK_PERMISSIONS:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // Permission Granted
                    //git  test >>>>>>>>>>>>>>>>>
                    queryAuthority();
                } else {
                    // Permission Denied
                    Toast.makeText(MainActivity.this, "READ_MESSAGE Denied", Toast.LENGTH_SHORT).show();
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

//監聽收到的簡訊
    class MessageReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            Bundle bundle = intent.getExtras();
            Object []pdus = (Object[]) bundle.get("pdus");
            String format = intent.getStringExtra("format");
            SmsMessage[]messages = new SmsMessage[pdus.length];
            Log.d(TAG, "onReceive format is "+format+" !!!!!! ");
            for(int i=0;i<messages.length;i++){
//                createFromPdu(byte []pdu)方法已被廢棄
//                原因是為了同時支援3GPP和3GPP2
//                他們是移動系統通訊標準的擬定組織分別擬定的GSM/UMTS/LTE標準和CDMA/LTE標準
//                因此推薦是用的方法是createFromPdu(byte[] pdu, String format)
//                其中fotmat可以是SmsConstants.FORMAT_3GPP或者SmsConstants.FORMAT_3GPP2
                byte[] sms = (byte[])pdus[i];
                messages[i]  = SmsMessage.createFromPdu(sms,format);
            }
            //獲取傳送方手機號碼
            String address = messages[0].getOriginatingAddress();
            String fullMessage = "";
            for(SmsMessage message:messages){
                //獲取簡訊內容(簡訊內容太長會被分段)
                fullMessage += message.getMessageBody();
            }
            content.setText(fullMessage);
            sender.setText(address);
        }
    }

    //監聽傳送出去的簡訊狀態
    class SendStatusReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            if(getResultCode() == RESULT_OK){
                //簡訊傳送成功
                Toast.makeText(context,"Send successfully!!!!",Toast.LENGTH_SHORT).show();
            }else
                //傳送失敗
            Toast.makeText(context,"Send fail!!!!",Toast.LENGTH_SHORT).show();
        }
    }
}</span>

activity_main.xml

<span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.administrator.smstest.MainActivity"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="50dp">

</span><pre name="code" class="java"><span style="font-size:14px;"><!-- 簡訊傳送方的號碼 --></span>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:padding="10dp" android:text="From:"/> <TextView android:id="@+id/sender" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical"/> </LinearLayout>
<!-- 收到的簡訊內容 -->
<LinearLayout android:layout_width="match_parent" android:layout_height="50dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:padding="10dp" android:text="Content:"/> <TextView android:id="@+id/content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" /> </LinearLayout>
<pre name="code" class="java"><span style="font-size:14px;"><!-- 收簡訊一方的號碼 --></span>
<LinearLayout android:layout_width="match_parent" android:layout_height="50dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:padding="10dp" android:text="To:"/> <EditText android:id="@+id/to" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_weight="1"/> </LinearLayout>
<span style="font-size:14px;"><!-- 編輯簡訊內容 --></span>
<EditText android:id="@+id/msg_input" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:maxLines="2"/>
<span style="font-size:14px;"><!-- 傳送簡訊按鈕 --></span>
<Button android:id="@+id/send" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:text="Send"/></LinearLayout>

順帶一提,我在使用android studio自帶的android模擬器試圖傳送簡訊時,Emulator Control也出現了變灰,無法使用的情況,一直沒能解決。

後來我發現,其實不需要使用Amulator Control,直接點選模擬器右側的功能欄這個按鈕即可


功能非常豐富,介面也很漂亮,下面是編輯簡訊介面: