Schnelle Übertragung von Instant Messenger - QIWI Android Wallet

Hallo!

Mein Name ist Alex, ich bin Entwickler bei QIWI.

TL; DR

So übertragen Sie vom Messenger direkt auf das Zahlungsformular:

  1. In das Manifest setzen wir eine leere Aktivität c des intent-filter Typs ACTION_VIEWund ACTION_DIALmit dem Schema "tel".
  2. In der Aktivität übertragen wir über den vorhandenen Deeplink auf das Zahlungsformular und bereichern es mit Daten aus dem Original intent- “tel:XXXXX”



Gewinn : Durch Klicken auf die markierte Telefonnummer im Messenger gelangt eine Person auf das Überweisungsformular mit dem ausgefüllten Feld des Überweisungsempfängers.
Bonus : Ich werde Ihnen sagen, wie schön es ist, diese Funktion zu aktivieren, ohne die Liste der Absichtsfilter im Manifest zur Laufzeit ändern zu können.

Wozu?


Angenommen, eine Person hat die Aufgabe, Geld für ein gemeinsames Geburtstagsgeschenk zu überweisen. Die empfangende Partei kann bequeme Überweisungsoptionen wählen: Überweisung auf eine Karte, elektronische Geldbörse, direkte Überweisung auf ein Konto oder etwas anderes. Viele Unternehmen, die Übersetzungsdienste anbieten, akzeptieren eine Telefonnummer als sekundäre oder primäre Benutzerkennung. Um fehlerhafte Überweisungen zu vermeiden, kann der Empfänger seine Telefonnummer per SMS übermitteln: E-Mail, Instant Messenger oder SMS. Die Nachricht zeigt auch das für die Übersetzung erforderliche System an.

Ein typischer Benutzerpfad besteht darin, die Telefonnummer aus dem Messenger zu kopieren und zur Übersetzung in die Anwendung einzufügen. Auf diese Weise müssen Sie zwischen Anwendungen wechseln, möglicherweise auf den Desktop zugreifen und sogar zwischen den installierten Anwendungen des Übersetzungsdienstanbieters suchen. Ist es möglich, diesen Pfad zu verkürzen, indem die Anzahl der Schritte verringert wird? Es gibt eine Option.

Theorie


Viele Instant Messenger in Smartphones erkennen Telefonnummern und markieren sie in Form eines Hyperlinks. Standardmäßig gibt es eine Anwendung zum Verarbeiten dieser Art von Links auf jedem mobilen Gerät mit einem GSM-Modul. Normalerweise heißt es "Telefon". In Android ist die Möglichkeit, eine freigegebene Telefonnummer zu verarbeiten, in AndroidManifest deklariert. Anwendungsbeispiele: „Telefon“, Viber, Skype. Wenn Sie diese Ereignisse abfangen, können Sie dem Benutzer sofort eine Liste möglicher Aktionen mit einer Telefonnummer zur Verfügung stellen. In unserem Fall handelt es sich um ein Transferangebot über QIWI Wallet.

Wir interessieren uns für Veranstaltungen mit Typen Intent.ACTION_VIEW, Intent.ACTION_DIAL, Intent.ACTION_CALLmit dem Tel-Schema. VeranstaltungIntent.ACTION_CALLDie Android-Sicherheitsrichtlinie unterliegt Einschränkungen, und für die Initialisierung ist die Erlaubnis des Benutzers ab der Version von Marshmallow inklusive erforderlich. Laut unseren Forschungsboten verwenden allgemeinere Intent.ACTION_VIEW, Intent.ACTION_DIAL.

Es gibt verschiedene ähnliche Typen speziell für Notruftelefone, aber dies ist eindeutig nicht unser Fall. Der Absichtskörper hat die Form "tel: 12345678". Diese Art von Absicht kann nicht verarbeitet werden android.content.UriMatcher, da hier der Host fehlt. Der einfachste Weg, mit dieser Art von Uri umzugehen, besteht darin, sie zu fragen schemeSpecificPart und zu überprüfen, ob es sich um eine gültige Telefonnummer handelt.

