Transferência rápida de mensageiros instantâneos - QIWI Android Wallet

Olá!

Meu nome é Alex, sou desenvolvedor da QIWI.

TL; DR

Como transferir do messenger diretamente para a forma de pagamento:

  1. No manifesto, colocamos uma Atividade c vazia do intent-filter tipo ACTION_VIEWe ACTION_DIALcom o esquema "tel".
  2. Na atividade, transferimos para a forma de pagamento através do link de profundidade existente, enriquecendo-a com dados do original intent- “tel:XXXXX”



Lucro : ao clicar no número de telefone destacado no messenger, uma pessoa entra no formulário de transferência com o campo preenchido do destinatário da transferência.
Bônus : mostrarei como ativar esse recurso de maneira bonita, sem poder alterar a lista de filtros de intenção no manifesto em tempo de execução.

Pelo que?


Suponha que uma pessoa tenha a tarefa de transferir dinheiro para um presente de aniversário coletivo. A parte receptora pode escolher opções convenientes de transferência: transferência para um cartão, carteira eletrônica, transferência direta para uma conta ou outra coisa. Muitas empresas que prestam serviços de tradução aceitam um número de telefone como identificador de usuário secundário ou primário. Para evitar transferências incorretas, o destinatário pode transmitir seu número de telefone por mensagem de texto: email, mensagem instantânea ou SMS. A mensagem também indica o sistema necessário para a tradução.

Um caminho típico do usuário é copiar o número de telefone do messenger e colá-lo no aplicativo para tradução. Dessa maneira, é possível alternar entre aplicativos, acessar a área de trabalho e até pesquisar entre os aplicativos instalados do provedor de serviços de tradução. É possível encurtar esse caminho reduzindo o número de etapas? Existe uma opção.

Teoria


Muitos mensageiros instantâneos em smartphones reconhecem números de telefone e os destacam na forma de um hiperlink. Por padrão, há um aplicativo para processar esse tipo de link em qualquer dispositivo móvel com um módulo GSM. É geralmente chamado de "Telefone". No Android, a capacidade de processar um número de telefone compartilhado é declarada no AndroidManifest. Exemplos de aplicações: "Telefone", Viber, Skype. Se você interceptar esses eventos, poderá fornecer imediatamente ao usuário uma lista de possíveis ações com um número de telefone. No nosso caso, esta será uma oferta de transferência através da QIWI Wallet.

Estamos interessados ​​em eventos com tipos Intent.ACTION_VIEW, Intent.ACTION_DIAL, Intent.ACTION_CALLcom o esquema tel. EventoIntent.ACTION_CALLPossui restrições à política de segurança do Android e sua inicialização requer permissão do usuário a partir da versão do Marshmallow, inclusive. De acordo com os nossos mensageiros de pesquisa usando mais geral Intent.ACTION_VIEW, Intent.ACTION_DIAL.

Existem vários tipos semelhantes especificamente para telefones de emergência, mas esse claramente não é o nosso caso. O corpo da intenção tem a forma "tel: 12345678". Esse tipo de intenção não pode ser processado android.content.UriMatcher, porque o host está ausente aqui. A maneira mais fácil de lidar com esse tipo de Uri é perguntar schemeSpecificPart e verificar se é um número de telefone válido.

A lista de filtros de intenção deve ser especificada no AndroidManifest, é impossível alterá-la durante a execução do aplicativo. Como desativar remotamente esse recurso? A primeira opção é rejeitar a solicitação do usuário no momento em que a Atividade foi aberta - com uma mensagem ou simplesmente fechar o aplicativo. Do nosso ponto de vista, esse não é o melhor UX, pois interromperemos o fluxo do usuário no meio. É melhor se não deixarmos uma pessoa escolher nosso aplicativo, se a funcionalidade estiver desativada. É mais fácil desativar o componente com a lista de filtros de intenção em tempo de execução, isso não dará ao usuário promessas falsas na interface do sistema. Ao usar o PackageManager, observe que a verificação da inclusão de componentes não é muito confiável. É preferível enabled forçar o sinalizador de um componente sem depender de seu estado atual usando valoresCOMPONENT_ENABLED_STATE_ENABLED e COMPONENT_ENABLED_STATE_DISABLED. As alterações feitas no PackageManager são salvas até que o aplicativo seja desinstalado do dispositivo.

Prática


Para desativar o recurso, precisamos de um componente Android para desativá-lo.
A maneira mais fácil é usar uma atividade vazia, o que faremos. Se você decidir usar o Serviço com um conjunto semelhante de filtros de intenção, consulte os guias do Google, que dizem especificamente "não declare filtros de intenção para seus serviços" . Observe que, por padrão, o componente está desativado: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>

A atividade em si simplesmente redireciona para a forma de pagamento por meio 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()
    }
}

O sinalizador android: enabled pode ser controlado por essa classe 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
        }

    }
}

O método "isMessengerP2PEnabled" não é usado aqui para verificar o estado atual do componente, pois durante o teste, ele produziu resultados não confiáveis. Se você decidir usá-lo, verifique cuidadosamente sua operação nas condições da lógica de negócios assíncrona e ao fazer o download do aplicativo.

O tempo para alterar o valor do sinalizador enabled não é muito importante, escolhemos o momento em que a configuração dos sinalizadores de recursos estava totalmente carregada.

Para que, quando você clicar no número de telefone nos mensageiros, haja uma caixa de diálogo do sistema, forneça ao usuário instruções sobre como desativar as configurações padrão da intenção - um “tel: XXXXX”. Por exemplo: “Se você só puder fazer uma chamada quando clicar em um número, vá para Configurações do Smartphone → selecione Telefone na lista de aplicativos → redefina a configuração para“ Abrir por padrão ”.


Se você desabilitar o componente em movimento, quando o usuário exibir esta caixa de diálogo do sistema, nada de ruim acontecerá. O item correspondente desaparecerá instantaneamente da lista, no nosso caso "Transferir dinheiro".

Um comportamento interessante começará se o usuário processar os links por meio de nosso aplicativo por padrão. Para fazer isso, basta pressionar o item “Lembrar seleção” ou “Sempre”. Se você desabilitar o componente, o usuário poderá escolher qual aplicativo usar e, na primeira inicialização, não haverá um item "Lembrar seleção". Depois de ativar os recursos, todo o fluxo será restaurado, o usuário será transferido para o aplicativo diretamente.

Conclusão


A ideia desse recurso veio até nós há muito tempo, o ticket original foi criado em 2017. A idéia ainda não perdeu sua relevância, não consegui encontrar um aplicativo bancário com funcionalidade semelhante. Lançamos “transferências do messenger” em 29 de abril. No primeiro dia, quase 8.000 usuários únicos se aproveitaram deles. Se os indicadores de negócios em um futuro próximo nos satisfizerem, desenvolveremos esse recurso ainda mais.

O que você acha, quantas intenções mais interessantes do Android aguardam pacificamente pelo aplicativo de negócios?

All Articles