来自Android App的自动短信回复

时间:2015-12-27 13:36:21

标签: android gps sms auto-responder

我正在努力实现与“查找我的手机”应用程序类似的功能,即将短信发送到我的手机并通过短信接收回复,告诉我手机的位置。该应用程序的要求是开源的。

我已经看到这种应用程序已经存在于F-Droid存储库中,被称为FindMyPhone。但是,当手机收到短信时,其回复只会在股票信息应用中显示为对联系人的回复,但无法有效发送。这不是预期的行为,我可以在代码库中看到作者试图纠正这个然后在2013年放弃。

我查看了代码并看到它使用的技术是直截了当的:

                try {
                SmsManager smsManager = SmsManager.getDefault();
                // ********* SENDING SMS HERE *******
                smsManager.sendTextMessage(currentFromAddress, null, txt, null, null);
                // ********* SENDING SMS HERE *******
                Log.d(FindMyPhoneHelper.LOG_TAG, "Sent SMS");
                Thread.sleep(5000);
                Log.d(FindMyPhoneHelper.LOG_TAG, "Slept 5000ms");
            } catch(Exception e) {
                Log.d(FindMyPhoneHelper.LOG_TAG, "Failed SMS: " + e.getMessage());
                e.printStackTrace();
            }

(link to the code in sourceforge)

此代码在实现LocationListener的类中执行,该类在服务的新线程内调用。

有关此行为原因的任何暗示?为什么消息刚刚显示但未发送?我查看了另一个类似的应用程序:https://f-droid.org/repository/browse/?fdid=com.teamdc.stephendiniz.autoaway

这是正常的,并按预期答复短信。它的主要区别在于这个应用程序在一个服务中运行,不断地监听新消息并在运行中注册接收器,而不是在清单中声明它。对我而言,这不会有什么大不了的,但我宁愿不让服务一直在运行。

提前感谢您提供任何帮助。

2 个答案:

答案 0 :(得分:0)

SMS无法发送的一个原因可能是应用程序将null作为SMS服务中心传递给sendTextMessage,而应该从SMS提供程序获取它,如下所示:

    public static String getSmsServiceCenterForConversation(final DatabaseWrapper dbWrapper,
        final String conversationId) {
    Assert.isNotMainThread();
    Cursor cursor = null;
    try {
        cursor = dbWrapper.query(DatabaseHelper.CONVERSATIONS_TABLE,
                new String[] { ConversationColumns.SMS_SERVICE_CENTER },
                ConversationColumns._ID + "=?",
                new String[] { conversationId },
                null, null, null);
        Assert.inRange(cursor.getCount(), 0, 1);
        if (cursor.moveToFirst()) {
            return cursor.getString(0);
        }
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
    return null;
}

参考:https://android.googlesource.com/platform/packages/apps/Messaging/+/master/src/com/android/messaging/datamodel/BugleDatabaseOperations.java#917

您应该在清单中注册收听SMS_RECEIVED的广播接收器 - 无需动态注册接收器。接收器应该将工作卸载到服务,就像IntentService一样,因为onReceive中的执行时间应该保持很短。

答案 1 :(得分:0)

发现问题所在,它与消息传递API无关。

在BroadcastReceiver对SMS到达作出反应时,发送者的电话号码被传递给服务实际上通过Intent数据发送回复短信

locationIntent.setData(Uri.parse("?destinationAddress=" + from));

由于“from”地址是URI编码的,因此国际前缀中的+(加号)字符丢失。消息应用程序可以使用它,因此它能够显示消息,但不会发送。

使用Intent Extras代替Data可以解决问题,因为这种方式的电话号码不会通过任何编码。

一切顺利