Android 上的 0 类 SMS(Flash SMS)

发布于 2025-01-01 13:34:41 字数 367 浏览 2 评论 0原文

据我所知,诺基亚和其他一些手机(如 iPhone)能够发送和接收 0 类短信,Android 是否可以?安卓有API吗?

什么是闪现短信?

Flash SMS 是一种到达后立即显示在手机屏幕上的短信。

除非您选择保存即显消息,否则它会在离开时消失,并且不会保存在您的收件箱中。

如果向一部手机发送多条闪信,则仅显示最新的一条短信,之前的短信将被覆盖。

Class 0:表示该消息将立即显示在MS上,并将消息传递报告发送回SC。该消息不必保存在 MS 或 SIM 卡中(除非移动用户选择这样做)。

As I know that Nokia and some others phone (like iPhone) are able to sent and receive class 0 SMS , is it possible for android ? Do Android have the API?

What is flash SMS?

Flash SMS is an SMS which is displayed on the phone screen immediately upon arrival.

Unless you choose to save the flash message, it will disappear upon navigating away and will not be saved in your inbox.

If several flash messages are sent to one phone, only the latest message will be displayed, and all the previous ones will be overwritten.

Class 0: Indicates that this message is to be displayed on the MS immediately and a message delivery report is to be sent back to the SC. The message does not have to be saved in the MS or on the SIM card (unless selected to do so by the mobile user).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我纯我任性 2025-01-08 13:34:41

对于获得 root 权限的 Android,可以绕过 API 并发送 0 类 SMS。 Git Hub 上有一个名为 ZeroSMS 的项目:

ZeroSMS 是一个概念验证,演示了在 Android >=2.3 上发送 0 类 SMS 的方法。

注意:这仅适用于版本 2.2 -> 4.1.2 中,sendRawPdu 方法已被删除,因此您需要找到一种新方法来执行此操作。

For rooted Android it is possible to bypass an API and send Class 0 SMS. There is a project on Git Hub called ZeroSMS:

ZeroSMS is a proof-of-concept demonstrating a way to send Class 0 SMS on android >=2.3.

Note: this only works on versions 2.2 -> 4.1.2, the sendRawPdu method was removed, so you will need to find a new way to do this.

旧人九事 2025-01-08 13:34:41

在 Android 2.2 之前,可以发送 Flash SMS(这是 0 类 SMS 的术语)。
Google删除了sendRawPdu API,所以即使你使用反射,你也无法做到这一点。

这是我之前的做法(在 Android 1.6 上测试并有效)

