Transferencia rápida desde mensajería instantánea - QIWI Android Wallet

¡Hola!

Mi nombre es Alex, soy desarrollador en QIWI.

TL; DR

Cómo transferir desde el messenger directamente al formulario de pago:

  1. En el manifiesto ponemos una Actividad c vacía del intent-filter tipo ACTION_VIEWy ACTION_DIALcon el esquema "tel".
  2. En actividad, transferimos al formulario de pago a través del enlace profundo existente, enriqueciéndolo con datos del original intent- “tel:XXXXX”



Beneficio : al hacer clic en el número de teléfono resaltado en el messenger, una persona obtiene el formulario de transferencia con el campo completado del destinatario de la transferencia.
Bonificación : te diré lo maravilloso que es habilitar esta función, sin poder cambiar la lista de filtros de intención en el manifiesto en tiempo de ejecución.

¿Para qué?


Supongamos que una persona tiene la tarea de transferir dinero para un regalo de cumpleaños colectivo. La parte receptora puede elegir opciones de transferencia convenientes: transferencia a una tarjeta, billetera electrónica, transferencia directa a una cuenta u otra cosa. Muchas compañías que brindan servicios de traducción aceptan un número de teléfono como identificador de usuario secundario o primario. Para evitar transferencias erróneas, el destinatario puede transmitir su número de teléfono por mensaje de texto: correo electrónico, mensajería instantánea o SMS. El mensaje también indica el sistema necesario para la traducción.

Una ruta de usuario típica es copiar el número de teléfono del messenger y pegarlo en la aplicación para su traducción. Esta forma implica cambiar entre aplicaciones, posiblemente accediendo al escritorio e incluso buscando entre las aplicaciones instaladas del proveedor de servicios de traducción. ¿Es posible acortar este camino reduciendo el número de pasos? Hay una opción

Teoría


Muchos mensajeros instantáneos en teléfonos inteligentes reconocen los números de teléfono y los resaltan en forma de hipervínculo. Por defecto, existe una aplicación para procesar este tipo de enlaces en cualquier dispositivo móvil con un módulo GSM. Por lo general, se llama "teléfono". En Android, la capacidad de procesar un número de teléfono compartido se declara en AndroidManifest. Ejemplos de aplicaciones: "Teléfono", Viber, Skype. Si intercepta estos eventos, puede proporcionar inmediatamente al usuario una lista de posibles acciones con un número de teléfono. En nuestro caso, esta será una oferta de transferencia a través de QIWI Wallet.

Estamos interesados ​​en eventos con tipos Intent.ACTION_VIEW, Intent.ACTION_DIAL, Intent.ACTION_CALLcon el esquema tel. EventoIntent.ACTION_CALLTiene restricciones en la política de seguridad de Android y su inicialización requiere permiso del usuario a partir de la versión de Marshmallow inclusive. De acuerdo con nuestros mensajeros de investigación usando más general Intent.ACTION_VIEW, Intent.ACTION_DIAL.

Existen varios tipos similares específicamente para teléfonos de emergencia, pero claramente este no es nuestro caso. El cuerpo de la intención tiene la forma "tel: 12345678". Este tipo de intención no se puede procesar android.content.UriMatcher, porque falta el host aquí. La forma más fácil de manejar este tipo de Uri es preguntarlo schemeSpecificPart y verificar si es un número de teléfono válido.

La lista de filtros intencionales debe especificarse en AndroidManifest, es imposible cambiarla durante la ejecución de la aplicación. ¿Cómo deshabilitar esta función de forma remota? La primera opción es rechazar la solicitud del usuario en el momento en que se abrió la Actividad, con un mensaje o simplemente cerrar la aplicación. Desde nuestro punto de vista, este no es el mejor UX, ya que interrumpiremos el flujo del usuario en el medio. Es mejor si no dejamos que una persona elija nuestra aplicación, si la funcionalidad está deshabilitada. Es más fácil deshabilitar el componente con la lista de filtro de intención en tiempo de ejecución, esto no le dará al usuario ninguna promesa falsa en la interfaz del sistema. Cuando utilice el PackageManager, tenga en cuenta que verificar la inclusión de componentes no es muy confiable. Es preferible enabled forzar el indicador de un componente sin depender de su estado actual utilizando valoresCOMPONENT_ENABLED_STATE_ENABLED y COMPONENT_ENABLED_STATE_DISABLED. Los cambios realizados a través del PackageManager se guardan hasta que la aplicación se desinstala del dispositivo.

Práctica


Para deshabilitar la función, necesitamos un componente de Android para deshabilitarla.
La forma más fácil es usar una Actividad vacía, que haremos. Si decide utilizar el Servicio con un conjunto similar de filtros de intención, consulte las guías de Google, que dicen específicamente "no declare filtros de intención para sus servicios" . Tenga en cuenta que, de forma predeterminada, el componente está deshabilitado: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>

La actividad en sí misma simplemente redirige a la forma de pago a través de diplinks existentes.

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

El android: bandera habilitada puede ser controlada por esta clase auxiliar.

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
        }

    }
}

El método "isMessengerP2PEnabled" no se utiliza aquí para verificar el estado actual del componente, ya que durante las pruebas produjo resultados poco confiables. Si decide usarlo, verifique cuidadosamente su funcionamiento en condiciones de lógica comercial asincrónica y al descargar la aplicación.

El tiempo para cambiar el valor del indicador enabled no es muy importante, elegimos el momento en que la configuración de indicadores de características se cargó completamente.

Para que cuando haga clic en el número de teléfono en los mensajeros haya un diálogo de elección del sistema, debe proporcionar al usuario instrucciones sobre cómo deshacerse de la configuración predeterminada para un "tel: XXXXX". Por ejemplo: "Si solo puede hacer una llamada cuando hace clic en un número, vaya a Configuración de teléfono inteligente → seleccione Teléfono en la lista de aplicaciones → restablezca la configuración a" Abrir por defecto ".


Si deshabilita el componente sobre la marcha, cuando se muestre al usuario este cuadro de diálogo del sistema, no ocurrirá nada malo. El elemento correspondiente desaparecerá instantáneamente de la lista, en nuestro caso "Transferir dinero".

Un comportamiento interesante comenzará si el usuario procesa los enlaces a través de nuestra aplicación de forma predeterminada. Para hacer esto, es suficiente presionar el ítem "Recordar selección" o "Siempre". Si deshabilita el componente, el usuario tendrá la opción de elegir qué aplicación usar, y la primera vez no aparecerá el elemento "Recordar elección". Después de habilitar las funciones, se restaurará todo el flujo y el usuario se transferirá directamente a la aplicación.

Conclusión


La idea de esta función se nos ocurrió hace mucho tiempo, el boleto original se creó en 2017. La idea no ha perdido su relevancia incluso ahora, no pude encontrar una aplicación bancaria con una funcionalidad similar. Lanzamos "transferencias desde el messenger" el 29 de abril, el primer día casi 8,000 usuarios únicos se aprovecharon de ellas. Si los indicadores comerciales en el futuro cercano nos satisfacen, desarrollaremos esta característica aún más.

¿Qué opinas, cuántas intenciones más interesantes de Android esperan pacíficamente su aplicación comercial?

All Articles