Die Liste der Absichtsfilter muss in AndroidManifest angegeben werden. Sie kann während der Ausführung der Anwendung nicht geändert werden. Wie kann ich diese Funktion aus der Ferne deaktivieren? Die erste Möglichkeit besteht darin, die Anforderung des Benutzers zum Zeitpunkt des Öffnens der Aktivität abzulehnen - mit einer Nachricht oder einfach die Anwendung zu schließen. Aus unserer Sicht ist dies nicht die beste UX, da wir den Benutzerfluss in der Mitte unterbrechen werden. Es ist besser, wenn wir nicht zulassen, dass eine Person unsere Anwendung auswählt, wenn die Funktionalität deaktiviert ist. Es ist einfacher, die Komponente mit der Intent-Filter-Liste zur Laufzeit zu deaktivieren. Dies gibt dem Benutzer keine falschen Versprechungen in der Systemschnittstelle. Beachten Sie bei der Verwendung des PackageManager, dass die Überprüfung der Komponenteneinbeziehung nicht sehr zuverlässig ist. Es ist vorzuziehen, enabled das Flag einer Komponente zu erzwingen, ohne sich mit Werten auf den aktuellen Status zu verlassenCOMPONENT_ENABLED_STATE_ENABLED und COMPONENT_ENABLED_STATE_DISABLED. Über den PackageManager vorgenommene Änderungen werden gespeichert, bis die Anwendung vom Gerät deinstalliert wird.

Trainieren


Um die Funktion zu deaktivieren, benötigen wir eine Android-Komponente, um sie zu deaktivieren.
Der einfachste Weg ist, eine leere Aktivität zu verwenden, was wir tun werden. Wenn Sie sich für die Verwendung des Dienstes mit einem ähnlichen Satz von Absichtsfiltern entscheiden, lesen Sie die Google-Handbücher, in denen ausdrücklich angegeben ist, dass "Absichtsfilter für Ihre Dienste nicht deklariert werden" . Bitte beachten Sie, dass die Komponente standardmäßig deaktiviert ist:android:enabled="false"

  <activity
            android:name=".messengerP2P.view.MessengerP2PActivity"
            android:configChanges="orientation"
            android:label="@string/title_activity_messenger_p2_p"
            android:enabled="false"
            android:screenOrientation="portrait">
            <!-- Open shared telephone number as dial application -->
            <intent-filter

                android:label="@string/title_activity_messenger_p2_p">
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.DIAL" />

                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="tel" />
            </intent-filter>
        </activity>

Die Aktivität selbst leitet einfach über bestehende Diplinks zur Zahlungsform weiter.

class MessengerP2PActivity : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        var phoneNumberFromDial: String? = intent?.data?.schemeSpecificPart
        phoneNumberFromDial?.let {
            if (ru.mw.utils.Utils
                    .isPhoneNumber(phoneNumberFromDial)) {
                val phoneNumberFromDialLink = PaymentActivity.getUriForProviderId(
                        resources.getInteger(R.integer.providerIdQiwiWallet).toLong(), null, null)
                    .buildUpon()
                    .appendQueryParameter(PaymentActivity.QUERY_PARAM_ACCOUNT, phoneNumberFromDial)
                startActivity(
                    Intent(Intent.ACTION_VIEW, phoneNumberFromDialLink.build()))
            }
        }
        finish()
    }
}

Das android: enabled-Flag kann von dieser Hilfsklasse gesteuert werden.

import android.content.ComponentName
import android.content.Context
import android.content.pm.PackageManager

class MessengerP2PUtils {

