SMSメッセージの送受信方法を理解しました。SMSメッセージを送信するには、クラスのsendTextMessage()
および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()
メソッドはメッセージの送信元の電話番号のみを取得できます。メディア添付ファイル(画像/音声/ビデオ)へのファイルパスや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)
、BroadcastReceiverがこのインテントの処理中にエラーを検出した場合に、結果コードを適切に設定することで抽出できます。@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 Content-Typeヘッダーからデコード)BroadcastReceiverがこのインテントの処理中にエラーを検出した場合、結果コードを適切に設定する必要があります。contentTypeParametersの追加の値は、名前でキー付けされたコンテンツパラメータのマップです。未割り当ての既知のパラメーターが検出された場合、マップのキーは「unassigned / 0x ...」になります。「...」は未割り当てのパラメーターの16進値です。パラメータにNo-Valueがある場合、マップの値は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のエキストラは、BroadcastReceiverによって受信されません
しかし、余分はに渡されるSendBroadcastReceiverないSMSReceiver。SMSReceiverにエクストラを渡すにはどうすればよいですか?
アップデート#3
MMSの受信
したがって、さらに調査を行った後、の登録に関するいくつかの提案を見ましたContentObserver
。これにより、content://mms-sms/conversations
コンテンツプロバイダーに変更があったことを検出できるため、着信MMSを検出できます。これが私が見つけたこれを機能させる最も近い例です:MMSの受信
ただし、mainActivity
タイプの変数がありますServiceController
。ServiceController
クラスはどこに実装されていますか?登録済みの他の実装はありますContentObserver
か?
MMSの送信
MMSの送信に関しては、次の例に遭遇しました。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
ContentProviderをクエリした後にスローされます。getMMSApns()
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の送信
私はこの例に従ってみました:MMSを送信します
@サムが彼の答えで示唆したように:
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を決して受け取っていないと述べた。