来自 Android 个应用的自动短信回复
Automatic SMS reply from Android App
我正在尝试实现类似于 "Find my phone" 应用程序的功能,即向我的 phone 发送短信并通过短信接收回复,告知我的 phone 所在位置.此应用程序的要求是开源。
我看到F-Droid库中已经存在这种应用程序,叫做FindMyPhone。然而,当phone收到短信时,其回复只是作为对联系人的回复显示在股票短信应用程序中,但并未有效发送。这不是预期的行为,我可以在代码存储库中看到作者尝试更正此问题,然后在 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)
此代码在 class 实现 LocationListener 中执行,由服务在新线程中调用。
关于此行为原因的任何提示?为什么消息只显示而不发送?我查看了另一个类似的应用程序:https://f-droid.org/repository/browse/?fdid=com.teamdc.stephendiniz.autoaway
这一切正常,可以按预期回复短信。它的主要区别在于,此应用程序在服务中运行,不断侦听新消息并即时注册接收者,而不是在清单中声明它。对我来说这没什么大不了的,但我宁愿不要总是有服务 运行.
提前感谢您对此提供的任何帮助。
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;
}
您应该在清单中注册收听 SMS_RECEIVED 的广播接收器 - 无需即时注册接收器。接收方应该将工作卸载到服务,例如 IntentService,因为在 onReceive 中花费的执行时间应该保持较短。
找到问题所在,与消息无关API。
在 BroadcastReceiver 对 SMS 到达做出反应时,phone 发送者的号码被传递给服务,实际上通过 Intent 数据发送回复 SMS
locationIntent.setData(Uri.parse("?destinationAddress=" + from));
由于 "from" 地址是 URI 编码的,国际前缀中的 +(加号)字符丢失了。消息传递应用程序可以接受,因此它能够显示消息,但不会发送。
使用 Intent Extras 而不是 Data 就成功了,因为这样 phone 数字将不会通过任何编码。
祝一切顺利
我正在尝试实现类似于 "Find my phone" 应用程序的功能,即向我的 phone 发送短信并通过短信接收回复,告知我的 phone 所在位置.此应用程序的要求是开源。
我看到F-Droid库中已经存在这种应用程序,叫做FindMyPhone。然而,当phone收到短信时,其回复只是作为对联系人的回复显示在股票短信应用程序中,但并未有效发送。这不是预期的行为,我可以在代码存储库中看到作者尝试更正此问题,然后在 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)
此代码在 class 实现 LocationListener 中执行,由服务在新线程中调用。
关于此行为原因的任何提示?为什么消息只显示而不发送?我查看了另一个类似的应用程序:https://f-droid.org/repository/browse/?fdid=com.teamdc.stephendiniz.autoaway
这一切正常,可以按预期回复短信。它的主要区别在于,此应用程序在服务中运行,不断侦听新消息并即时注册接收者,而不是在清单中声明它。对我来说这没什么大不了的,但我宁愿不要总是有服务 运行.
提前感谢您对此提供的任何帮助。
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;
}
您应该在清单中注册收听 SMS_RECEIVED 的广播接收器 - 无需即时注册接收器。接收方应该将工作卸载到服务,例如 IntentService,因为在 onReceive 中花费的执行时间应该保持较短。
找到问题所在,与消息无关API。
在 BroadcastReceiver 对 SMS 到达做出反应时,phone 发送者的号码被传递给服务,实际上通过 Intent 数据发送回复 SMS
locationIntent.setData(Uri.parse("?destinationAddress=" + from));
由于 "from" 地址是 URI 编码的,国际前缀中的 +(加号)字符丢失了。消息传递应用程序可以接受,因此它能够显示消息,但不会发送。
使用 Intent Extras 而不是 Data 就成功了,因为这样 phone 数字将不会通过任何编码。
祝一切顺利