Coloquei meu aplicativo na Google Play Store. Ele foi instalado por muitos clientes da minha empresa. Eu entendo o mecanismo de como o aplicativo deve ser atualizado.
Os usuários devem marcar a caixa de seleção de atualização automática no aplicativo playstore para cada aplicativo que desejam atualizar automaticamente. No entanto, alguns usuários o desmarcaram ou não o verificaram em primeiro lugar.
O aplicativo que escrevi é para a indústria de cuidados e é usado por cuidadores para entregar cuidados domiciliares. Alguns de nossos clientes podem ter 1200 cuidadores. Eles teriam que chamar todos os cuidadores no escritório para atualizar os telefones individualmente. Isso é obviamente inaceitável.
Existe uma maneira de verificar programaticamente se há uma versão atualizada do meu aplicativo na Play Store?
Posso ter um código que é executado sempre que o usuário inicia o aplicativo que verifica a Play Store? Se houver uma versão atualizada, o usuário pode ser direcionado para a playstore. Isso significa que não é essencial verificar a atualização automática.
Respostas:
Atualização 17 de outubro de 2019
https://developer.android.com/guide/app-bundle/in-app-updates
Atualização em 24 de abril de 2019:
O Android anunciou um recurso que provavelmente resolverá esse problema. Usando a API de atualizações no aplicativo: https://android-developers.googleblog.com/2018/11/unfolding-right-now-at-androiddevsummit.html
Original:
Até onde eu sei, não existe uma API oficial do Google que suporte isso.
Você deve considerar obter um número de versão de uma API.
Em vez de se conectar a APIs externas ou páginas da web (como Google Play Store). Existe o risco de que algo mude na API ou na página da web, então você deve considerar verificar se o código da versão do aplicativo atual está abaixo do número da versão que você obteve de sua própria API.
Lembre-se de que, se você atualizar seu aplicativo, será necessário alterar a versão em sua própria API com o número da versão do aplicativo.
Eu recomendo que você faça um arquivo em seu próprio site ou API, com o número da versão. (Eventualmente, faça um cronjob e torne a atualização da versão automática, e envie uma notificação quando algo der errado)
Você deve obter este valor em sua página da Google Play Store (foi alterado entretanto, não funciona mais):
<div class="content" itemprop="softwareVersion"> x.x.x </div>
Verifique em seu aplicativo se a versão usada no celular está abaixo do número da versão mostrado em sua própria API.
Mostrar indicação de que ele precisa atualizar com uma notificação, de preferência.
Coisas que você pode fazer
Número da versão usando sua própria API
Prós:
Contras:
Número da versão na página da web Google Play Store
Prós:
Contras:
fonte
Current Version
listado comoVaries with device
alguma idéia de como isso pode ser resolvido ou se qualquer outra alternativa está disponível ??Inclua JSoup em seu arquivo build.gradle de aplicativos:
dependencies { compile 'org.jsoup:jsoup:1.8.3' }
e obter a versão atual como:
currentVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
E execute o seguinte thread:
private class GetVersionCode extends AsyncTask<Void, String, String> { @Override protected String doInBackground(Void... voids) { String newVersion = null; try { newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + MainActivity.this.getPackageName() + "&hl=it") .timeout(30000) .userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6") .referrer("http://www.google.com") .get() .select(".hAyfc .htlgb") .get(7) .ownText(); return newVersion; } catch (Exception e) { return newVersion; } } @Override protected void onPostExecute(String onlineVersion) { super.onPostExecute(onlineVersion); Log.d("update", "Current version " + currentVersion + "playstore version " + onlineVersion); if (onlineVersion != null && !onlineVersion.isEmpty()) { if (Float.valueOf(currentVersion) < Float.valueOf(onlineVersion)) { //show dialog } } }
Para obter mais detalhes, visite: http://revisitingandroid.blogspot.in/2016/12/programmatically-check-play-store-for.html
fonte
getPackageManager().getPackageInfo(getPackageName(), 0).versionName
Você pode simplesmente usarBuildConfig.VERSION_NAME
:)O Firebase remote config pode ser uma solução possível e confiável por enquanto, já que o Google não expôs nenhuma API a ele.
Verifique os documentos do Firebase Remote Config
Etapas 1.Crie um projeto firebase e adicione google_play_service.json ao seu projeto
2. Crie chaves como "android_latest_version_code" e "android_latest_version_name" no console do Firebase-> Configuração remota
3. Código Android
public void initializeFirebase() { if (FirebaseApp.getApps(mContext).isEmpty()) { FirebaseApp.initializeApp(mContext, FirebaseOptions.fromResource(mContext)); } final FirebaseRemoteConfig config = FirebaseRemoteConfig.getInstance(); FirebaseRemoteConfigSettings configSettings = new FirebaseRemoteConfigSettings.Builder() .setDeveloperModeEnabled(BuildConfig.DEBUG) .build(); config.setConfigSettings(configSettings); }
Obtenha o nome e o código da versão atual
int playStoreVersionCode = FirebaseRemoteConfig.getInstance().getString( "android_latest_version_code"); PackageInfo pInfo = this.getPackageManager().getPackageInfo(getPackageName(), 0); int currentAppVersionCode = pInfo.versionCode; if(playStoreVersionCode>currentAppVersionCode){ //Show update popup or whatever best for you }
4. E mantenha o firebase "android_latest_version_code" e "android_latest_version_name" atualizados com o nome e o código da versão de produção atual.
A configuração remota do Firebase funciona no Android e no iPhone.
fonte
Caused by: com.android.tools.r8.utils.AbortException: Error: null, Cannot fit requested classes in a single dex file (# methods: 68703 > 65536)
. Nesse caso, você deve adicionar MultiDex ao seu aplicativo.Você pode obter a versão atual do Playstore usando
JSoup
algumas modificações como a seguir:@Override protected String doInBackground(Void... voids) { String newVersion = null; try { newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + MainActivity.this.getPackageName() + "&hl=it") .timeout(30000) .userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6") .referrer("http://www.google.com") .get() .select(".hAyfc .htlgb") .get(7) .ownText(); return newVersion; } catch (Exception e) { return newVersion; } } @Override protected void onPostExecute(String onlineVersion) { super.onPostExecute(onlineVersion); Log.d("update", "playstore version " + onlineVersion); }
resposta de @Tarun não está mais funcionando.
fonte
A resposta do @Tarun estava funcionando perfeitamente. Mas agora não está, devido às mudanças recentes do Google no site do Google Play.
Basta mudar isso de @Tarun answer ..
class GetVersionCode extends AsyncTask<Void, String, String> { @Override protected String doInBackground(Void... voids) { String newVersion = null; try { Document document = Jsoup.connect("https://play.google.com/store/apps/details?id=" + MainActivity.this.getPackageName() + "&hl=en") .timeout(30000) .userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6") .referrer("http://www.google.com") .get(); if (document != null) { Elements element = document.getElementsContainingOwnText("Current Version"); for (Element ele : element) { if (ele.siblingElements() != null) { Elements sibElemets = ele.siblingElements(); for (Element sibElemet : sibElemets) { newVersion = sibElemet.text(); } } } } } catch (IOException e) { e.printStackTrace(); } return newVersion; } @Override protected void onPostExecute(String onlineVersion) { super.onPostExecute(onlineVersion); if (onlineVersion != null && !onlineVersion.isEmpty()) { if (Float.valueOf(currentVersion) < Float.valueOf(onlineVersion)) { //show anything } } Log.d("update", "Current version " + currentVersion + "playstore version " + onlineVersion); } }
e não se esqueça de adicionar a biblioteca JSoup
dependencies { compile 'org.jsoup:jsoup:1.8.3'}
e no Oncreate ()
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); String currentVersion; try { currentVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } new GetVersionCode().execute(); }
é isso .. Graças a este link
fonte
O Google introduziu API de atualizações no aplicativo
A API atualmente oferece suporte a dois fluxos:
fonte
Vindo de um POV de aplicação híbrido. Este é um exemplo de javascript, eu tenho um rodapé de atualização disponível no meu menu principal. Se uma atualização estiver disponível (ou seja, meu número de versão no arquivo de configuração é menor do que a versão recuperada, exiba o rodapé) Isso direcionará o usuário para a app / play store, onde o usuário pode clicar no botão atualizar.
Eu também pego os novos dados (ou seja, notas de versão) e os exibo em um modal no login se for a primeira vez nesta versão.
No dispositivo pronto, defina o URL da sua loja
if (device.platform == 'iOS') storeURL = 'https://itunes.apple.com/lookup?bundleId=BUNDLEID'; else storeURL = 'https://play.google.com/store/apps/details?id=BUNDLEID';
O método Update Available pode ser executado com a freqüência que você desejar. O meu é executado sempre que o usuário navega para a tela inicial.
function isUpdateAvailable() { if (device.platform == 'iOS') { $.ajax(storeURL, { type: "GET", cache: false, dataType: 'json' }).done(function (data) { isUpdateAvailable_iOS(data.results[0]); }).fail(function (jqXHR, textStatus, errorThrown) { commsErrorHandler(jqXHR, textStatus, false); }); } else { $.ajax(storeURL, { type: "GET", cache: false }).done(function (data) { isUpdateAvailable_Android(data); }).fail(function (jqXHR, textStatus, errorThrown) { commsErrorHandler(jqXHR, textStatus, false); }); } }
Retorno de chamada do iOS: a Apple tem uma API, muito fácil de obter
function isUpdateAvailable_iOS (data) { var storeVersion = data.version; var releaseNotes = data.releaseNotes; // Check store Version Against My App Version ('1.14.3' -> 1143) var _storeV = parseInt(storeVersion.replace(/\./g, '')); var _appV = parseInt(appVersion.substring(1).replace(/\./g, '')); $('#ft-main-menu-btn').off(); if (_storeV > _appV) { // Update Available $('#ft-main-menu-btn').text('Update Available'); $('#ft-main-menu-btn').click(function () { openStore(); }); } else { $('#ft-main-menu-btn').html(' '); // Release Notes settings.updateReleaseNotes('v' + storeVersion, releaseNotes); } }
Android Callback: PlayStore você tem que raspar, como você pode ver, a versão é relativamente fácil de pegar e o que há de novo eu pego o html em vez do texto, pois assim posso usar a formatação (ou seja, novas linhas, etc.)
function isUpdateAvailable_Android(data) { var html = $(data); var storeVersion = html.find('div[itemprop=softwareVersion]').text().trim(); var releaseNotes = html.find('.whatsnew')[0].innerHTML; // Check store Version Against My App Version ('1.14.3' -> 1143) var _storeV = parseInt(storeVersion.replace(/\./g, '')); var _appV = parseInt(appVersion.substring(1).replace(/\./g, '')); $('#ft-main-menu-btn').off(); if (_storeV > _appV) { // Update Available $('#ft-main-menu-btn').text('Update Available'); $('#ft-main-menu-btn').click(function () { openStore(); }); } else { $('#ft-main-menu-btn').html(' '); // Release Notes settings.updateReleaseNotes('v' + storeVersion, releaseNotes); } }
A lógica da loja aberta é direta, mas para integridade
function openStore() { var url = 'https://itunes.apple.com/us/app/appname/idUniqueID'; if (device.platform != 'iOS') url = 'https://play.google.com/store/apps/details?id=appid' window.open(url, '_system') }
Certifique-se de que a Play Store e a App Store estejam na lista de permissões:
<access origin="https://itunes.apple.com"/> <access origin="https://play.google.com"/>
fonte
Há biblioteca AppUpdater . Como incluir:
fonte
O Firebase Remote config é melhor.
Implementando Configuração Remota no Android
Adicionar a dependência do Configuração remota
compile 'com.google.firebase:firebase-config:9.6.0'
Uma vez feito isso, podemos acessar a instância FirebaseRemoteConfig em todo o nosso aplicativo, quando necessário:
Recuperando valores do Remote config
boolean someBoolean = firebaseRemoteConfig.getBoolean("some_boolean"); byte[] someArray = firebaseRemoteConfig.getByteArray("some_array"); double someDouble = firebaseRemoteConfig.getDouble("some_double"); long someLong = firebaseRemoteConfig.getLong("some_long"); String appVersion = firebaseRemoteConfig.getString("appVersion");
Buscar valores do lado do servidor
firebaseRemoteConfig.fetch(cacheExpiration) .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()) { mFirebaseRemoteConfig.activateFetched(); // We got our config, let's do something with it! if(appVersion < CurrentVersion){ //show update dialog } } else { // Looks like there was a problem getting the config... } } });
Agora, depois de fazer o upload da nova versão para o playstore, temos que atualizar o número da versão dentro do firebase. Agora, se for uma nova versão, a janela de atualização será exibida
fonte
Dentro do método OnCreate escreva o código abaixo.
VersionChecker versionChecker = new VersionChecker(); try { latestVersion = versionChecker.execute().get(); Toast.makeText(getBaseContext(), latestVersion , Toast.LENGTH_SHORT).show(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }
isso dá a você a versão da Play Store do aplicativo.
então você tem que verificar a versão do aplicativo conforme abaixo
PackageManager manager = getPackageManager(); PackageInfo info = null; try { info = manager.getPackageInfo(getPackageName(), 0); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } assert info != null; version = info.versionName;
depois disso, você pode compará-lo com a versão da loja e configurar suas próprias telas de atualização
if(version.equals(latestVersion)){ Toast.makeText(getBaseContext(), "No Update" , Toast.LENGTH_SHORT).show(); }else { Toast.makeText(getBaseContext(), "Update" , Toast.LENGTH_SHORT).show(); }
E adicione VersionChecker.class como abaixo
public class VersionChecker extends AsyncTask<String, String, String> { private String newVersion; @Override protected String doInBackground(String... params) { try { newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + "package name" + "&hl=en") .timeout(30000) .userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6") .referrer("http://www.google.com") .get() .select(".hAyfc .htlgb") .get(7) .ownText(); } catch (IOException e) { e.printStackTrace(); } return newVersion; } }
fonte
Configure um servidor que exponha um url HTTP que relata a versão mais recente e, em seguida, use um AlarmManager para chamar esse URL e ver se a versão no dispositivo é igual à versão mais recente. Se não for, abra uma mensagem ou notificação e envie ao mercado para atualização.
Existem alguns exemplos de código: Como permitir que os usuários verifiquem a versão mais recente do aplicativo de dentro do aplicativo?
fonte
Além de usar JSoup, podemos alternativamente fazer correspondência de padrões para obter a versão do aplicativo da playStore.
Para corresponder ao padrão mais recente do google playstore, ou seja
<div class="BgcNfc">Current Version</div><span class="htlgb"><div><span class="htlgb">X.X.X</span></div>
, primeiro temos que corresponder à sequência de nós acima e, em seguida, obter o valor da versão da sequência acima. Abaixo está o snippet de código para o mesmo:private String getAppVersion(String patternString, String inputString) { try{ //Create a pattern Pattern pattern = Pattern.compile(patternString); if (null == pattern) { return null; } //Match the pattern string in provided string Matcher matcher = pattern.matcher(inputString); if (null != matcher && matcher.find()) { return matcher.group(1); } }catch (PatternSyntaxException ex) { ex.printStackTrace(); } return null; } private String getPlayStoreAppVersion(String appUrlString) { final String currentVersion_PatternSeq = "<div[^>]*?>Current\\sVersion</div><span[^>]*?>(.*?)><div[^>]*?>(.*?)><span[^>]*?>(.*?)</span>"; final String appVersion_PatternSeq = "htlgb\">([^<]*)</s"; String playStoreAppVersion = null; BufferedReader inReader = null; URLConnection uc = null; StringBuilder urlData = new StringBuilder(); final URL url = new URL(appUrlString); uc = url.openConnection(); if(uc == null) { return null; } uc.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6"); inReader = new BufferedReader(new InputStreamReader(uc.getInputStream())); if (null != inReader) { String str = ""; while ((str = inReader.readLine()) != null) { urlData.append(str); } } // Get the current version pattern sequence String versionString = getAppVersion (currentVersion_PatternSeq, urlData.toString()); if(null == versionString){ return null; }else{ // get version from "htlgb">X.X.X</span> playStoreAppVersion = getAppVersion (appVersion_PatternSeq, versionString); } return playStoreAppVersion; }
Resolvi o problema com isso, pois isso também funciona para as últimas alterações da Playstore do Google. Espero que ajude.
fonte
private void CheckUPdate() { VersionChecker versionChecker = new VersionChecker(); try { String appVersionName = BuildConfig.VERSION_NAME; String mLatestVersionName = versionChecker.execute().get(); if(!appVersionName.equals(mLatestVersionName)){ AlertDialog.Builder alertDialog = new AlertDialog.Builder(Activity.this); alertDialog.setTitle("Please update your app"); alertDialog.setMessage("This app version is no longer supported. Please update your app from the Play Store."); alertDialog.setPositiveButton("UPDATE NOW", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { final String appPackageName = getPackageName(); try { startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName))); } catch (android.content.ActivityNotFoundException anfe) { startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName))); } } }); alertDialog.show(); } } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } @SuppressLint("StaticFieldLeak") public class VersionChecker extends AsyncTask<String, String, String> { private String newVersion; @Override protected String doInBackground(String... params) { try { newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id="+getPackageName()) .timeout(30000) .userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6") .referrer("http://www.google.com") .get() .select(".hAyfc .htlgb") .get(7) .ownText(); } catch (IOException e) { e.printStackTrace(); } return newVersion; } }
fonte
Não existe uma API oficial do GooglePlay para fazer isso.
Mas você pode usar esta biblioteca não oficial para obter dados da versão do aplicativo.
E, se o acima não funcionar para você, você sempre pode conectar-se http à página do seu aplicativo (por exemplo, https://play.google.com/store/apps/details?id=com.shots.android&hl=en ) e analise o campo "Versão atual".
fonte
Você pode tentar seguir o código usando Jsoup
String latestVersion = doc.getElementsContainingOwnText("Current Version").parents().first().getAllElements().last().text();
fonte
O Google introduziu a API de atualização no aplicativo. Usando isso, podemos pedir ao usuário para atualizar o aplicativo dentro do aplicativo. se o usuário aceitar, podemos baixar diretamente o aplicativo mais recente e instalar sem redirecionar para a playstore. para mais detalhes, consulte o link abaixo
link1 link2
fonte
O Google introduziu o recurso de atualizações no aplicativo ( https://developer.android.com/guide/app-bundle/in-app-updates ) que funciona no Lollipop + e oferece a capacidade de solicitar ao usuário uma atualização com um bom diálogo (FLEXÍVEL) ou com mensagem de tela cheia obrigatória (IMEDIATA).
Esta é a aparência da atualização flexível :
e aqui está o fluxo de atualização imediato :
Você pode verificar minha resposta aqui https://stackoverflow.com/a/56808529/5502121 para obter o código de amostra completo de implementação de fluxos de atualização flexíveis e imediatos . Espero que ajude!
fonte
confirmou apenas que o método funciona agora:
newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + AcMainPage.this.getPackageName() + "&hl=it") .timeout(30000) .userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6") .referrer("http://www.google.com") .get() .select(".hAyfc .htlgb") .get(5) .ownText();
fonte