当前位置: 首页 > 知识库问答 >
问题:

在Android中发送和接收短信和彩信(Pre-Kit Kat Android 4.4)

苏俊友
2023-03-14

我已经想好了如何发送和接收短信。要发送SMS消息,我必须调用SMSManager类的SendTextMessage()SendMultipartTextMessage()方法。要接收SMS消息,我必须在AndroidMainfest.xml文件中注册一个接收方。然后我必须重写broadcastreceiveronreceive()方法。我在下面列出了一些例子。

mainactivity.java

public class MainActivity extends Activity {
    private static String SENT = "SMS_SENT";
    private static String DELIVERED = "SMS_DELIVERED";
    private static int MAX_SMS_MESSAGE_LENGTH = 160;

    // ---sends an SMS message to another device---
    public static void sendSMS(String phoneNumber, String message) {

        PendingIntent piSent = PendingIntent.getBroadcast(mContext, 0, new Intent(SENT), 0);
        PendingIntent piDelivered = PendingIntent.getBroadcast(mContext, 0,new Intent(DELIVERED), 0);
        SmsManager smsManager = SmsManager.getDefault();

        int length = message.length();          
        if(length > MAX_SMS_MESSAGE_LENGTH) {
            ArrayList<String> messagelist = smsManager.divideMessage(message);          
            smsManager.sendMultipartTextMessage(phoneNumber, null, messagelist, null, null);
        }
        else
            smsManager.sendTextMessage(phoneNumber, null, message, piSent, piDelivered);
        }
    }

    //More methods of MainActivity ...
}
public class SMSReceiver extends BroadcastReceiver {
    private final String DEBUG_TAG = getClass().getSimpleName().toString();
    private static final String ACTION_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
    private Context mContext;
    private Intent mIntent;

    // Retrieve SMS
    public void onReceive(Context context, Intent intent) {
        mContext = context;
        mIntent = intent;

        String action = intent.getAction();

        if(action.equals(ACTION_SMS_RECEIVED)){

            String address, str = "";
            int contactId = -1;

            SmsMessage[] msgs = getMessagesFromIntent(mIntent);
            if (msgs != null) {
                for (int i = 0; i < msgs.length; i++) {
                    address = msgs[i].getOriginatingAddress();
                    contactId = ContactsUtils.getContactId(mContext, address, "address");
                    str += msgs[i].getMessageBody().toString();
                    str += "\n";
                }
            }   

            if(contactId != -1){
                showNotification(contactId, str);
            }

            // ---send a broadcast intent to update the SMS received in the
            // activity---
            Intent broadcastIntent = new Intent();
            broadcastIntent.setAction("SMS_RECEIVED_ACTION");
            broadcastIntent.putExtra("sms", str);
            context.sendBroadcast(broadcastIntent);
        }

    }

    public static SmsMessage[] getMessagesFromIntent(Intent intent) {
        Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
        byte[][] pduObjs = new byte[messages.length][];

        for (int i = 0; i < messages.length; i++) {
            pduObjs[i] = (byte[]) messages[i];
        }
        byte[][] pdus = new byte[pduObjs.length][];
        int pduCount = pdus.length;
        SmsMessage[] msgs = new SmsMessage[pduCount];
        for (int i = 0; i < pduCount; i++) {
            pdus[i] = pduObjs[i];
            msgs[i] = SmsMessage.createFromPdu(pdus[i]);
        }
        return msgs;
    }

