gpt4 book ai didi

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

转载 作者:IT老高 更新时间:2023-10-28 12:59:02 31 4
gpt4 key购买 nike

我已经弄清楚如何发送和接收 SMS 消息。要发送 SMS 消息,我必须调用 sendTextMessage()sendMultipartTextMessage() SmsManager 的方法类(class)。要接收 SMS 消息,我必须在 AndroidMainfest.xml 中注册一个接收器。文件。然后我不得不覆盖 onReceive() BroadcastReceiver 的方法.我在下面提供了示例。

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 ...
}

SMSReceiver.java

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到 native 消息传递应用程序。我正在尝试在不离开我的应用程序的情况下发送彩信。似乎没有发送和接收彩信的标准方式。有人让这个工作吗?

另外,我知道 SMS/MMS ContentProvider 不是官方 Android SDK 的一部分,但我想可能有人能够实现这一点。非常感谢任何帮助。

更新

我添加了一个 BroadcastReceiverAndroidManifest.xml接收彩信的文件

<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 类中,onReceive()方法只能获取发送消息的电话号码。您如何从 MMS 中获取其他重要信息,例如媒体附件(图像/音频/视频)的文件路径或 MMS 中的文本?

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...
}
}

根据Documentation of android.provider.Telephony :

Broadcast Action: A new text based SMS message has been received by the device. The intent will have the following extra values:

pdus - An Object[] of byte[]s containing the PDUs that make up the message.

The extra values can be extracted using getMessagesFromIntent(android.content.Intent) If a BroadcastReceiver encounters an error while processing this intent it should set the result code appropriately.

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

Broadcast Action: A new data based SMS message has been received by the device. The intent will have the following extra values:

pdus - An Object[] of byte[]s containing the PDUs that make up the message.

The extra values can be extracted using getMessagesFromIntent(android.content.Intent). If a BroadcastReceiver encounters an error while processing this intent it should set the result code appropriately.

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

Broadcast Action: A new WAP PUSH message has been received by the device. The intent will have the following extra values:

transactionId (Integer) - The WAP transaction ID

pduType (Integer) - The WAP PDU type`

header (byte[]) - The header of the message

data (byte[]) - The data payload of the message

contentTypeParameters (HashMap<String,String>) - Any parameters associated with the content type (decoded from the WSP Content-Type header)

If a BroadcastReceiver encounters an error while processing this intent it should set the result code appropriately. The contentTypeParameters extra value is map of content parameters keyed by their names. If any unassigned well-known parameters are encountered, the key of the map will be 'unassigned/0x...', where '...' is the hex value of the unassigned parameter. If a parameter has No-Value the value in the map will be null.

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

更新 #2

我已经知道如何在 PendingIntent 中传递额外内容由 BroadcastReceiver 接收: Android PendingIntent extras, not received by BroadcastReceiver

但是,额外的被传递给 SendBroadcastReceiver 而不是 SMSReceiver。我怎样才能将额外信息传递给 SMSReceiver

更新 #3

接收彩信

所以在做了更多研究之后,我看到了一些注册 ContentObserver 的建议。 .这样您就可以检测到 content://mms-sms/conversations 何时有任何更改。内容提供程序,因此允许您检测传入的彩信。这是我发现的最接近的示例:Receiving MMS

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

发送彩信

关于发送彩信,我遇到过这个例子:Send MMS

问题是我尝试在 Android v4.2.2 上的 Nexus 4 上运行此代码,但收到此错误:

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

查询 Carriers 后抛出错误getMMSApns() 中的 ContentProvider APNHelper 的方法类。

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

显然你不能read APNs in Android 4.2

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

更新 #4

发送彩信

我尝试过以下示例:Send MMS

正如@Sam 在他的回答中建议的那样:

You have to add jsoup to the build path, the jar to the build path and import com.droidprism.*; To do that in android, add the jars to the libs directory first, then configure the project build path to use the jars already in the libs directory, then on the build path config click order and export and check the boxes of the jars and move jsoup and droidprism jar to the top of the build order.

所以现在我不再收到 SecurityException 错误。我现在正在 Android KitKat 上的 Nexus 5 上进行测试。运行示例代码后,它会在调用

后给我一个 200 响应代码
MMResponse mmResponse = sender.send(out, isProxySet, MMSProxy, MMSPort);

但是,我与尝试向其发送彩信的人进行了核实。他们说他们从未收到过彩信。

最佳答案

我遇到了与您在上面描述的完全相同的问题(t-mobile USA 上的 Galaxy Nexus),这是因为移动数据已关闭。

在果冻 bean 中是:设置 > 数据使用 > 移动数据

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

由于某些原因,当您的电话提供商允许您发送和接收彩信时,您必须启用移动数据,即使您使用的是 Wifi,如果启用了移动数据,您将能够接收和发送彩信,即使 Wifi 在您的设备上显示为您的互联网。

这真的很痛苦,就像你没有打开它一样,即使打开移动数据,消息也会挂很多,并且可能需要重新启动设备。

关于android - 在 Android 中发送和接收短信和彩信(Kit Kat Android 4.4 之前),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14452808/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com