SMS 메시지를 보내고받는 방법을 알아 냈습니다. SMS 메시지를 보내려면 클래스 의 sendTextMessage()
and sendMultipartTextMessage()
메소드 를 호출해야했습니다 SmsManager
. 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>
그러나 비슷한 방식으로 MMS 메시지를 보내고받을 수 있는지 궁금합니다. 몇 가지 조사를 수행 한 후 블로그에 제공된 많은 예제는 단순히 Intent
기본 메시징 응용 프로그램으로 전달 됩니다. 신청서를 남기지 않고 MMS를 보내려고합니다. MMS를 보내고받는 표준 방법은없는 것 같습니다. 누구든지 작동하도록 했습니까?
또한 SMS / MMS ContentProvider가 공식 Android SDK의 일부가 아니라는 것을 알고 있지만 누군가가 이것을 구현할 수 있다고 생각했습니다. 도움을 주시면 감사하겠습니다.
최신 정보
MMS 메시지를 받기 BroadcastReceiver
위해 AndroidManifest.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()
메소드는 메시지가 전송 된 phoneNumber 만 가져올 수 있습니다. 파일 경로와 미디어 첨부 파일 (이미지 / 오디오 / 비디오) 또는 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[]
메시지를 구성하는 PDU를 포함하는의.추가 값은 사용하여 추출 될 수
getMessagesFromIntent(android.content.Intent)
는 적절 결과 코드를 설정해야이 의도 된 브로드 캐스트의 처리 중에 오류가 발생하면.@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
브로드 캐스트 조치 : 장치가 새로운 데이터 기반 SMS 메시지를 수신했습니다. 의도에는 다음과 같은 추가 값이 있습니다.
pdus
-Object[]
의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 PUSH 메시지를 수신했습니다. 의도에는 다음과 같은 추가 값이 있습니다.
transactionId (Integer)
-WAP 거래 ID
pduType (Integer)
-WAP PDU 유형
header (byte[])
-메시지 헤더
data (byte[])
-메시지의 데이터 페이로드
contentTypeParameters (HashMap<String,String>)
-컨텐츠 유형과 연관된 모든 매개 변수 (WSP 컨텐츠 유형 헤더에서 디코딩 됨)이 의도를 처리하는 동안 BroadcastReceiver에 오류가 발생하면 결과 코드를 적절하게 설정해야합니다. contentTypeParameters 추가 값은 해당 이름으로 키가 지정된 컨텐츠 매개 변수의 맵입니다. 할당되지 않은 잘 알려진 매개 변수가 발견되면 맵의 키는 '지정되지 않은 / 0x ...'가됩니다. 여기서 '...'는 지정되지 않은 매개 변수의 16 진수 값입니다. 매개 변수에 No-Value가 있으면 맵의 값이 널입니다.
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String WAP_PUSH_RECEIVED_ACTION = "android.provider.Telephony.WAP_PUSH_RECEIVED";
업데이트 # 2
브로드 캐스트 리시버가 수신하지 않는 Android PendingIntent 엑스트라를PendingIntent
수신하여 추가로 전달하는 방법을 알아 냈습니다 BroadcastReceiver
.
그러나 여분이 전달됩니다 SendBroadcastReceiver 하지 SMSReceiver . SMSReceiver에 엑스트라를 전달하려면 어떻게 해야 합니까?
업데이트 # 3
MMS 받기
그래서 더 많은 연구를 한 후에 나는 등록에 대한 제안을 보았습니다 ContentObserver
. 이렇게하면 content://mms-sms/conversations
콘텐츠 공급자에 변경 사항이있을 때 이를 감지하여 들어오는 MMS를 감지 할 수 있습니다. 이것이 내가 찾은 가장 효과적인 예입니다. MMS 받기
그러나 mainActivity
유형 의 변수 가 ServiceController
있습니다. ServiceController
수업 은 어디에서 시행됩니까? 등록 된 다른 구현이 ContentObserver
있습니까?
MMS 전송
MMS 전송과 관련하여 다음 예제를 보았습니다 . 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);
분명히 Android 4.2에서 APN을 읽을 수 없습니다
모바일 데이터를 사용하여 MMS 전송과 같은 작업을 수행하고 장치에있는 기본 APN 설정을 모르는 모든 응용 프로그램의 대안은 무엇입니까?
업데이트 # 4
MMS 전송
이 예제를 따라 해 보았습니다. 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);
그러나 MMS를 보내려는 사람에게 확인했습니다. 그리고 그들은 MMS를받지 못했다고 말했습니다.