SMSマネージャを使用してSMSを送信します。シングルSIMの場合、SMSを送信するには完全に機能しますが、デュアルSIMでは、SMSは送信されません。デュアルSIMからSMS)を送信することは、可能な場合、SMSを送信するSIMを選択する方法を意味します。
単一のSIM作業コード
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(ph_number, null, body, null,null);
この方法を使用して、SMSさらに長いメッセージを送信するために使用するsimを管理します。私のデュアルsim電話Lenovo A319(4.4.3)で動作し、rootは不要です。反射。
import Android.app.PendingIntent;
import Android.content.Context;
import Android.os.Build;
import Android.os.IBinder;
import Android.util.Log;
import Java.lang.reflect.InvocationTargetException;
import Java.lang.reflect.Method;
import Java.util.ArrayList;
import Java.util.List;
/**
* Created by Apipas on 6/4/15.
*/
public class SimUtil {
public static boolean sendSMS(Context ctx, int simID, String toNum, String centerNum, String smsText, PendingIntent sentIntent, PendingIntent deliveryIntent) {
String name;
try {
if (simID == 0) {
name = "isms";
// for model : "Philips T939" name = "isms0"
} else if (simID == 1) {
name = "isms2";
} else {
throw new Exception("can not get service which for sim '" + simID + "', only 0,1 accepted as values");
}
Method method = Class.forName("Android.os.ServiceManager").getDeclaredMethod("getService", String.class);
method.setAccessible(true);
Object param = method.invoke(null, name);
method = Class.forName("com.Android.internal.telephony.ISms$Stub").getDeclaredMethod("asInterface", IBinder.class);
method.setAccessible(true);
Object stubObj = method.invoke(null, param);
if (Build.VERSION.SDK_INT < 18) {
method = stubObj.getClass().getMethod("sendText", String.class, String.class, String.class, PendingIntent.class, PendingIntent.class);
method.invoke(stubObj, toNum, centerNum, smsText, sentIntent, deliveryIntent);
} else {
method = stubObj.getClass().getMethod("sendText", String.class, String.class, String.class, String.class, PendingIntent.class, PendingIntent.class);
method.invoke(stubObj, ctx.getPackageName(), toNum, centerNum, smsText, sentIntent, deliveryIntent);
}
return true;
} catch (ClassNotFoundException e) {
Log.e("apipas", "ClassNotFoundException:" + e.getMessage());
} catch (NoSuchMethodException e) {
Log.e("apipas", "NoSuchMethodException:" + e.getMessage());
} catch (InvocationTargetException e) {
Log.e("apipas", "InvocationTargetException:" + e.getMessage());
} catch (IllegalAccessException e) {
Log.e("apipas", "IllegalAccessException:" + e.getMessage());
} catch (Exception e) {
Log.e("apipas", "Exception:" + e.getMessage());
}
return false;
}
public static boolean sendMultipartTextSMS(Context ctx, int simID, String toNum, String centerNum, ArrayList<String> smsTextlist, ArrayList<PendingIntent> sentIntentList, ArrayList<PendingIntent> deliveryIntentList) {
String name;
try {
if (simID == 0) {
name = "isms";
// for model : "Philips T939" name = "isms0"
} else if (simID == 1) {
name = "isms2";
} else {
throw new Exception("can not get service which for sim '" + simID + "', only 0,1 accepted as values");
}
Method method = Class.forName("Android.os.ServiceManager").getDeclaredMethod("getService", String.class);
method.setAccessible(true);
Object param = method.invoke(null, name);
method = Class.forName("com.Android.internal.telephony.ISms$Stub").getDeclaredMethod("asInterface", IBinder.class);
method.setAccessible(true);
Object stubObj = method.invoke(null, param);
if (Build.VERSION.SDK_INT < 18) {
method = stubObj.getClass().getMethod("sendMultipartText", String.class, String.class, List.class, List.class, List.class);
method.invoke(stubObj, toNum, centerNum, smsTextlist, sentIntentList, deliveryIntentList);
} else {
method = stubObj.getClass().getMethod("sendMultipartText", String.class, String.class, String.class, List.class, List.class, List.class);
method.invoke(stubObj, ctx.getPackageName(), toNum, centerNum, smsTextlist, sentIntentList, deliveryIntentList);
}
return true;
} catch (ClassNotFoundException e) {
Log.e("apipas", "ClassNotFoundException:" + e.getMessage());
} catch (NoSuchMethodException e) {
Log.e("apipas", "NoSuchMethodException:" + e.getMessage());
} catch (InvocationTargetException e) {
Log.e("apipas", "InvocationTargetException:" + e.getMessage());
} catch (IllegalAccessException e) {
Log.e("apipas", "IllegalAccessException:" + e.getMessage());
} catch (Exception e) {
Log.e("apipas", "Exception:" + e.getMessage());
}
return false;
}
}
許可を追加:
<uses-permission Android:name="Android.permission.SEND_SMS"/>
次に、このような(血なまぐさい)静的メソッドを呼び出します
SIM1を使用するには:
SimUtil.sendSMS(this,0,"00970XXXXXXXXX",null,"Hi Stackoverflow! its me Maher. Sent by sim1",null,null);
SIM2を使用するには:
SimUtil.sendSMS(this,1,"00970XXXXXXXXX",null,"Hi Stackoverflow! its me Maher. Sent by sim2",null,null);
しかし、待ってください...メッセージが160文字よりも長い場合は機能しません..より良い方法:
String textSMS;
//short <160
// textSMS = "Hi Stackoverflow! its me Maher.";
//long >160
textSMS = "Hi Jerusalem, hi Cairo, Hi Prague, hi Baghdad, hi Riyadh, hi Jeddah, hi Dammam, hi Aleppo, hi Casablanca, hi Damascus, hi Alexandria, hi Algiers, hi Mosul, hi Basra, hi Arabia, hi Tripoli, hi Amman, hi Kuwait, hi Beirut, hi Abu Dhabi";
int simID = 0;//0:sim_1, 1:sim_2
ArrayList<String> messageList = SmsManager.getDefault().divideMessage(textSMS);
if (messageList.size() > 1) {
SimUtil.sendMultipartTextSMS(this, simID, "00972XXXXXXXXX", null, messageList, null, null);
} else {
SimUtil.sendSMS(this, simID, "00972XXXXXXXXX", null, textSMS, null, null);
}
そのため、長さを気にせずにメッセージ本文を安全に渡すことができます。
------------ 2016年9月10日更新----------
MultipartMessageでPendingIntent/DeliveryIntentを使用するには、同じコンテンツでArrayListを作成し、それを渡すだけです。 PendingIntentのリストを作成する実装を次に示します。
final static String sSMSManagerIntentSENT = "package.DeliveryReport.SMS_SENT";
int numParts = parts.size();
ArrayList<PendingIntent> pendingIntents = new ArrayList<PendingIntent>();
for (int i = 0; i < numParts; i++) {
Intent pendingIntent = new Intent(sSMSManagerIntentSENT);
//optional if you want to keep info about what action has been done for feedback or analysis later when message is sent
pendingIntent.putExtra("package.DeliveryReport.phoneNumber", phoneNo); // receiver phoneNo
pendingIntent.putExtra("package.DeliveryReport.textSMS", msg);// msg body
pendingIntent.putExtra("SIM", simID); // which sim is sending this message
pendingIntents.add(PendingIntent.getBroadcast(getActivity(), 0, pendingIntent,PendingIntent.FLAG_ONE_SHOT));
}
配信するには、同じアプローチを使用します。
------------------追加------------------
私はAndroid 22がAndroid 5.1からのマルチSIMカードをサポートしており、ここにそれを使用する方法があります..残念ながら、私はそのバージョンのデバイスを持っていませんテストのため、フィードバックをお待ちください:
SmsManager.getSmsManagerForSubscriptionId(int subscriptionId).sendTextMessage(String destinationAddress, String scAddress, String text,PendingIntent sentIntent, PendingIntent deliveryIntent);
SubscriptionIdを取得する方法は? SIMカードに属するすべての利用可能なsubscriptionIDを確認するには:
SubscriptionManager subscriptionManager = SubscriptionManager.from(getApplicationContext());
List<SubscriptionInfo> subscriptionInfoList = subscriptionManager.getActiveSubscriptionInfoList();
for (SubscriptionInfo subscriptionInfo : subscriptionInfoList) {
int subscriptionId = subscriptionInfo.getSubscriptionId();
Log.d("apipas","subscriptionId:"+subscriptionId);
}
**このコードは5.1で動作していることに注意してください。古いバージョンで実行しようとすると、メソッドが存在しないという例外が発生します。
------------ UPDATE 19.8.2015 ----------
SIMに関する情報は、テーブルsiminfoのDB:telephony.db(デフォルトでは/data/data/com.Android.providers.telephony/databases/telephony.db)にあります。実際のデバイス上のDBの表siminfoのスクリーンショットを参照してください。
幸いなことに、そのためのコンテンツプロバイダーがあります。
"content://telephony/siminfo/"
したがって、基本的にはそのテーブルからデータを照会するだけです。スロット0はSIM1を表し、1はSIM2を表し、スロット-1は古い/削除された/交換されたSIMであることに注意してください。
これはLenovo A319に適用されます。他のデバイスでも動作する可能性があります。私が使用するutilメソッドは次のとおりです。
public static List<SimInfo> getSIMInfo(Context context) {
List<SimInfo> simInfoList = new ArrayList<>();
Uri URI_TELEPHONY = Uri.parse("content://telephony/siminfo/");
Cursor c = context.getContentResolver().query(URI_TELEPHONY, null, null, null, null);
if (c.moveToFirst()) {
do {
int id = c.getInt(c.getColumnIndex("_id"));
int slot = c.getInt(c.getColumnIndex("slot"));
String display_name = c.getString(c.getColumnIndex("display_name"));
String icc_id = c.getString(c.getColumnIndex("icc_id"));
SimInfo simInfo = new SimInfo(id, display_name, icc_id, slot);
Log.d("apipas_sim_info", simInfo.toString());
simInfoList.add(simInfo);
} while (c.moveToNext());
}
c.close();
return simInfoList;
}
エンティティクラスSimInfoは次のとおりです。
public class SimInfo {
private int id_;
private String display_name;
private String icc_id;
private int slot;
public SimInfo(int id_, String display_name, String icc_id, int slot) {
this.id_ = id_;
this.display_name = display_name;
this.icc_id = icc_id;
this.slot = slot;
}
public int getId_() {
return id_;
}
public String getDisplay_name() {
return display_name;
}
public String getIcc_id() {
return icc_id;
}
public int getSlot() {
return slot;
}
@Override
public String toString() {
return "SimInfo{" +
"id_=" + id_ +
", display_name='" + display_name + '\'' +
", icc_id='" + icc_id + '\'' +
", slot=" + slot +
'}';
}
}
がんばろう、'。
Maherのリフレクションベースのソリューションはエミュレータで動作しますAndroid SDK 10、17、18、19、20、21前述のSubscriptionIdベースのソリューションはSDK 22で動作し、Micromax Canvas 4(Android 4.2)でも動作します。
ただし、Lenevoなどの一部の携帯電話ブランド、Android 5.0ではAsusブランドでは、
Java.lang.NullPointerException:コードで仮想メソッド 'Java.lang.Class Java.Lang.Object.GetClass()'をnullオブジェクト参照で呼び出そうとする
"method = stubObj.getClass()。getMethod(" sendText "、String.class、String.class、String.class、String.class、PendingIntent.class、PendingIntent.class);
これは、適切なstubObj
を取得できないことを意味します。
デュアルsimでsmsを送信するMahers Refletionメソッドを試しましたAndroid phone(API 19以下)。スマートフォンのチップセットはSpreadtrum。Maherのコードで例外が発生しましたが、最初は名前= isms2のNull Pointer例外でした。次のコードをさらに検索するとうまくいきました:
public class SimUtil {
public static boolean sendSMS(Context ctx, int simID, String toNum, String centerNum, String smsText, PendingIntent sentIntent, PendingIntent deliveryIntent) {
String name;
try {
if (simID == 0) {
name = "isms0";
} else if (simID == 1) {
name = "isms1";
} else {
throw new Exception("can not get service which for sim '" + simID + "', only 0,1 accepted as values");
}
try
{
Method method = Class.forName("Android.os.ServiceManager").getDeclaredMethod("getService", new Class[]{String.class});
method.setAccessible(true);
Object param = method.invoke(null, new Object[]{name});
if (param == null)
{
throw new RuntimeException("can not get service which is named '" + name + "'");
}
method = Class.forName("com.Android.internal.telephony.ISms$Stub").getDeclaredMethod("asInterface", new Class[]{IBinder.class});
method.setAccessible(true);
Object stubObj = method.invoke(null, new Object[]{param});
method = stubObj.getClass().getMethod("sendText", String.class, String.class, String.class, String.class, PendingIntent.class, PendingIntent.class);
method.invoke(stubObj, ctx.getPackageName(), toNum, centerNum, smsText, sentIntent, deliveryIntent);
} catch (ClassNotFoundException e)
{
throw new RuntimeException(e);
} catch (NoSuchMethodException e)
{
throw new RuntimeException(e);
} catch (InvocationTargetException e)
{
throw new RuntimeException(e);
} catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
return true;
} catch (ClassNotFoundException e) {
Log.e("Exception", "ClassNotFoundException:" + e.getMessage());
} catch (NoSuchMethodException e) {
Log.e("Exception", "NoSuchMethodException:" + e.getMessage());
} catch (InvocationTargetException e) {
Log.e("Exception", "InvocationTargetException:" + e.getMessage());
} catch (IllegalAccessException e) {
Log.e("Exception", "IllegalAccessException:" + e.getMessage());
} catch (Exception e) {
Log.e("Exception", "Exception:" + e);
}
return false;
}
}
次のリンクは役に立つかもしれません:
Maherのソリューションはほぼ正しいです。
Motorola motog 5.1 Android(single sim)で試してみましたが、読み取りテーブルcontent://telephony/siminfo
わずかなバグが1つありました。
私のモトローラでは、フィールドslot
がありませんでしたが、sim_id
これの残りは大丈夫で同一でした。
@Vibhavソリューションに関して、ここに私がそれをうまく実装する方法があります
method = Class.forName("Android.telephony.SubscriptionManager").getDeclaredMethod("getSubId", int.class);
method.setAccessible(true);
int simID = 1; //while simID is the slot number of your second simCard
param = (int[]) method.invoke(null, new Integer(simID));
int inst = param[0];
smsMan = SmsManager.getSmsManagerForSubscriptionId(inst);
smsMan.sendTextMessage(toNum, null, smsText, null, null);
このソリューションは私と一緒にうまく機能しましたが、ここにあるこのはるかにクリーンなソリューション(リフレクションは不要、APIレベル22+で動作します)を強くお勧めします https:/ /stackoverflow.com/a/51380282/342788(