จะลบ SMS จากกล่องขาเข้าใน Android โดยทางโปรแกรมได้อย่างไร?


98

ในโทรศัพท์ Android ข้อความ SMS ที่ลงทะเบียนกับแอปพลิเคชันจะถูกส่งไปยังกล่องจดหมายของอุปกรณ์ด้วย อย่างไรก็ตามเพื่อป้องกันความยุ่งเหยิงมันเป็นการดีที่จะสามารถลบข้อความ SMS เฉพาะของแอปพลิเคชันออกจากกล่องจดหมายเพื่อลดปัญหาที่อาจเกิดขึ้นกับข้อความเหล่านั้น

คำถามเกี่ยวกับกลุ่ม Google อื่น ๆ เกี่ยวกับการรับคำตอบที่ชัดเจนเกี่ยวกับวิธีการแบบเป็นโปรแกรมในการลบข้อความ SMS จากกล่องจดหมายของ Android ดูเหมือนจะไม่เกิดขึ้น

ดังนั้นสถานการณ์:

  • การเริ่มต้นแอป Android
  • ลงทะเบียนข้อความ SMS ประเภท X, Y และ Z
  • ข้อความ P, Q, X, Y, Z จะสตรีมในช่วงเวลาหนึ่งซึ่งฝากไว้ในกล่องจดหมาย
  • แอปพลิเคชัน Android ตรวจพบการรับ X, Y, Z (น่าจะเป็นส่วนหนึ่งของเหตุการณ์ขัดจังหวะโปรแกรม)
  • กระบวนการ X, Y, Z
  • ความปรารถนา !!! X, Y, Z จะถูกลบออกจากกล่องจดหมายของ Android

ได้ดำเนินการหรือไม่ มันสามารถทำได้?


4
ฉันพบว่าการทำอะไรที่เป็นประโยชน์กับความสามารถของโทรศัพท์ Android เป็นประสบการณ์ที่ไม่พึงประสงค์
BobbyShaftoe

1
เพื่อนคำถามที่ดี ฉันกำลังมองหาสิ่งที่คล้ายกัน: D cheers
Harsha MV

3
วิธีที่ดีที่สุดคือการป้องกันไม่ให้ SMS เข้าถึงกล่องจดหมายตั้งแต่แรก: stackoverflow.com/questions/1741628/…
Christopher Orr

คำตอบ:


87

"สำหรับ Android 1.6 การส่งข้อความ SMS ขาเข้า ( android.provider.Telephony.SMS_RECEIVED) จะถูกส่งเป็น" การออกอากาศตามลำดับ "ซึ่งหมายความว่าคุณสามารถบอกระบบได้ว่าส่วนประกอบใดควรได้รับการออกอากาศก่อน"

ซึ่งหมายความว่าคุณสามารถสกัดกั้นข้อความขาเข้าและยกเลิกการแพร่ภาพต่อไปได้

ในAndroidManifest.xmlไฟล์ของคุณตรวจสอบให้แน่ใจว่าได้ตั้งลำดับความสำคัญไว้ที่สูงสุด:

<receiver android:name=".receiver.SMSReceiver" android:enabled="true">
    <intent-filter android:priority="1000">
        <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
</receiver>

ในของคุณBroadcastReceiverในonReceive()วิธีการก่อนที่จะทำการอะไรกับข้อความของคุณเพียงโทรabortBroadcast();

แก้ไข: สำหรับ KitKat ดูเหมือนจะใช้ไม่ได้อีกต่อไป

แก้ไข 2: ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีการใช้งาน KitKat ได้ที่นี่:

ลบ SMS จาก Android บน 4.4.4 (แถวที่ได้รับผลกระทบ = 0 (ศูนย์) หลังจากลบแล้ว)


3
และอย่าลืมดูstackoverflow.com/questions/1741628/…
Michael Levy

โปรดดูที่นี่stackoverflow.com/questions/25988574/… ?
Gangadhar Nimballi

คำตอบที่ดีที่สุดสำหรับสิ่งนี้ = D
Mike Brian Olivera

27

การใช้คำแนะนำจากผู้อื่นฉันคิดว่าฉันได้ผล:

(ใช้ SDK v1 R2)

มันไม่สมบูรณ์แบบเนื่องจากฉันจำเป็นต้องลบการสนทนาทั้งหมด แต่เพื่อจุดประสงค์ของเรามันเป็นการประนีประนอมที่เพียงพอเพราะอย่างน้อยเราก็รู้ว่าข้อความทั้งหมดจะได้รับการตรวจสอบและยืนยัน โฟลว์ของเราอาจจะต้องฟังข้อความจับข้อความที่เราต้องการทำแบบสอบถามเพื่อรับ thread_id ของข้อความขาเข้าล่าสุดและทำการโทร delete ()