    /**
    * The notification is the icon and associated expanded entry in the status
    * bar.
    */
    protected void showNotification(int contactId, String message) {
        //Display notification...
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.myexample"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="17" />

    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.WRITE_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_MMS" />
    <uses-permission android:name="android.permission.WRITE" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:debuggable="true"
        android:icon="@drawable/ic_launcher_icon"
        android:label="@string/app_name" >

        <activity
            //Main activity...
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            //Activity 2 ...
        </activity>
        //More acitivies ...

        // SMS Receiver
        <receiver android:name="com.myexample.receivers.SMSReceiver" >
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>

    </application>
</manifest>

然而,我想知道你是否可以发送和接收彩信以类似的方式。在做了一些研究之后,博客上提供的许多示例只是将intent传递给本机消息传递应用程序。我正在尝试发送一个彩信而不离开我的应用程序。似乎没有一个标准的发送和接收彩信的方式。有人把这个弄好了吗?

此外,我知道SMS/MMS内容提供程序不是官方Android SDK的一部分,但我想有人可能已经实现了这一点。非常感谢任何帮助。

<receiver android:name="com.sendit.receivers.MMSReceiver" >
    <intent-filter>
        <action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" />

        <data android:mimeType="application/vnd.wap.mms-message" />
    </intent-filter>
</receiver>

MMSReceiver.java

public class MMSReceiver extends BroadcastReceiver {
    private final String DEBUG_TAG = getClass().getSimpleName().toString();
    private static final String ACTION_MMS_RECEIVED = "android.provider.Telephony.WAP_PUSH_RECEIVED";
    private static final String MMS_DATA_TYPE = "application/vnd.wap.mms-message";

     // Retrieve MMS
    public void onReceive(Context context, Intent intent) {

        String action = intent.getAction();
        String type = intent.getType();

        if(action.equals(ACTION_MMS_RECEIVED) && type.equals(MMS_DATA_TYPE)){

            Bundle bundle = intent.getExtras();

            Log.d(DEBUG_TAG, "bundle " + bundle);
            SmsMessage[] msgs = null;
            String str = "";
            int contactId = -1;
            String address;

            if (bundle != null) {

                byte[] buffer = bundle.getByteArray("data");
                Log.d(DEBUG_TAG, "buffer " + buffer);
                String incomingNumber = new String(buffer);
                int indx = incomingNumber.indexOf("/TYPE");
                if(indx>0 && (indx-15)>0){
                    int newIndx = indx - 15;
                    incomingNumber = incomingNumber.substring(newIndx, indx);
                    indx = incomingNumber.indexOf("+");
                    if(indx>0){
                        incomingNumber = incomingNumber.substring(indx);
                        Log.d(DEBUG_TAG, "Mobile Number: " + incomingNumber);
                    }
                }

                int transactionId = bundle.getInt("transactionId");
                Log.d(DEBUG_TAG, "transactionId " + transactionId);

                int pduType = bundle.getInt("pduType");
                Log.d(DEBUG_TAG, "pduType " + pduType);

                byte[] buffer2 = bundle.getByteArray("header");      
                String header = new String(buffer2);
                Log.d(DEBUG_TAG, "header " + header);

                if(contactId != -1){
                    showNotification(contactId, str);
                }

                // ---send a broadcast intent to update the MMS received in the
                // activity---
                Intent broadcastIntent = new Intent();
                broadcastIntent.setAction("MMS_RECEIVED_ACTION");
                broadcastIntent.putExtra("mms", str);
                context.sendBroadcast(broadcastIntent);

            }
        }

    }

    /**
    * The notification is the icon and associated expanded entry in the status
    * bar.
    */
    protected void showNotification(int contactId, String message) {
        //Display notification...
    }
}

根据Android.Provider.Telephony的文档:

广播操作:设备已接收到一个新的基于文本的SMS消息。该意图将具有以下额外价值:

 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
 public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";

广播操作:设备已接收到新的基于数据的SMS消息。该意图将具有以下额外价值:

PDU-byte[]对象[]包含组成消息的PDU。

可以使用getMessagesFromIntent(Android.content.intent)提取额外的值。如果BroadcastReceiver在处理这个意图时遇到错误,它应该适当地设置结果代码。

@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String DATA_SMS_RECEIVED_ACTION = "android.intent.action.DATA_SMS_RECEIVED";

广播操作:设备已接收到新的WAP推送消息。该意图将具有以下额外价值:

transactionid(Integer)-WAP事务ID

PDUType(Integer)-WAP PDU类型`

ContentTypeParameters(hashmap ) -与内容类型相关联的任何参数(从WSP Content-Type头解码)

如果BroadcastReceiver在处理这个意图时遇到错误,它应该适当地设置结果代码。contentTypeParameters额外值是内容参数的map(按其名称键控)。如果遇到任何未分配的已知参数,映射的键将是“未分配/0x...",其中”...“未赋值参数的十六进制值。如果参数没有值,则映射中的值将为空。

@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String WAP_PUSH_RECEIVED_ACTION = "android.provider.Telephony.WAP_PUSH_RECEIVED";

我已经想好了如何在PendingIntent中传递额外的内容,以便由BroadcastReceiver接收:Android PendingIntent额外的内容,而不是由BroadcastReceiver接收

但是,额外的部分会传递给SendBroadcastReceiver,而不是SMSReceiver。我如何向SMSReceiver传递额外的信息?

接收彩信

所以在做了更多的研究之后,我看到了一些注册ContentObserver的建议。通过这种方式,您可以检测Content:/mms-sms/conversations内容提供程序何时发生了任何更改,从而允许您检测传入的彩信。下面是我找到的最接近于实现这一功能的例子:接收彩信

但是,有一个ServiceController类型的变量MainActivityServiceController类在哪里实现?注册的ContentObserver是否有其他实现?

发送彩信

问题是我尝试在我的Nexus4上运行这段代码,它是在AndroidV4.2.2上,我收到了这个错误:

java.lang.SecurityException: No permission to write APN settings: Neither user 10099 nor current process has android.permission.WRITE_APN_SETTINGS.

apnhelper类的getMmsapns()方法中查询carrierContentProvider后,将引发该错误。

final Cursor apnCursor = this.context.getContentResolver().query(Uri.withAppendedPath(Carriers.CONTENT_URI, "current"), null, null, null, null);

显然,你无法在Android4.2中读取APN

对于那些使用移动数据执行操作(如发送彩信)并且不知道设备中存在的默认APN设置的应用程序,有什么替代方案?

发送彩信

我尝试过以下示例:发送彩信

所以现在我不再得到SecurityException错误。我现在正在Android Kitkat上的Nexus5上进行测试。运行示例代码后,在调用

MMResponse mmResponse = sender.send(out, isProxySet, MMSProxy, MMSPort);

然而,我和我试图发送彩信的人进行了核实。他们说他们从来没有收到过彩信。

共有1个答案

司空俊雄
2023-03-14

我遇到了和你上面描述的完全一样的问题(美国t-mobile上的Galaxy Nexus),那是因为移动数据被关闭了。

在Jelly Bean中是:设置>数据使用>移动数据

注意,我必须在发送彩信或接收彩信之前打开移动数据。如果我收到一个移动数据关闭的彩信,我会得到一个新消息的通知,我会收到一个下载按钮的消息。但如果我在Priver上没有移动数据,传入的MMS附件将不会被接收。即使我在收到消息后打开它。

这是一个真正的痛苦,就像你没有它,消息可以挂起很多,甚至在打开移动数据,并可能需要重新启动设备。

 类似资料:
  • 本文向大家介绍Android接收和发送短信处理,包括了Android接收和发送短信处理的使用技巧和注意事项,需要的朋友参考一下 关于短信接收处理方面,当前已经有一些app做的比较好了,比如发给手机发验证码验证的问题,很多app在手机接收到验证码后,不需要输入,就直接可以跳过验证界面,这就是用到了对接收到的短信的处理。至于短信的发送,也没什么好说的了。在此也只是附上一个小实例。 效果图: MainA

  • 我正在尝试设置一个类来接收短信和发送状态。以下是我的清单如何查找此任务: 我收到了收到的消息,但没有收到发送的消息,我的清单声明有问题吗?

  • 我希望我的Java应用程序在不使用任何额外硬件设备的情况下发送和接收短信,而且它必须是免费的。 我进行了搜索,但我只找到了标题,我找到了一些类似SMSLib的东西,但另一方面,我没有找到学习这些的教程或书籍。 我还发现了SMSLib代码,但不明白: 发送消息/短信代码 阅读信息/短信代码

  • 本文向大家介绍Android创建简单发送和接收短信应用,包括了Android创建简单发送和接收短信应用的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Android创建发送和接收短信应用的简单实现过程,供大家参考,具体内容如下 一、接收短信 项目的结构如下:一个简单的接收和发送短信的功能 1、定义一个接收短信的广播:当手机接收到一条短信的时候,系统会发出一条值为android.pro

  • 本文向大家介绍Android项目实现短信的发送、接收和对短信进行拦截,包括了Android项目实现短信的发送、接收和对短信进行拦截的使用技巧和注意事项,需要的朋友参考一下 说实话,关于Android中对短信的一些相关操作是一个比较入门的东西。那我现在还要来写这一篇博客的原因只是因为现在开发中有相关内容,而又想将这些东西分享给更多的人来学习,同时在以后对Android系统的短信进行其他学习的时候也就

  • 本文向大家介绍详解Android短信的发送和广播接收实现短信的监听,包括了详解Android短信的发送和广播接收实现短信的监听的使用技巧和注意事项,需要的朋友参考一下 本文介绍了Android短信的发送和广播接收者实现短信的监听,要注意Android清单中权限的设置以及广播的注册监听实现,废话不多说,代码如下: 以下就是 Android清单的XML AndroidManifest.xml 发送短息