Transfert rapide depuis les messageries instantanées - Portefeuille Android QIWI

salut!

Je m'appelle Alex, je suis développeur chez QIWI.

TL; DR

Comment transférer du messager directement sur le formulaire de paiement:

  1. Dans le manifeste, nous mettons une activité c vide du intent-filter type ACTION_VIEWet ACTION_DIALavec le schéma «tel».
  2. En activitĂ©, nous transfĂ©rons vers le formulaire de paiement via le lien profond existant, l'enrichissant avec les donnĂ©es de l'original intent- “tel:XXXXX”



Bénéfice : en cliquant sur le numéro de téléphone en surbrillance dans le messager, une personne accÚde au formulaire de transfert avec le champ rempli du destinataire du transfert.
Bonus : je vais vous dire Ă  quel point activer cette fonctionnalitĂ©, sans ĂȘtre en mesure de modifier la liste des filtres d'intention dans le manifeste lors de l'exĂ©cution.

Pourquoi?


Supposons qu'une personne ait la tùche de transférer de l'argent pour un cadeau d'anniversaire collectif. Le destinataire peut choisir des options de transfert pratiques: transfert vers une carte, portefeuille électronique, transfert direct vers un compte ou autre chose. De nombreuses entreprises fournissant des services de traduction acceptent un numéro de téléphone comme identifiant d'utilisateur secondaire ou principal. Afin d'éviter les transferts erronés, le destinataire peut transmettre son numéro de téléphone via un SMS: email, messagerie instantanée ou SMS. Le message indique également le systÚme nécessaire pour la traduction.

Un chemin d'utilisateur typique consiste Ă  copier le numĂ©ro de tĂ©lĂ©phone Ă  partir du messager et Ă  le coller dans l'application pour la traduction. Cette mĂ©thode implique de basculer entre les applications, d'accĂ©der Ă©ventuellement au bureau et mĂȘme de rechercher parmi les applications installĂ©es du fournisseur de services de traduction. Est-il possible de raccourcir ce chemin en rĂ©duisant le nombre d'Ă©tapes? Il y a une option.

Théorie


De nombreux messagers instantanés dans les smartphones reconnaissent les numéros de téléphone et les mettent en évidence sous la forme d'un lien hypertexte. Par défaut, il existe une application pour traiter ce type de liens sur n'importe quel appareil mobile avec un module GSM. Habituellement, il est appelé «Téléphone». Dans Android, la possibilité de traiter un numéro de téléphone partagé est déclarée dans AndroidManifest. Exemples d'applications: «Téléphone», Viber, Skype. Si vous interceptez ces événements, vous pouvez immédiatement fournir à l'utilisateur une liste d'actions possibles avec un numéro de téléphone. Dans notre cas, ce sera une offre de transfert via QIWI Wallet.

Nous sommes intéressés par les événements avec types Intent.ACTION_VIEW, Intent.ACTION_DIAL, Intent.ACTION_CALLavec le schéma tel. un événementIntent.ACTION_CALLIl a des restrictions sur la politique de sécurité Android et son initialisation nécessite l'autorisation de l'utilisateur à partir de la version de Marshmallow incluse. Selon nos messagers de recherche en utilisant plus générale Intent.ACTION_VIEW, Intent.ACTION_DIAL.

Il existe plusieurs types similaires spĂ©cifiquement pour les tĂ©lĂ©phones d'urgence, mais ce n'est clairement pas notre cas. Le corps d'intention a la forme «tel: 12345678». Ce type d'intention ne peut pas ĂȘtre traitĂ© android.content.UriMatcher, car l'hĂŽte manque ici. Le moyen le plus simple de gĂ©rer ce type d'Uri est de le demander schemeSpecificPart et de vĂ©rifier s'il s'agit d'un numĂ©ro de tĂ©lĂ©phone valide.

