我正在寻找一种方法来挂钩SMSManager或更低级别的机制,这样我就可以在发送之前截取,读取和取消任何外发短信。
答案 0 :(得分:11)
显然,这不是您想要听到的内容,但Android并非旨在允许第三方应用程序相互干扰或超越用户的自由选择。
它没有为基本功能的硬拦截提供“钩子”类型的机制,缺少修改安装在设备上的Android本身的构建。
设备管理员界面不包含任何用于调节短信的内容。
是的,偶尔人们会利用各种“黑客”方法制作产品,以在某种程度上完成这些事情,但是它们与平台的设计相悖,因此当各种“错误修复”类型改进时,它们不可靠或可能会破坏制作到android。或者它们的范围有限,例如更换主屏幕,从而限制易于启动的内容 - 但只要主屏幕应用程序保持选中状态,并且无法管理其他意图来源。
你可能会发现一个足够吸引人的想法,你决定与它一起运行,但请记住,除非它是未来的API介绍打算做这种事情,你很可能会利用平台设计的监督,很可能很快就会得到纠正。
答案 1 :(得分:11)
晚了好,从来没有:)
我花了2天时间......并且不想让任何其他人浪费时间:)
public class SMS {
public Date date;
public String from;
public String message;
public String to;
public SMS(String paramString1, String paramString2, String paramString3,Date paramDate) {
this.from = paramString1;
this.to = paramString2;
this.message = paramString3;
this.date = paramDate;
}
}
public class ServiceClass extends Service implements SMSListener {
public static boolean sendSms = true;
private final IBinder mBinder = new LocalBinder();
public static MyContentObserver mSMSObserver;
private Context ctx;
public static SMS param_SMS;
int myID = -1;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
myID = startId;
sendSms = true;
Context localContext = getApplicationContext();
ctx = localContext;
mSMSObserver = new MyContentObserver(null);
mSMSObserver.setSMSListener(this);
mSMSObserver.start(localContext);
return Service.START_STICKY;
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
SharedPreferences prefs = getApplicationContext().getSharedPreferences(
"appData", 0);
if (prefs.getBoolean(CommonStrings.KEY_PREFS_TOGGLE, false)) {
super.onDestroy();
Log.e("OnDestroy", "Stopping Service");
Context localContext = getApplicationContext();
mSMSObserver.stop(localContext);
try {
stopSelf(myID);
Log.e("Stopping self", "Stopping Service");
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.e("OnBinder", "OnBinder");
return null;
}
@Override
public void reportIncomingSms(SMS paramSMS) {
// TODO Auto-generated method stub
}
public void reportOutgoingSms(SMS paramSMS) {
if (!MainActivity.stopped) {
Log.e("OUT GOING SMS DETECTED", "OUT GOING SMS DETECTED");
sendSms = true;
param_SMS = paramSMS;
// DO ANY THING, Out going Msg detected...
}
}
public class LocalBinder extends Binder {
public LocalBinder() {
}
public ServiceClass getService() {
return ServiceClass.this;
}
}
}
扩展内容观察器
public class MyContentObserver extends ContentObserver {
public static final int MESSAGE_TYPE_ALL = 0;
public static final int MESSAGE_TYPE_DRAFT = 3;
public static final int MESSAGE_TYPE_FAILED = 5;
public static final int MESSAGE_TYPE_INBOX = 1;
public static final int MESSAGE_TYPE_OUTBOX = 4;
public static final int MESSAGE_TYPE_QUEUED = 6;
public static final int MESSAGE_TYPE_SENT = 2;
public static final String TYPE = "type";
private SMSListener mSMSListener;
public static long _id;
private ContentObserver observer;
public MyContentObserver(Handler handler) {
super(handler);
// TODO Auto-generated constructor stub
}
private void readFromOutgoingSMS(Context paramContext) {
if (!MainActivity.stopped) {
Cursor localCursor = paramContext.getContentResolver().query(
Uri.parse("content://sms"), null, null, null, null);
long l = 0;
int i;
if (localCursor.moveToNext()) {
l = localCursor.getLong(localCursor.getColumnIndex("_id"));
String str1 = localCursor.getString(localCursor
.getColumnIndex("protocol"));
i = localCursor.getInt(localCursor.getColumnIndex("type"));
if ((str1 != null) || (i != 6))
localCursor.close();
if (i == 6) {
int j = localCursor.getColumnIndex("body");
int k = localCursor.getColumnIndex("address");
Date localDate = new Date(localCursor.getLong(localCursor
.getColumnIndex("date")));
String str2 = localCursor.getString(k);
String str3 = localCursor.getString(j);
localCursor.close();
_id = l;
// Delete SMS and Save the sms content to custom type variable
if (deleteSms(paramContext, l)) {
SMS localSMS = new SMS("", str2, str3, localDate);
this.mSMSListener.reportOutgoingSms(localSMS);
} else {
localCursor.close();
}
}
}
}
}
public static boolean deleteSms(Context paramContext, long paramLong) {
Uri localUri = ContentUris.withAppendedId(Uri.parse("content://sms"),
paramLong);
boolean bool = false;
if (localUri != null) {
try {
int j = paramContext.getContentResolver().delete(localUri,
null, null);
if (j == 1)
bool = true;
else
bool = false;
} catch (Exception localException) {
localException.printStackTrace();
bool = false;
}
}
return bool;
}
private void registerContentObserver(final Context paramContext) {
this.observer = new ContentObserver(null) {
public void onChange(boolean paramAnonymousBoolean) {
readFromOutgoingSMS(paramContext);
}
};
paramContext.getContentResolver().registerContentObserver(
Uri.parse("content://sms"), true, this.observer);
}
public void setSMSListener(SMSListener paramSMSListener) {
this.mSMSListener = paramSMSListener;
}
public void start(Context paramContext) {
registerContentObserver(paramContext);
listenForIncomingSms(paramContext);
}
public void stop(Context paramContext) {
paramContext.getContentResolver().unregisterContentObserver(
this.observer);
}
private void listenForIncomingSms(Context paramContext) {
//.....
}
}
SMS LIstener
public abstract interface SMSListener {
public abstract void reportIncomingSms(SMS paramSMS);
public abstract void reportOutgoingSms(SMS paramSMS);
}
需要的权限:
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
答案 2 :(得分:3)
妥协怎么办?为什么不创建一个应用程序来写短信?用户可以选择它作为写短信的默认应用程序,这样它就不会一直打扰它们。我相信这是接近您的目标的唯一方法,而无需生根/提供您自己的Android版本。