Recentemente, tenho trabalhado com aplicativos móveis corporativos. Esses aplicativos não são distribuídos usando qualquer mercado, então eu preciso lidar com o processo de distribuição. Com o Android, você pode compilar seus aplicativos, criar seus arquivos APK e distribuí-los. Você pode enviar os arquivos por e-mail, usar um link para download, enviar o arquivo com bluetooth, ou qualquer outra coisa. Com o iOS é um pouco diferente. Você precisa comprar uma licença da empresa, compilar o aplicativo e distribuir seus arquivos IPA usando padrões da Apple.
OK, mas este artigo não é sobre como distribuir aplicativos fora dos mercados. Este artigo é sobre um grande problema que aparece quando precisamos atualizar nossos aplicativos: como é que o usuário sabe que tem uma nova versão do aplicativo e que precisa fazer o upgrade? Quando trabalhamos dentro da Google Play Store, não precisamos nos preocupar com isso, mas se nós distribuímos nossos aplicativos manualmente precisamos fazer alguma coisa. Podemos enviar notificações push ou e-mails para o usuário para informar sobre a nova versão. Deixe-me mostrar como estou fazendo isso.
Meu problema não é só informar o usuário sobre uma nova versão. Às vezes, eu também preciso garantir que o usuário execute a última versão do app. Imagine um bug crítico (corrigido no último lançamento), mas o usuário não atualiza.
Primeiro, precisamos criar uma página HTML estática, na qual o usuário pode baixar o arquivo APK. Imagine que esta é a URL na qual o usuário pode fazer o download da última versão do app:
http://192.168.1.1:8888/app.apk
Podemos verificar a versão do app em relação ao servidor cada vez que o usuário abre o aplicativo, mas essa verificação significa que a comunicação de rede e é lenta. Precisamos reduzir a comunicação entre o cliente e o servidor para a menor expressão, e somente quando for estritamente necessário. Verificar a versão cada vez pode ser bom para um aplicativo de desktop, mas reduz a experiência do usuário com os aplicativos móveis. Minha abordagem é um pouco diferente. Normalmente usamos a autenticação baseada em tokens dentro de aplicativos móveis. Isso significa que precisamos enviar o nosso token com toda solicitação. Se o enviarmos, podemos também enviar a versão.
Em um app angular, podemos definir a versão e caminho do nosso apk usando um armazenamento valor-chave.
.value('config', {
version: 4,
androidAPK: "http://192.168.1.1:8888/app.apk"
})
Agora precisamos adicionar o parâmetro da versão a cada pedido (que pode criar facilmente um serviço http personalizado para anexar esse parâmetro automaticamente para cada solicitação, na verdade):
$http.get('http://192.168.1.1:8888/api/doSomething', {params: {_version: config.version}})
.success(function (data) {
alert("OK");
})
.error(function (err, status) {
switch (status) {
case 410:
$state.go('upgrade');
break;
}
});
Podemos criar um backend simples para cuidar da versão e gerar uma exceção HTTP (um erro HTTP 410, por exemplo), caso as versões não coincidam. Aqui você pode ver um exemplo Silex simples:
<?php
include __DIR__ . "/../vendor/autoload.php";
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
$app = new Application([
'debug' => true,
'version' => 4,
]);
$app->after(function (Request $request, Response $response) {
$response->headers->set('Access-Control-Allow-Origin', '*');
});
$app->get('/api/doSomething', function (Request $request, Application $app) {
if ($request->get('_version') != $app['version']) {
throw new HttpException(410, "Wrong version");
} else {
return $app->json('hello');
}
});
$app->run();
Como você pode ver, precisamos tomar cuidado com CORS.
Com esse exemplo simples, podemos ver se o usuário tem uma versão errada dentro de cada pedido do servidor. Se as versões não corresponderem, podemos, por exemplo, redirecionar para uma rota específica a fim de informar que o usuário precisa atualizar o aplicativo e fornecer um link para executar a ação.
Com o Android, não podemos criar um link para o arquivo APK. Não funciona. Precisamos fazer o download do APK (usando o plugin FileTransfer) e abrir o arquivo usando o plugin webintent.
O código é muito simples:
var fileTransfer = new FileTransfer();
fileTransfer.download(encodeURI(androidUrl),
"cdvfile://localhost/temporary/app.apk",
function (entry) {
window.plugins.webintent.startActivity({
action: window.plugins.webintent.ACTION_VIEW,
url: entry.toURL(),
type: 'application/vnd.android.package-archive'
}, function () {
}, function () {
alert('Failed to open URL via Android Intent.');
console.log("Failed to open URL via Android Intent. URL: " + entry.fullPath);
});
}, function (error) {
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("upload error code" + error.code);
}, true);
E, basicamente, isso é tudo. Quando o usuário atualizar o app, ele fecha automaticamente e o usuário precisa abri-lo novamente, mas agora com a versão correta.
***
Artigo traduzido pela Redação iMasters, com autorização do autor. Publicado originalmente em http://gonzalo123.com/2014/07/28/upgrading-android-apps-outside-google-play-store-with-angularjs/