La liste des filtres d'intention doit ĂȘtre spĂ©cifiĂ©e dans AndroidManifest, il est impossible de la modifier lors de l'exĂ©cution de l'application. Comment dĂ©sactiver Ă  distance cette fonctionnalitĂ©? La premiĂšre option consiste Ă  rejeter la demande de l'utilisateur au moment de l'ouverture de l'activitĂ© - avec un message ou tout simplement fermer l'application. De notre point de vue, ce n'est pas le meilleur UX, car nous allons interrompre le flux de l'utilisateur au milieu. Il vaut mieux ne laisser personne choisir notre application, si la fonctionnalitĂ© est dĂ©sactivĂ©e. Il est plus facile de dĂ©sactiver le composant avec la liste des filtres d'intention lors de l'exĂ©cution, cela ne donnera Ă  l'utilisateur aucune fausse promesse dans l'interface systĂšme. Lorsque vous utilisez le PackageManager, notez que la vĂ©rification de l'inclusion de composants n'est pas trĂšs fiable. Il est prĂ©fĂ©rable de enabled forcer l' indicateur d' un composant sans se fier Ă  son Ă©tat actuel Ă  l'aide de valeursCOMPONENT_ENABLED_STATE_ENABLED et COMPONENT_ENABLED_STATE_DISABLED. Les modifications apportĂ©es via PackageManager sont enregistrĂ©es jusqu'Ă  ce que l'application soit dĂ©sinstallĂ©e de l'appareil.

Entraine toi


Afin de désactiver la fonctionnalité, nous avons besoin d'un composant Android pour la désactiver.
Le moyen le plus simple consiste à utiliser une activité vide, ce que nous ferons. Si vous décidez d'utiliser le Service avec un ensemble similaire de filtres d'intention, consultez les guides Google, qui disent spécifiquement «ne déclarez pas de filtres d'intention pour vos services» . Veuillez noter que par défaut le composant est désactivé: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>

L'activitĂ© elle-mĂȘme est simplement redirigĂ©e vers le mode de paiement via les diplinks existants.

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()
    }
}

Le drapeau android: enabled peut ĂȘtre contrĂŽlĂ© par cette classe d'assistance.

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
        }

    }
}

Ici, la méthode «isMessengerP2PEnabled» n'est pas utilisée pour vérifier l'état actuel du composant, car lors des tests, il a produit des résultats peu fiables. Si vous décidez de l'utiliser, vérifiez soigneusement son fonctionnement dans les conditions de la logique métier asynchrone et lors du téléchargement de l'application.

Le temps pour changer la valeur de l'indicateur n'est enabled pas trĂšs important, nous avons choisi le moment oĂč la configuration des indicateurs de fonctionnalitĂ© Ă©tait complĂštement chargĂ©e.

Pour que lorsque vous cliquez sur le numĂ©ro de tĂ©lĂ©phone dans les messagers, il y ait une boĂźte de dialogue de sĂ©lection du systĂšme, vous devez fournir Ă  l'utilisateur des instructions sur la façon de dĂ©sactiver les paramĂštres par dĂ©faut pour l'intention - un «tel: XXXXX». Par exemple: «Si vous ne pouvez passer un appel que lorsque vous cliquez sur un numĂ©ro, accĂ©dez aux paramĂštres du smartphone → sĂ©lectionnez TĂ©lĂ©phone dans la liste des applications → rĂ©initialisez« Ouvrir par dĂ©faut ».


Si vous désactivez le composant lors de vos déplacements, lorsque l'utilisateur voit cette boßte de dialogue systÚme, rien de mauvais ne se produira. L'élément correspondant disparaßtra instantanément de la liste, dans notre cas «Transfert d'argent».

Un comportement intéressant commencera si l'utilisateur traite les liens via notre application par défaut. Pour ce faire, il suffit de pousser l'élément «Mémoriser la sélection» ou «Toujours». Si vous désactivez le composant, l'utilisateur aura le choix de l'application à utiliser et, au premier démarrage, il n'y aura pas d'élément «Mémoriser la sélection». AprÚs avoir activé les fonctionnalités, l'ensemble du flux sera restauré, l'utilisateur sera transféré directement vers l'application.

Conclusion


L'idĂ©e de cette fonctionnalitĂ© nous est venue il y a longtemps, le ticket original a Ă©tĂ© crĂ©Ă© en 2017. L'idĂ©e n'a pas perdu de sa pertinence, mĂȘme maintenant, je n'ai pas pu trouver une application bancaire avec des fonctionnalitĂ©s similaires. Nous avons publiĂ© les «transferts du messager» le 29 avril, le premier jour, prĂšs de 8 000 utilisateurs uniques en ont profitĂ©. Si les indicateurs commerciaux dans un avenir proche nous satisfont, nous dĂ©velopperons davantage cette fonctionnalitĂ©.

Que pensez-vous, combien d'intentions plus intéressantes d'Android attendent paisiblement leur application métier?

All Articles