ในกิจกรรมของเรา:

Uri uriSms = Uri.parse("content://sms/inbox");
Cursor c = getContentResolver().query(uriSms, null,null,null,null); 
int id = c.getInt(0);
int thread_id = c.getInt(1); //get the thread_id
getContentResolver().delete(Uri.parse("content://sms/conversations/" + thread_id),null,null);

หมายเหตุ: ฉันไม่สามารถลบเนื้อหา: // sms / inbox / หรือ content: // sms / all /

ดูเหมือนว่าเธรดจะมีความสำคัญเหนือกว่าซึ่งก็สมเหตุสมผล แต่ข้อความแสดงข้อผิดพลาดทำให้ฉันรู้สึกโกรธเท่านั้น เมื่อลองลบใน sms / inbox / หรือ sms / all / คุณอาจจะได้รับ:

java.lang.IllegalArgumentException: Unknown URL
    at com.android.providers.telephony.SmsProvider.delete(SmsProvider.java:510)
    at android.content.ContentProvider$Transport.delete(ContentProvider.java:149)
    at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:149)

สำหรับการอ้างอิงเพิ่มเติมอย่าลืมใส่สิ่งนี้ลงในรายการของคุณสำหรับผู้รับเจตนาของคุณ:

<receiver android:name=".intent.MySmsReceiver">
    <intent-filter>
        <action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
    </intent-filter>
</receiver>

โปรดทราบว่าแท็กเครื่องรับไม่มีลักษณะดังนี้:

<receiver android:name=".intent.MySmsReceiver" 
    android:permission="android.permission.RECEIVE_SMS">

เมื่อฉันมีการตั้งค่าเหล่านั้น android ให้การอนุญาตที่บ้าๆแก่ฉันซึ่งไม่อนุญาตให้ android.phone ส่ง SMS ที่ได้รับไปตามความตั้งใจของฉัน ดังนั้นอย่าใส่แอตทริบิวต์การอนุญาต RECEIVE_SMS นั้นไว้ในเจตนาของคุณ! หวังว่าจะมีคนที่ฉลาดกว่าฉันสามารถบอกฉันได้ว่าทำไมถึงเป็นเช่นนั้น


โปรดดูที่นี่stackoverflow.com/questions/25988574/… ?
Gangadhar Nimballi

24

