Я понял, как отправлять и получать SMS-сообщения. Для отправки SMS - сообщений , которые я должен был назвать sendTextMessage()
и sendMultipartTextMessage()
методы SmsManager
класса. Чтобы получать смс-сообщения, мне пришлось прописать получателя в 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>
Однако мне было интересно, можно ли аналогичным образом отправлять и получать сообщения MMS. После некоторых исследований многие примеры, представленные в блогах, просто передаются Intent
в собственное приложение обмена сообщениями. Я пытаюсь отправить MMS, не выходя из приложения. Кажется, нет стандартного способа отправки и получения MMS. У кого-нибудь это работает?
Кроме того, я знаю, что ContentProvider SMS / MMS не является частью официального Android SDK, но я думал, что кто-то, возможно, смог это реализовать. Любая помощь очень ценится.
Обновить
Я добавил BroadcastReceiver
в AndroidManifest.xml
файл, чтобы получать сообщения MMS
<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...
}
}
Согласно документации android.provider.Telephony :
Действие широковещательной рассылки: устройство получило новое текстовое SMS-сообщение. У намерения будут следующие дополнительные значения:
pdus
- ЭлементObject[]
изbyte[]
s, содержащий блоки PDU, составляющие сообщение.Дополнительные значения могут быть извлечены с помощью.
getMessagesFromIntent(android.content.Intent)
Если BroadcastReceiver обнаруживает ошибку при обработке этого намерения, он должен соответствующим образом установить код результата.@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
Действие широковещательной передачи: устройство получило новое SMS-сообщение на основе данных. У намерения будут следующие дополнительные значения:
pdus
- ЭлементObject[]
изbyte[]
s, содержащий блоки 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 PUSH. У намерения будут следующие дополнительные значения:
transactionId (Integer)
- ID транзакции WAP
pduType (Integer)
- Тип WAP PDU`
header (byte[])
- Заголовок сообщения
data (byte[])
- Полезные данные сообщения
contentTypeParameters (HashMap<String,String>)
- Любые параметры, связанные с типом контента (декодированные из заголовка WSP Content-Type)Если BroadcastReceiver обнаруживает ошибку при обработке этого намерения, он должен соответствующим образом установить код результата. Дополнительное значение contentTypeParameters - это карта параметров содержимого, привязанных к их именам. Если встречаются какие-либо неназначенные общеизвестные параметры, ключ карты будет 'unassigned / 0x ...', где '...' - шестнадцатеричное значение неназначенного параметра. Если параметр не имеет значения, значение на карте будет нулевым.
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String WAP_PUSH_RECEIVED_ACTION = "android.provider.Telephony.WAP_PUSH_RECEIVED";
Обновление № 2
Я выяснил, как передать дополнения в объект, PendingIntent
который будет получен BroadcastReceiver
:
дополнениями Android PendingIntent, не полученными BroadcastReceiver
Однако дополнительная информация передается в SendBroadcastReceiver, а не в SMSReceiver . Как передать SMSReceiver дополнительную услугу ?
Обновление № 3
Получение MMS
Итак, после дополнительных исследований я увидел несколько предложений по регистрации домена ContentObserver
. Таким образом, вы можете определить, есть ли какие-либо изменения в content://mms-sms/conversations
Content Provider, что позволит вам обнаруживать входящие MMS. Вот ближайший из обнаруженных мною пример того, как это работает: получение MMS.
Однако есть переменная mainActivity
типа ServiceController
. Где ServiceController
реализован класс? Есть ли другие реализации зарегистрированного ContentObserver
?
Отправка MMS
Что касается отправки MMS, я встречал такой пример: Отправить MMS
Проблема в том, что я пытался запустить этот код на своем Nexus 4, который находится на Android v4.2.2, и получаю следующую ошибку:
java.lang.SecurityException: No permission to write APN settings: Neither user 10099 nor current process has android.permission.WRITE_APN_SETTINGS.
Ошибка возникает после запроса Carriers
ContentProvider в getMMSApns()
методе APNHelper
класса.
final Cursor apnCursor = this.context.getContentResolver().query(Uri.withAppendedPath(Carriers.CONTENT_URI, "current"), null, null, null, null);
Похоже, вы не можете читать APN в Android 4.2
Какая альтернатива для всех тех приложений, которые используют мобильные данные для выполнения операций (например, отправки MMS) и не знают настройки APN по умолчанию, присутствующей в устройстве?
Обновление № 4
Отправка MMS
Я пробовал следовать этому примеру: Отправить 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. Сейчас я тестирую Nexus 5 на Android KitKat. После запуска примера кода он дает мне код ответа 200 после вызова
MMResponse mmResponse = sender.send(out, isProxySet, MMSProxy, MMSPort);
Однако я посоветовался с человеком, которому пытался отправить MMS. И они сказали, что никогда не получали MMS.
источник
Ответы:
У меня была точно такая же проблема, как вы описали выше (Galaxy Nexus на t-mobile USA), потому что мобильные данные отключены.
В Jelly Bean это: Настройки> Использование данных> мобильные данные.
Обратите внимание, что у меня должны быть включены мобильные данные ДО отправки MMS ИЛИ получения его. Если я получу MMS с отключенными мобильными данными, я получу уведомление о новом сообщении, и я получу сообщение с кнопкой загрузки. Но если у меня нет данных по мобильной связи, входящее вложение MMS не будет получено. Даже если я его включу после получения сообщения.
По какой-то причине, когда ваш телефонный провайдер позволяет вам отправлять и получать MMS, вы должны включить мобильные данные, даже если вы используете Wi-Fi, если мобильные данные включены, вы сможете получать и отправлять MMS, даже если Wi-Fi отображается на вашем устройстве как ваш Интернет.
Это настоящая боль, так как, если у вас его нет, сообщение может сильно зависать, даже при включении мобильных данных, и может потребоваться перезагрузка устройства.
источник
Официальной поддержки API нет, что означает, что он не документирован для общественности, и библиотеки могут быть изменены в любое время. Я понимаю, что вы не хотите выходить из приложения, но вот как вы это делаете, чтобы всем было интересно.
Я не совсем понял, как делать такие вещи, как отслеживать доставку сообщения, но теперь оно должно быть отправлено.
Вы можете быть предупреждены о получении ммс так же, как смс. Фильтр намерений на приемнике должен выглядеть так.
источник
BroadcastReceiver
и использовал то,Intent Filter
что вы разместили. Я скоро обновлю этот вопрос.Чтобы отправить mms для Android 4.0 api 14 или более поздней версии без разрешения на запись настроек apn, вы можете использовать эту библиотеку : получить коды mnc и mcc из android, затем вызвать
Чтобы использовать это, добавьте Jsoup и droid prism jar в путь сборки и импортируйте com.droidprism. *;
источник
java.lang.NoClassDefFoundError: com.droidprism.Carrier
это происходит с вами?Я не думаю, что есть поддержка sdk для отправки ммс в android. Посмотрите здесь По крайней мере, я еще не нашел. Но парень утверждал, что у него это есть. Взгляните на этот пост.
Отправить MMS из моего приложения в android
источник
Я не понимаю разочарования. Почему бы просто не сделать широковещательный приемник, который фильтрует это намерение:
Я проверил немного дальше, и вам может потребоваться доступ на системном уровне, чтобы получить это (рутированный телефон).
источник
источник