private void sendSms(String phone, String sms) {
    if ((phone == null) || (sms == null) || (phone.length() == 0)
            || (sms.length() == 0)) {
        String message = "Phone or message empty!!!";
        Toast notification = Toast.makeText(getBaseContext(), message,
                Toast.LENGTH_SHORT);
        notification.show();
        return;
    }

    // SecurityManager oldSM = System.getSecurityManager();
    // MySecurityManager newSM = new MySecurityManager();
    // System.setSecurityManager(newSM);

    // ServiceManager.getService("isms")
    // ServiceManager.getService("isms");

    SmsManager m = SmsManager.getDefault();
    PendingIntent sentIntent = PendingIntent
            .getBroadcast(this, 0, new Intent(
                    MessageStatusReceiver_MESSAGE_STATUS_RECEIVED_ACTION),
                    0);

    PendingIntent deliveryIntent = PendingIntent.getBroadcast(this, 0,
            new Intent(SmsReceiverService_MESSAGE_SENT_ACTION), 0);

    // String sms = "Message self-destroyed!!!";
    // String phone = "93634096";

    long NOW = System.currentTimeMillis();
    String time = String.valueOf(NOW);

    // // m.sendTextMessage(phone, null, sms, sentIntent, deliveryIntent);
    // working // m.sendTextMessage(phone, null, sms, null, null);
    byte[] bb = new byte[1];
    Method m2 = null;
    try {
        m2 = SmsManager.class.getDeclaredMethod("sendRawPdu",
                bb.getClass(), bb.getClass(), PendingIntent.class,
                PendingIntent.class);
    } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    // send message

    SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(null, phone, sms,
            false);

    // http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=telephony/java/android/telephony/gsm/SmsMessage.java;h=9ccfa90d2e24e5caea26c1deac641b3c31ae56d4;hb=c883b143ba2b8bfe2f2033d00dee9ff733f1b59c

    boolean submitted = false;
    try {
        byte[] encodedMessage = pdus.encodedMessage;
        // byte[0] = mtiByte
        // byte[1] = TP Message Reference
        // byte[2] = length of source phone
        // byte[3..length] = phone
        // protocol identifier
        int msgLen = encodedMessage[2] / 2;
        // +2 -> length of source phone
        // +2 -> for 91 after the length
        // +1 -> TP PID
        int indexTPDCS = msgLen + 5;
        byte TPDCS = encodedMessage[indexTPDCS];
        // System.out.println(TPDCS);
        System.out.println(getHexString(encodedMessage));
        byte[] changedMessage = encodedMessage.clone();
        // Set bit 4 to 1 using OR (|), indicating there is a message class
        // Set bit 0 and 1 to 0 using AND (&), indicating class 0
        byte newTPDCS = (byte) ((TPDCS | 0x10) & 0xFC); // Flash SMS
        changedMessage[indexTPDCS] = newTPDCS; // Class 0
        System.out.println(getHexString(changedMessage));
        // Log.d(SmsScheduler_TAG, getHexString(changedMessage));
        boolean send = true;
        if (send) {
            m2.invoke(m, pdus.encodedScAddress, changedMessage, null, null);

            // sendSMS(HexDump.bytesToHexString(pdus.encodedScAddress),
            // HexDump.bytesToHexString(changedMessage), null);

            String message = "Flash SMS sent to " + phone
                    + " successfully!";
            Toast notification = Toast.makeText(getBaseContext(), message,
                    Toast.LENGTH_SHORT);
            notification.show();
            Log.d(SmsScheduler_TAG, message);
            submitted = true;
        }
    } catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

            // not essential, saves the SMS sent. 
    if (submitted) {
        ContentValues values = new ContentValues();
        values.put(ADDRESS, phone);
        values.put(DATE, time);
        values.put(READ, 0);
        values.put(STATUS, -1);
        values.put(TYPE, MESSAGE_TYPE_SENT);
        values.put(BODY, sms);

        Uri inserted = getContentResolver().insert(
                Uri.parse("content://sms"), values);
    }

    // System.setSecurityManager(oldSM);

}