ฉันได้เล่นและเป็นไปได้ที่จะลบ SMS ที่ได้รับ น่าเสียดายที่ไม่ใช่การเดินเรือธรรมดาทั้งหมด :(

ฉันมีเครื่องรับที่รับข้อความ SMS ที่เข้ามา ตอนนี้วิธีการกำหนดเส้นทางขาเข้าของ Android SMS ทำงานคือส่วนของรหัสที่รับผิดชอบในการถอดรหัสข้อความส่งการออกอากาศ (ใช้sendBroadcast()วิธีการซึ่งน่าเสียดายที่ไม่ใช่เวอร์ชันที่ให้คุณโทรได้ง่ายๆabortBroadcast()) เมื่อใดก็ตามที่มีข้อความมาถึง

ผู้รับของฉันอาจถูกเรียกก่อนเครื่องรับ SMS ของระบบหรือไม่ก็ได้และในกรณีใด ๆ การออกอากาศที่ได้รับไม่มีคุณสมบัติที่สามารถแสดง_idคอลัมน์ในตาราง SMS ได้

อย่างไรก็ตามไม่ใช่คนที่จะหยุดง่ายๆอย่างนั้นฉันโพสต์ข้อความล่าช้าด้วยตัวเอง (ผ่านทาง Handler) โดยมี SmsMessage เป็นวัตถุที่แนบมา (ฉันคิดว่าคุณสามารถโพสต์ Runnable ตัวเองได้เช่นกัน ... )

handler.sendMessageDelayed(handler.obtainMessage(MSG_DELETE_SMS, msg), 2500);

ความล่าช้าอยู่ที่นั่นเพื่อให้แน่ใจว่าเมื่อถึงเวลาที่ข้อความมาถึงเครื่องรับการถ่ายทอดสดทั้งหมดจะดำเนินการเสร็จสิ้นและข้อความจะถูกตรึงไว้อย่างปลอดภัยในตาราง SMS

เมื่อได้รับข้อความ (หรือ Runnable) นี่คือสิ่งที่ฉันทำ:

case MSG_DELETE_SMS:
    Uri deleteUri = Uri.parse("content://sms");
    SmsMessage msg = (SmsMessage)message.obj;

    getContentResolver().delete(deleteUri, "address=? and date=?", new String[] {msg.getOriginatingAddress(), String.valueOf(msg.getTimestampMillis())});

ฉันใช้ช่องที่อยู่ต้นทางและการประทับเวลาเพื่อให้แน่ใจว่ามีความเป็นไปได้สูงมากที่จะลบเฉพาะข้อความที่ฉันสนใจหากฉันต้องการหวาดระแวงมากขึ้นฉันสามารถรวมmsg.getMessageBody()เนื้อหาไว้เป็นส่วนหนึ่งของข้อความค้นหา

ใช่ข้อความถูกลบแล้ว (ไชโย!) ขออภัยที่แถบการแจ้งเตือนไม่ได้รับการอัปเดต :(

เมื่อคุณเปิดพื้นที่แจ้งเตือนคุณจะเห็นข้อความอยู่ตรงนั้นสำหรับคุณ ... แต่เมื่อคุณแตะที่เพื่อเปิด - มันหายไปแล้ว!

สำหรับฉันนี่ยังไม่ดีพอ - ฉันต้องการให้ร่องรอยของข้อความทั้งหมดหายไป - ฉันไม่ต้องการให้ผู้ใช้คิดว่ามี TXT เมื่อไม่มี (ซึ่งจะทำให้เกิดรายงานข้อบกพร่องเท่านั้น)

ภายในระบบปฏิบัติการโทรศัพท์เรียกMessagingNotification.updateNewMessageIndicator(Context)แต่ฉันซ่อนคลาสนั้นจาก API และฉันไม่ต้องการจำลองรหัสนั้นทั้งหมดเพียงเพื่อทำให้ตัวบ่งชี้ถูกต้อง


ดั๊กนี่สุดยอดมาก เป็นคำถามคุณรู้หรือไม่ว่าจำเป็นต้องโพสต์ไปยัง Handler หรือไม่? ฉันสงสัยว่ามีการแทรก SMS ลงในฐานข้อมูล SMS ของระบบก่อนและเรียกตัวรับสัญญาณออกอากาศหรือไม่? ฉันอาจจะต้องตรวจสอบระบบปฏิบัติการเพื่อดูว่าการแทรกเกิดขึ้นที่ใด แต่ฉันคิดว่าการแทรก SMS ลงในฐานข้อมูลบางส่วนเกิดขึ้นก่อนที่จะมีการแจ้งเครื่องรับการออกอากาศ มีข้อมูลเชิงลึกเกี่ยวกับสิ่งนี้หรือคุณเคยตรวจสอบแล้วหรือยัง?
Hamy

โปรดดูที่นี่stackoverflow.com/questions/25988574/… ?
Gangadhar Nimballi

11
public boolean deleteSms(String smsId) {
    boolean isSmsDeleted = false;
    try {
        mActivity.getContentResolver().delete(Uri.parse("content://sms/" + smsId), null, null);
        isSmsDeleted = true;

    } catch (Exception ex) {
        isSmsDeleted = false;
    }
    return isSmsDeleted;
}

ใช้การอนุญาตนี้ใน AndroidManifiest

<uses-permission android:name="android.permission.WRITE_SMS"/>

1
เราจะได้รับ sms id ได้อย่างไร?
Dev01


@ Dev01 หากคุณต้องการลบ sms ใดคุณต้องมี id ใช่ไหม และถ้าไม่มีคุณต้องสอบถาม id ด้วยที่อยู่หรือ smsbody
Dr. aNdRO

6

ควรใช้ _id และ thread_id เพื่อลบข้อความ

Thread_id คือสิ่งที่กำหนดให้กับข้อความที่มาจากผู้ใช้คนเดียวกัน ดังนั้นหากคุณใช้เฉพาะ thread_id ข้อความทั้งหมดจากผู้ส่งจะถูกลบ

หากคุณใช้การรวมกันของ _id, thread_id มันจะลบข้อความที่คุณต้องการลบ

Uri thread = Uri.parse( "content://sms");
int deleted = contentResolver.delete( thread, "thread_id=? and _id=?", new String[]{String.valueOf(thread_id), String.valueOf(id)} );

โปรดดูที่นี่stackoverflow.com/questions/25988574/… ?
Gangadhar Nimballi

5

คุณจะต้องค้นหาURIของข้อความ แต่เมื่อคุณคิดว่าคุณควรจะสามารถ android.content.ContentResolver.delete (... ) ได้

นี่คือบางส่วนเพิ่มเติมข้อมูล


2

ฉันคิดว่าสิ่งนี้ไม่สามารถทำได้อย่างสมบูรณ์แบบในขณะนี้ มี 2 ​​ปัญหาพื้นฐาน:

  1. คุณจะแน่ใจได้อย่างไรว่ามี sms อยู่ในกล่องจดหมายแล้วเมื่อพยายามลบ
    โปรดสังเกตว่า SMS_RECEIVED ไม่ใช่การออกอากาศตามสั่ง
    วิธีแก้ปัญหาของ dmyung ก็คือการลองเสี่ยงโชค แม้แต่ความล่าช้าในคำตอบของ Doug ก็ไม่สามารถรับประกันได้

  2. SmsProvider ไม่ปลอดภัยต่อเธรด (ดูที่http://code.google.com/p/android/issues/detail?id=2916#c0 )
    ความจริงที่ว่าลูกค้ามากกว่าหนึ่งรายกำลังขอให้ลบและแทรกลงใน ในเวลาเดียวกันจะทำให้ข้อมูลเสียหายหรือแม้แต่ Runtime Exception ในทันที


2

ฉันไม่สามารถใช้งานได้โดยใช้โซลูชันของ dmyung มันทำให้ฉันมีข้อยกเว้นเมื่อได้รับรหัสข้อความหรือรหัสเธรด

ในท้ายที่สุดฉันใช้วิธีต่อไปนี้เพื่อรับรหัสเธรด:

private long getThreadId(Context context) {
    long threadId = 0;

    String SMS_READ_COLUMN = "read";
    String WHERE_CONDITION = SMS_READ_COLUMN + " = 0";
    String SORT_ORDER = "date DESC";
    int count = 0;

    Cursor cursor = context.getContentResolver().query(
                    SMS_INBOX_CONTENT_URI,
          new String[] { "_id", "thread_id", "address", "person", "date", "body" },
                    WHERE_CONDITION,
                    null,
                    SORT_ORDER);

    if (cursor != null) {
            try {
                count = cursor.getCount();
                if (count > 0) {
                    cursor.moveToFirst();
                    threadId = cursor.getLong(1);                              
                }
            } finally {
                    cursor.close();
            }
    }


    return threadId;
}

จากนั้นฉันสามารถลบมันได้ อย่างไรก็ตามดังที่ Doug กล่าวการแจ้งเตือนยังคงอยู่ที่นั่นแม้ข้อความจะปรากฏขึ้นเมื่อเปิดแผงการแจ้งเตือน เมื่อแตะข้อความเท่านั้นที่ฉันเห็นว่าว่างเปล่า

ดังนั้นฉันเดาว่าวิธีเดียวที่จะได้ผลคือการดักฟัง SMS ก่อนที่จะส่งไปยังระบบก่อนที่มันจะไปถึงกล่องจดหมาย อย่างไรก็ตามฉันสงสัยอย่างมากว่าสิ่งนี้ทำได้ กรุณาแก้ไขฉันถ้าฉันผิด


ดีที่คุณมีความผิดเกี่ยวกับ intercepting ข้อความก่อนที่กล่องจดหมาย: คุณสามารถได้รับการออกอากาศ android.provider.Telephony.SMS_RECEIVED คุณต้องการเพียง android.permission.RECEIVE_SMS permssion คุณสามารถหยุดข้อความไม่ให้เข้าถึงกล่องจดหมายได้อย่างง่ายดายโดยโทรไปที่ abortBroadcast () เนื่องจากเป็นการออกอากาศตามคำสั่ง ปล. ต้องตลกถึงจะแก้ไขได้ในอีก 2 ปีข้างหน้า :)
lapis

2

ใช้ฟังก์ชันนี้เพื่อลบเธรดข้อความเฉพาะหรือแก้ไขตามความต้องการของคุณ:

public void delete_thread(String thread) 
{ 
  Cursor c = getApplicationContext().getContentResolver().query(
  Uri.parse("content://sms/"),new String[] { 
  "_id", "thread_id", "address", "person", "date","body" }, null, null, null);

 try {
  while (c.moveToNext()) 
      {
    int id = c.getInt(0);
    String address = c.getString(2);
    if (address.equals(thread)) 
        {
     getApplicationContext().getContentResolver().delete(
     Uri.parse("content://sms/" + id), null, null);
    }

       }
} catch (Exception e) {

  }
}

เรียกใช้ฟังก์ชันนี้ด้านล่าง:

delete_thread("54263726");//you can pass any number or thread id here

อย่าลืมเพิ่มสิทธิ์ Android mainfest ด้านล่าง:

<uses-permission android:name="android.permission.WRITE_SMS"/>

1

เพียงปิดการแจ้งเตือนสำหรับแอป sms เริ่มต้น ประมวลผลการแจ้งเตือนของคุณเองสำหรับข้อความทั้งหมด!


1

เพียงแค่ดูที่ลิงค์นี้มันจะให้แนวคิดสั้น ๆ เกี่ยวกับตรรกะ:

https://gist.github.com/5178e798d9a00cac4ddb
เพียงแค่เรียกใช้ฟังก์ชัน deleteSMS () โดยมีความล่าช้าเนื่องจากมีความแตกต่างเล็กน้อยระหว่างเวลา ของการแจ้งเตือนและเวลาบันทึกจริง .... ดูรายละเอียดได้ที่ลิงค์นี้ด้วย ..........

http://htmlcoderhelper.com/how-to-delete-sms-from- inbox-in-android-programmatically /

ขอบคุณ ..........


1

คุณเพียงแค่ลองใช้รหัสต่อไปนี้จะลบ sms ทั้งหมดที่อยู่ในโทรศัพท์ (รับหรือส่ง)

Uri uri = Uri.parse("content://sms");

ContentResolver contentResolver = getContentResolver();

Cursor cursor = contentResolver.query(uri, null, null, null,
  null);



while (cursor.moveToNext()) {

 long thread_id = cursor.getLong(1);
 Uri thread = Uri.parse("content://sms/conversations/"
   + thread_id);
 getContentResolver().delete(thread, null, null);
}

1

อัปเดตไฟล์รายการเพื่อลบ sms ที่คุณต้องการสิทธิ์ในการเขียน

<uses-permission android:name="android.permission.WRITE_SMS"/>


0

ตัวอย่างการลบ SMS หนึ่งรายการไม่ใช่การสนทนา:

getContentResolver().delete(Uri.parse("content://sms/conversations/" + threadID), "_id = ?", new String[]{id});

0
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    SMSData sms = (SMSData) getListAdapter().getItem(position);
    Toast.makeText(getApplicationContext(), sms.getBody(),
            Toast.LENGTH_LONG).show();
    Toast.makeText(getApplicationContext(), sms.getNumber(),
            Toast.LENGTH_LONG).show();

    deleteSms(sms.getId());

}

public boolean deleteSms(String smsId) {
    boolean isSmsDeleted = false;
    try {
        MainActivity.this.getContentResolver().delete(
                Uri.parse("content://sms/" + smsId), null, null);
        isSmsDeleted = true;

    } catch (Exception ex) {
        isSmsDeleted = false;
    }
    return isSmsDeleted;
}

0

ลองสิ่งนี้ฉันมั่นใจ 100% ว่าจะใช้งานได้ดี: - // ใส่ที่อยู่การแปลงที่นี่เพื่อลบการแปลงทั้งหมดตามที่อยู่ (อย่าลืมเพิ่มสิทธิ์การอ่านเขียนใน mainfest) นี่คือรหัส:

String address="put address only";

Cursor c = getApplicationContext().getContentResolver().query(Uri.parse("content://sms/"), new String[] { "_id", "thread_id", "address", "person", "date", "body" }, null, null, null);

try {
    while (c.moveToNext()) {
        int id = c.getInt(0);
        String address = c.getString(2);
        if(address.equals(address)){
        getApplicationContext().getContentResolver().delete(Uri.parse("content://sms/" + id), null, null);}
    }
} catch(Exception e) {

}

0

ใช้หนึ่งในวิธีนี้เพื่อเลือก SMS ที่ได้รับล่าสุดและลบทิ้งในกรณีนี้ฉันได้รับ sms มากที่สุดและกำลังจะลบโดยใช้เธรดและค่ารหัสของ sms

try {
    Uri uri = Uri.parse("content://sms/inbox");
    Cursor c = v.getContext().getContentResolver().query(uri, null, null, null, null);
    int i = c.getCount();

    if (c.moveToFirst()) {
    }
} catch (CursorIndexOutOfBoundsException ee) {
    Toast.makeText(v.getContext(), "Error :" + ee.getMessage(), Toast.LENGTH_LONG).show();
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.