    companion object {
        private const val componentName = "ru.mw.messengerP2P.view.MessengerP2PActivity"

        private fun switchMessengerP2P(enabled: Boolean = true, packageName: String, packageManager: PackageManager) {
            val compName = ComponentName(packageName, componentName)
            packageManager.setComponentEnabledSetting(
                compName,
                when (enabled) {
                    true -> PackageManager.COMPONENT_ENABLED_STATE_ENABLED
                    else -> PackageManager.COMPONENT_ENABLED_STATE_DISABLED
                },
                PackageManager.DONT_KILL_APP)
        }

        fun enableMessengerP2P(applicationContext: Context) {
            val packageName = applicationContext.packageName
            val packageManager = applicationContext.packageManager
            switchMessengerP2P(enabled = true, packageName = packageName, packageManager = packageManager);
        }

        fun disableMessengerP2P(applicationContext: Context) {
            val packageName = applicationContext.packageName
            val packageManager = applicationContext.packageManager
            switchMessengerP2P(enabled = false, packageName = packageName, packageManager = packageManager);
        }

        fun isMessengerP2PEnabled(packageName: String, packageManager: PackageManager): Boolean {
            val state = packageManager.getComponentEnabledSetting(ComponentName(packageName, componentName))
            return state == PackageManager.COMPONENT_ENABLED_STATE_ENABLED || state == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
        }

    }
}

Die Methode „isMessengerP2PEnabled“ wird hier nicht verwendet, um den aktuellen Status der Komponente zu überprüfen, da sie beim Testen zu unzuverlässigen Ergebnissen führte. Wenn Sie sich für die Verwendung entscheiden, überprüfen Sie den Betrieb unter den Bedingungen der asynchronen Geschäftslogik und beim Herunterladen der Anwendung sorgfältig.

Die Zeit zum Ändern des Flag-Werts ist enabled nicht sehr wichtig. Wir haben den Moment gewählt, in dem die Feature-Flags-Konfiguration vollständig geladen wurde.

Wenn Sie in den Messenger auf die Telefonnummer klicken, wird ein Systemdialog Ihrer Wahl angezeigt. Sie müssen dem Benutzer Anweisungen zum Deaktivieren der Standardeinstellungen für Vorsatz geben - ein „Tel: XXXXX“. Beispiel: „Wenn Sie nur dann einen Anruf tätigen können, wenn Sie auf eine Nummer klicken, gehen Sie zu Smartphone-Einstellungen → Wählen Sie in der Anwendungsliste Telefon aus → Setzen Sie die Einstellung auf„ Standardmäßig öffnen “zurück.


Wenn Sie die Komponente unterwegs deaktivieren und dem Benutzer dieses Systemdialogfeld angezeigt wird, passiert nichts Schlimmes. Der entsprechende Artikel verschwindet sofort aus der Liste, in unserem Fall "Geld überweisen".

Ein interessantes Verhalten beginnt, wenn der Benutzer die Links standardmäßig über unsere Anwendung verarbeitet. Dazu reicht es aus, den Punkt „Auswahl merken“ oder „Immer“ zu drücken. Wenn Sie die Komponente deaktivieren, hat der Benutzer die Wahl, welche Anwendung er verwenden möchte, und beim ersten Start wird kein Element "Auswahl speichern" angezeigt. Nach dem Aktivieren der Funktionen wird der gesamte Ablauf wiederhergestellt und der Benutzer direkt zur Anwendung übertragen.

Fazit


Die Idee zu dieser Funktion ist uns schon vor langer Zeit gekommen, das Originalticket wurde 2017 erstellt. Die Idee hat auch jetzt noch nicht an Relevanz verloren, ich konnte keine Bankanwendung mit ähnlicher Funktionalität finden. Wir haben am 29. April "Transfers from the Messenger" veröffentlicht. Am ersten Tag nutzten fast 8.000 Unique User diese. Wenn uns Geschäftsindikatoren in naher Zukunft zufrieden stellen, werden wir diese Funktion weiterentwickeln.

Was denkst du, wie viele weitere interessante Absichten von Android warten friedlich auf ihre Geschäftsanwendung?

All Articles