Saya telah menemukan cara untuk mengirim dan menerima pesan SMS. Untuk mengirim pesan SMS saya harus memanggil metode sendTextMessage()
dan kelas. Untuk menerima pesan SMS, saya harus mendaftarkan penerima di file. Kemudian saya harus mengganti metode . Saya telah memasukkan contoh di bawah ini.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>
Namun, saya bertanya-tanya apakah Anda bisa mengirim dan menerima pesan MMS dengan cara yang sama. Setelah melakukan beberapa penelitian, banyak contoh yang disediakan di blog hanya meneruskan Intent
ke aplikasi Pesan asli. Saya mencoba mengirim MMS tanpa meninggalkan aplikasi saya. Tampaknya tidak ada cara standar untuk mengirim dan menerima MMS. Adakah yang berhasil melakukannya?
Juga, saya menyadari bahwa ContentProvider SMS / MMS bukan bagian dari SDK Android resmi, tetapi saya berpikir seseorang mungkin dapat menerapkan ini. Setiap bantuan sangat dihargai.
Memperbarui
Saya telah menambahkan BroadcastReceiver
ke AndroidManifest.xml
file untuk menerima pesan 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>
Di kelas MMSReceiver, onReceive()
metode ini hanya dapat meraih Nomor telepon tempat pesan dikirim. Bagaimana Anda mengambil hal-hal penting lainnya dari MMS seperti jalur file ke lampiran media (gambar / audio / video), atau teks dalam 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...
}
}
Menurut Dokumentasi android.provider.Telephony :
Tindakan Siaran: Pesan SMS berbasis teks baru telah diterima oleh perangkat. Niat akan memiliki nilai tambahan berikut:
pdus
- SeorangObject[]
daribyte[]
s yang berisi PDU yang membentuk pesan.Nilai tambahan dapat diekstraksi menggunakan
getMessagesFromIntent(android.content.Intent)
Jika BroadcastReceiver menemukan kesalahan saat memproses maksud ini, ia harus mengatur kode hasil dengan tepat.@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
Tindakan Siaran: Pesan SMS berbasis data baru telah diterima oleh perangkat. Niat akan memiliki nilai tambahan berikut:
pdus
- SeorangObject[]
daribyte[]
s yang berisi PDU yang membentuk pesan.Nilai tambahan dapat diekstraksi menggunakan getMessagesFromIntent (android.content.Intent). Jika BroadcastReceiver menemukan kesalahan saat memproses maksud ini, ia harus menetapkan kode hasil dengan tepat.
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String DATA_SMS_RECEIVED_ACTION = "android.intent.action.DATA_SMS_RECEIVED";
Tindakan Siaran: Pesan WAP PUSH baru telah diterima oleh perangkat. Niat akan memiliki nilai tambahan berikut:
transactionId (Integer)
- ID transaksi WAP
pduType (Integer)
- Jenis WAP PDU`
header (byte[])
- Header pesan
data (byte[])
- Muatan data pesan
contentTypeParameters (HashMap<String,String>)
- Parameter apa pun yang terkait dengan tipe konten (diterjemahkan dari header Tipe Konten WSP)Jika BroadcastReceiver menemukan kesalahan saat memproses maksud ini, ia harus menetapkan kode hasil dengan tepat. Nilai tambahan contentTypeParameters adalah peta parameter konten yang dikunci dengan namanya. Jika ada parameter terkenal yang belum ditetapkan ditemukan, kunci peta akan 'unassigned / 0x ...', di mana '...' adalah nilai hex dari parameter yang belum ditetapkan. Jika suatu parameter tidak memiliki Nilai, nilai dalam peta akan menjadi nol.
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String WAP_PUSH_RECEIVED_ACTION = "android.provider.Telephony.WAP_PUSH_RECEIVED";
Perbarui # 2
Saya telah menemukan cara untuk mengirim tambahan dalam PendingIntent
untuk diterima oleh BroadcastReceiver
:
Android PendingIntent ekstra, tidak diterima oleh BroadcastReceiver
Namun, tambahan tersebut akan diteruskan ke SendBroadcastReceiver, bukan SMSReceiver . Bagaimana saya bisa memberikan tambahan ke SMSReceiver ?
Perbarui # 3
Menerima MMS
Jadi setelah melakukan penelitian lebih lanjut saya melihat beberapa saran untuk mendaftar a ContentObserver
. Dengan begitu Anda dapat mendeteksi ketika ada perubahan pada content://mms-sms/conversations
Penyedia Konten, akibatnya memungkinkan Anda untuk mendeteksi MMS yang masuk. Berikut adalah contoh terdekat untuk mendapatkan ini berfungsi yang saya temukan: Menerima MMS
Namun, ada variabel mainActivity
tipe ServiceController
. Di mana ServiceController
kelas diimplementasikan? Apakah ada implementasi lain yang terdaftar ContentObserver
?
Mengirim MMS
Sedangkan untuk mengirim MMS, saya telah menemukan contoh ini: Kirim MMS
Masalahnya adalah saya mencoba menjalankan kode ini pada Nexus 4 saya, yang ada di Android v4.2.2, dan saya menerima kesalahan ini:
java.lang.SecurityException: No permission to write APN settings: Neither user 10099 nor current process has android.permission.WRITE_APN_SETTINGS.
Kesalahan dilempar setelah meminta Carriers
ContentProvider dalam getMMSApns()
metode APNHelper
kelas.
final Cursor apnCursor = this.context.getContentResolver().query(Uri.withAppendedPath(Carriers.CONTENT_URI, "current"), null, null, null, null);
Tampaknya Anda tidak dapat membaca APN di Android 4.2
Apa alternatif untuk semua aplikasi yang menggunakan data seluler untuk melakukan operasi (seperti mengirim MMS) dan tidak tahu pengaturan APN default yang ada di perangkat?
Perbarui # 4
Mengirim MMS
Saya telah mencoba mengikuti contoh ini: Kirim MMS
Seperti yang disarankan @Sam dalam jawabannya:
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.
Jadi sekarang saya tidak lagi mendapatkan kesalahan SecurityException. Saya menguji sekarang pada Nexus 5 di Android KitKat. Setelah menjalankan kode sampel itu memberi saya kode respons 200 setelah panggilan ke
MMResponse mmResponse = sender.send(out, isProxySet, MMSProxy, MMSPort);
Namun, saya mengecek dengan orang yang saya coba kirimi MMS. Dan mereka mengatakan mereka tidak pernah menerima MMS.