Автоматичен SMS отговор от приложението за Android

Опитвам се да постигна нещо подобно на приложение „Намерете моя телефон“, тоест да изпратя SMS до телефона си и да получа отговор чрез SMS, който казва къде се намира телефонът ми. Изискване за това приложение е да бъде с отворен код.

Видях, че този вид приложение вече съществува в хранилището на F-Droid и се нарича FindMyPhone. Въпреки това, когато телефонът получи SMS, неговият отговор просто се показва в приложението за съобщения на склад като отговор на контакта, но не се изпраща ефективно. Това не е очакваното поведение и можех да видя в хранилището на кодове, че авторът се е опитал да коригира това и след това се е отказал през 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();
            }

(връзка към кода в sourceforge)

Този код се изпълнява в клас, изпълняващ LocationListener, извикан в нова нишка от услуга.

Някакъв намек за причината за това поведение? Защо съобщението просто се показва, но не се изпраща? Погледнах в друго подобно приложение: https://f-droid.org/repository/browse/?fdid=com.teamdc.stephendiniz.autoaway

Това работи добре и отговаря на SMS-ите според очакванията. Основната му разлика е, че това приложение работи в услуга, която непрекъснато слуша за нови съобщения и регистрира приемника в движение, вместо да го декларира в манифеста. За мен това няма да е голяма работа, но бих предпочел услугата да не работи винаги.

Благодаря предварително за всяка помощ по този въпрос.


person Antonio Pisano    schedule 27.12.2015    source източник


Отговори (2)


Една от причините за неуспешното изпращане на 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, трябва да бъде кратко.

person fejd    schedule 27.12.2015
comment
Благодаря за отговора ви, но се страхувам, че това не е причината за моя проблем: AutoAway, приложението, което правилно изпраща SMS-и, извършва същото повикване за sendTextMessage, като предава null като център за услуги за SMS. - person Antonio Pisano; 30.12.2015
comment
FindMyPhone се регистрира, за да реагира на SMS_RECEIVED в манифеста. Реакцията действително се случва, но SMS се показва само в моето приложение за съобщения и не се изпраща така или иначе. - person Antonio Pisano; 30.12.2015
comment
Не можех да кажа защо не е изпратено, без да гледам регистрационните файлове (adb logcat -b radio), но ако се показва в приложението за съобщения в запаса като изпратено (изпратено, на опашка или неуспешно изпращане?), тогава това означава рамката на Android го е запазил в базата данни за SMS/MMS и това се случва, след като съобщението е изпратено (или неуспешно) в android.googlesource.com/platform/frameworks/opt/telephony/+/. - person fejd; 30.12.2015

Открих какъв е проблемът, няма нищо общо с API за съобщения.

В BroadcastReceiver, реагиращ на пристигането на SMS, телефонният номер на изпращача беше предаден на Услугата, която всъщност изпраща отговора на SMS чрез данни за намерение като тези

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

Тъй като адресът „от“ беше URI кодиран, знакът + (плюс) в международния префикс беше загубен. Приложението за съобщения можеше да приеме това, така че успя да покаже съобщението, но това нямаше да бъде изпратено.

Използването на Intent Extras вместо Data свърши работа, тъй като по този начин телефонният номер няма да премине през никакво кодиране.

Всичко най-хубаво

person Antonio Pisano    schedule 30.12.2015