J'ai compris comment envoyer et recevoir des SMS. Pour envoyer des SMS, j'ai dû appeler les méthodes sendTextMessage()
et sendMultipartTextMessage()
de la SmsManager
classe. Pour recevoir des SMS, j'ai dû enregistrer un destinataire dans le AndroidMainfest.xml
fichier. Ensuite, j'ai dû remplacer la onReceive()
méthode du BroadcastReceiver
. J'ai inclus des exemples ci-dessous.
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>
Cependant, je me demandais si vous pouviez envoyer et recevoir des messages MMS de la même manière. Après quelques recherches, de nombreux exemples fournis sur les blogs passent simplement un Intent
à l'application de messagerie native. J'essaye d'envoyer un MMS sans quitter mon application. Il ne semble pas y avoir de moyen standard d'envoyer et de recevoir des MMS. Quelqu'un a-t-il réussi à faire fonctionner cela?
De plus, je sais que le fournisseur de contenu SMS / MMS ne fait pas partie du SDK Android officiel, mais je pensais que quelqu'un aurait pu l'implémenter. Toute aide est grandement appréciée.
Mettre à jour
J'ai ajouté un BroadcastReceiver
au AndroidManifest.xml
fichier pour recevoir des messages 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>
Dans la classe MMSReceiver, la onReceive()
méthode ne peut récupérer que le phoneNumber à partir duquel le message a été envoyé. Comment récupérez-vous d'autres éléments importants d'un MMS comme le chemin du fichier vers la pièce jointe multimédia (image / audio / vidéo) ou le texte dans le 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...
}
}
Selon la documentation de android.provider.Telephony :
Action de diffusion: un nouveau message SMS textuel a été reçu par l'appareil. L'intention aura les valeurs supplémentaires suivantes:
pdus
- UnObject[]
debyte[]
s contenant les PDU qui composent le message.Les valeurs supplémentaires peuvent être extraites à l'aide de
getMessagesFromIntent(android.content.Intent)
Si un BroadcastReceiver rencontre une erreur lors du traitement de cette intention, il doit définir le code de résultat de manière appropriée.@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
Action de diffusion: un nouveau message SMS basé sur les données a été reçu par l'appareil. L'intention aura les valeurs supplémentaires suivantes:
pdus
- UnObject[]
debyte[]
s contenant les PDU qui composent le message.Les valeurs supplémentaires peuvent être extraites à l'aide de getMessagesFromIntent (android.content.Intent). Si un BroadcastReceiver rencontre une erreur lors du traitement de cette intention, il doit définir le code de résultat de manière appropriée.
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String DATA_SMS_RECEIVED_ACTION = "android.intent.action.DATA_SMS_RECEIVED";
Action de diffusion: un nouveau message WAP PUSH a été reçu par l'appareil. L'intention aura les valeurs supplémentaires suivantes:
transactionId (Integer)
- L'ID de transaction WAP
pduType (Integer)
- Le type de PDU WAP`
header (byte[])
- L'en-tête du message
data (byte[])
- La charge de données du message
contentTypeParameters (HashMap<String,String>)
- Tous les paramètres associés au type de contenu (décodés à partir de l'en-tête Content-Type du WSP)Si un BroadcastReceiver rencontre une erreur lors du traitement de cette intention, il doit définir le code de résultat de manière appropriée. La valeur supplémentaire contentTypeParameters est une carte des paramètres de contenu indexés par leur nom. Si des paramètres connus non attribués sont rencontrés, la clé de la carte sera «unassigned / 0x ...», où «...» est la valeur hexadécimale du paramètre non assigné. Si un paramètre n'a aucune valeur, la valeur de la carte sera nulle.
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String WAP_PUSH_RECEIVED_ACTION = "android.provider.Telephony.WAP_PUSH_RECEIVED";
Mise à jour # 2
J'ai compris comment passer des extras dans un PendingIntent
pour être reçu par un BroadcastReceiver
:
extras Android PendingIntent, non reçus par BroadcastReceiver
Toutefois, le supplément est transmis au SendBroadcastReceiver et non au SMSReceiver . Comment puis-je transmettre un supplément au SMSReceiver ?
Mise à jour n ° 3
Recevoir des MMS
Donc, après avoir fait plus de recherches, j'ai vu quelques suggestions d'enregistrement d'un fichier ContentObserver
. De cette façon, vous pouvez détecter les modifications apportées au content://mms-sms/conversations
fournisseur de contenu, ce qui vous permet par conséquent de détecter les MMS entrants. Voici l'exemple le plus proche pour que cela fonctionne que j'ai trouvé: Réception de MMS
Cependant, il existe une variable mainActivity
de type ServiceController
. Où la ServiceController
classe est-elle implémentée? Existe-t-il d'autres implémentations d'un enregistré ContentObserver
?
Envoi de MMS
Quant à l'envoi de MMS, je suis tombé sur cet exemple: Envoyer des MMS
Le problème est que j'ai essayé d'exécuter ce code sur mon Nexus 4, qui est sur Android v4.2.2, et je reçois cette erreur:
java.lang.SecurityException: No permission to write APN settings: Neither user 10099 nor current process has android.permission.WRITE_APN_SETTINGS.
L'erreur est levée après avoir interrogé Carriers
ContentProvider dans la getMMSApns()
méthode de la APNHelper
classe.
final Cursor apnCursor = this.context.getContentResolver().query(Uri.withAppendedPath(Carriers.CONTENT_URI, "current"), null, null, null, null);
Apparemment, vous ne pouvez pas lire les APN dans Android 4.2
Quelle est l'alternative pour toutes ces applications qui utilisent des données mobiles pour effectuer des opérations (comme l'envoi de MMS) et ne connaissent pas le paramètre APN par défaut présent dans l'appareil?
Mise à jour n ° 4
Envoi de MMS
J'ai essayé de suivre cet exemple: Envoyer des MMS
Comme @Sam l'a suggéré dans sa réponse:
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.
Alors maintenant, je n'obtiens plus les erreurs SecurityException. Je teste maintenant sur un Nexus 5 sur Android KitKat. Après avoir exécuté l'exemple de code, il me donne un code de réponse 200 après l'appel à
MMResponse mmResponse = sender.send(out, isProxySet, MMSProxy, MMSPort);
Cependant, j'ai vérifié auprès de la personne à qui j'ai essayé d'envoyer le MMS. Et ils ont dit qu'ils n'avaient jamais reçu le MMS.
la source
Réponses:
J'ai eu exactement le même problème que vous décrivez ci-dessus (Galaxy Nexus sur t-mobile USA), c'est parce que les données mobiles sont désactivées.
Dans Jelly Bean, c'est: Paramètres> Utilisation des données> données mobiles
Notez que je dois activer les données mobiles AVANT d'envoyer un MMS OU d'en recevoir un. Si je reçois un MMS avec les données mobiles désactivées, je recevrai la notification d'un nouveau message et je recevrai le message avec un bouton de téléchargement. Mais si je n'ai pas de données mobiles avant, la pièce jointe MMS entrante ne sera pas reçue. Même si je l'allume après la réception du message.
Pour une raison quelconque, lorsque votre fournisseur de téléphonie vous permet d'envoyer et de recevoir des MMS, vous devez activer les données mobiles, même si vous utilisez le Wifi, si les données mobiles sont activées, vous pourrez recevoir et envoyer des MMS, même si Le Wi-Fi apparaît comme votre connexion Internet sur votre appareil.
C'est vraiment pénible, car si vous ne l'avez pas allumé, le message peut se bloquer beaucoup, même lors de l'activation des données mobiles, et peut nécessiter un redémarrage de l'appareil.
la source
Il n'y a pas de support officiel d'API, ce qui signifie qu'il n'est pas documenté pour le public et que les bibliothèques peuvent changer à tout moment. Je me rends compte que vous ne voulez pas quitter l'application, mais voici comment procéder avec l'intention que toute autre personne se demande.
Je n'ai pas complètement compris comment faire des choses comme suivre la livraison du message, mais cela devrait être envoyé.
Vous pouvez être alerté de la réception de mms de la même manière que les sms. Le filtre d'intention sur le récepteur devrait ressembler à ceci.
la source
BroadcastReceiver
, et j'ai utilisé leIntent Filter
que vous avez posté. Je mettrai à jour cette question bientôt.Pour envoyer un mms pour Android 4.0 api 14 ou supérieur sans autorisation d'écrire les paramètres apn, vous pouvez utiliser cette bibliothèque : Récupérez les codes mnc et mcc depuis Android, puis appelez
Pour l'utiliser, ajoutez Jsoup et droid prism jar au chemin de construction et importez com.droidprism. *;
la source
java.lang.NoClassDefFoundError: com.droidprism.Carrier
est-ce que cela vous arrive?Je ne pense pas qu'il existe un support sdk pour l'envoi de mms dans Android. Regardez ici Au moins je n'ai pas encore trouvé. Mais un gars a prétendu l'avoir. Jetez un œil à ce post.
Envoyer des MMS depuis mon application sous Android
la source
Je ne comprends pas les frustrations. Pourquoi ne pas simplement créer un récepteur de diffusion qui filtre cette intention:
J'ai vérifié un peu plus loin et vous pourriez avoir besoin d'un accès au niveau du système pour l'obtenir (téléphone enraciné).
la source
la source