It was possible to send Flash SMS (that's the term for class 0 SMS) before Android 2.2.
Google removed the sendRawPdu API, so even if you used reflection, you wouldn't be able to do it.

Here's how I did it previously (this was tested on Android 1.6 and worked)

private void sendSms(String phone, String sms) {
    if ((phone == null) || (sms == null) || (phone.length() == 0)
            || (sms.length() == 0)) {
        String message = "Phone or message empty!!!";
        Toast notification = Toast.makeText(getBaseContext(), message,
                Toast.LENGTH_SHORT);
        notification.show();
        return;
    }

    // SecurityManager oldSM = System.getSecurityManager();
    // MySecurityManager newSM = new MySecurityManager();
    // System.setSecurityManager(newSM);

    // ServiceManager.getService("isms")
    // ServiceManager.getService("isms");

    SmsManager m = SmsManager.getDefault();
    PendingIntent sentIntent = PendingIntent
            .getBroadcast(this, 0, new Intent(
                    MessageStatusReceiver_MESSAGE_STATUS_RECEIVED_ACTION),
                    0);

    PendingIntent deliveryIntent = PendingIntent.getBroadcast(this, 0,
            new Intent(SmsReceiverService_MESSAGE_SENT_ACTION), 0);

    // String sms = "Message self-destroyed!!!";
    // String phone = "93634096";

    long NOW = System.currentTimeMillis();
    String time = String.valueOf(NOW);

    // // m.sendTextMessage(phone, null, sms, sentIntent, deliveryIntent);
    // working // m.sendTextMessage(phone, null, sms, null, null);
    byte[] bb = new byte[1];
    Method m2 = null;
    try {
        m2 = SmsManager.class.getDeclaredMethod("sendRawPdu",
                bb.getClass(), bb.getClass(), PendingIntent.class,
                PendingIntent.class);
    } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    // send message

    SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(null, phone, sms,
            false);

    // http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=telephony/java/android/telephony/gsm/SmsMessage.java;h=9ccfa90d2e24e5caea26c1deac641b3c31ae56d4;hb=c883b143ba2b8bfe2f2033d00dee9ff733f1b59c

    boolean submitted = false;
    try {
        byte[] encodedMessage = pdus.encodedMessage;
        // byte[0] = mtiByte
        // byte[1] = TP Message Reference
        // byte[2] = length of source phone
        // byte[3..length] = phone
        // protocol identifier
        int msgLen = encodedMessage[2] / 2;
        // +2 -> length of source phone
        // +2 -> for 91 after the length
        // +1 -> TP PID
        int indexTPDCS = msgLen + 5;
        byte TPDCS = encodedMessage[indexTPDCS];
        // System.out.println(TPDCS);
        System.out.println(getHexString(encodedMessage));
        byte[] changedMessage = encodedMessage.clone();
        // Set bit 4 to 1 using OR (|), indicating there is a message class
        // Set bit 0 and 1 to 0 using AND (&), indicating class 0
        byte newTPDCS = (byte) ((TPDCS | 0x10) & 0xFC); // Flash SMS
        changedMessage[indexTPDCS] = newTPDCS; // Class 0
        System.out.println(getHexString(changedMessage));
        // Log.d(SmsScheduler_TAG, getHexString(changedMessage));
        boolean send = true;
        if (send) {
            m2.invoke(m, pdus.encodedScAddress, changedMessage, null, null);

            // sendSMS(HexDump.bytesToHexString(pdus.encodedScAddress),
            // HexDump.bytesToHexString(changedMessage), null);

            String message = "Flash SMS sent to " + phone
                    + " successfully!";
            Toast notification = Toast.makeText(getBaseContext(), message,
                    Toast.LENGTH_SHORT);
            notification.show();
            Log.d(SmsScheduler_TAG, message);
            submitted = true;
        }
    } catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

            // not essential, saves the SMS sent. 
    if (submitted) {
        ContentValues values = new ContentValues();
        values.put(ADDRESS, phone);
        values.put(DATE, time);
        values.put(READ, 0);
        values.put(STATUS, -1);
        values.put(TYPE, MESSAGE_TYPE_SENT);
        values.put(BODY, sms);

        Uri inserted = getContentResolver().insert(
                Uri.parse("content://sms"), values);
    }

    // System.setSecurityManager(oldSM);

}
零崎曲识 2025-01-08 13:34:41

Scrool的答案确实是正确的,https://stackoverflow.com/a/12873325/3082310,因为 ZeroSMS 确实会发送 Flash SMS;
然而,它只是一个概念验证,仅支持 7 位编码的短信。

为了正确编码,似乎需要修改代码并添加 if-then 或 switch-case 语句:
对于 7 位编码,如英语,

使用 (byte)0xF0

对于 16 位编码,UCS-2 编码

使用 (byte) 0x18

否则,如果您输入不支持的语言。

Scrool's answer is indeed correct, https://stackoverflow.com/a/12873325/3082310 , as ZeroSMS does send flash SMS's;
however, it is a Proof-of-Concept and only supports SMS's with 7-bit encoding.

For proper encoding it seems there is a need to modify the code and add if-then or switch-case statements:
For 7-bit coding, as in english

use (byte)0xF0

For 16-bit encoding, UCS-2 encoding

use (byte) 0x18

Otherwise, junk characters appear if you enter unsupported language.

陈年往事 2025-01-08 13:34:41

是的,也不是。这容易可能吗?不。从技术上来说,愚蠢的行为(阅读:反射)是否可行?

Yes and no. Is it easily possible? No. Is it technically possible with tomfoolery (read: reflection)? Usually.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文