He puesto mi aplicación en Google Play Store. Ha sido instalado por muchos de los clientes de mi empresa. Entiendo el mecanismo de actualización de la aplicación.
Los usuarios deben marcar la casilla de verificación de actualización automática en la aplicación PlayStore para cada aplicación que deseen actualizar automáticamente. Sin embargo, algunos usuarios lo han desmarcado o no lo han marcado en primer lugar.
La aplicación que he escrito es para la industria del cuidado y los cuidadores la utilizan para brindar atención domiciliaria. Algunos de nuestros clientes pueden tener 1200 cuidadores. Tendrían que llamar a todos los cuidadores a la oficina para actualizar los teléfonos individualmente. Evidentemente, esto es inaceptable.
¿Existe alguna forma de comprobar mediante programación si hay una versión actualizada de mi aplicación en Play Store?
¿Podría tener un código que se ejecute cada vez que el usuario inicia la aplicación que verifica Play Store? Si hay una versión actualizada, el usuario puede ser dirigido a la tienda de juegos. Esto significará que no es esencial que se verifique la actualización automática.
Gracias por adelantado
Mate
Respuestas:
Actualización 17 de octubre de 2019
https://developer.android.com/guide/app-bundle/in-app-updates
Actualización 24 de abril de 2019:
Android anunció una función que probablemente solucionará este problema. Usando la API de actualizaciones en la aplicación: https://android-developers.googleblog.com/2018/11/unfolding-right-now-at-androiddevsummit.html
Original:
Hasta donde yo sé, no existe una API oficial de Google que admita esto.
Debería considerar obtener un número de versión de una API.
En lugar de conectarse a API o páginas web externas (como Google Play Store). Existe el riesgo de que algo cambie en la API o en la página web, por lo que debe considerar verificar si el código de versión de la aplicación actual está por debajo del número de versión que obtiene de su propia API.
Solo recuerde que si actualiza su aplicación, debe cambiar la versión en su propia API con el número de versión de la aplicación.
Le recomendaría que cree un archivo en su propio sitio web o API, con el número de versión. (Eventualmente, haga un cronjob y haga que la versión se actualice automáticamente, y envíe una notificación cuando algo salga mal)
Debe obtener este valor de su página de Google Play Store (se cambia mientras tanto, ya no funciona):
<div class="content" itemprop="softwareVersion"> x.x.x </div>
Verifique en su aplicación si la versión utilizada en el móvil está por debajo del número de versión que se muestra en su propia API.
Muestra una indicación de que necesita actualizar con una notificación, idealmente.
Cosas que puedes hacer
Número de versión usando su propia API
Pros:
Contras:
Número de versión en la página web Google Play Store
Pros:
Contras:
fuente
Current Version
aparece comoVaries with device
una idea de cómo se puede resolver esto o si hay alguna otra alternativa disponible.Incluya JSoup en el archivo build.gradle de su aplicación:
dependencies { compile 'org.jsoup:jsoup:1.8.3' }
y obtenga la versión actual como:
currentVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
Y ejecuta el siguiente hilo:
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 obtener más detalles, visite: http://revisitingandroid.blogspot.in/2016/12/programmatic-check-play-store-for.html
fuente
getPackageManager().getPackageInfo(getPackageName(), 0).versionName
Podrías usarBuildConfig.VERSION_NAME
:)Firebase Remote Config podría ser una solución posible y confiable por ahora, ya que Google no expuso ninguna API.
Ver la documentación de Firebase Remote Config
Pasos 1.Cree un proyecto de base de fuego y agregue google_play_service.json a su proyecto
2.Crear claves como "android_latest_version_code" y "android_latest_version_name" en firebase console-> Remote Config
3. Código de 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); }
Obtener el nombre y el código de la versión actual
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. Y mantenga la base de fuego "android_latest_version_code" y "android_latest_version_name" actualizados con el nombre y el código de su versión de producción actual.
La configuración remota de Firebase funciona tanto en Android como en iPhone.
fuente
Caused by: com.android.tools.r8.utils.AbortException: Error: null, Cannot fit requested classes in a single dex file (# methods: 68703 > 65536)
. En este caso, debe agregar MultiDex a su aplicación.Puede obtener actual playstore Versión utilizando
JSoup
con algunas modificaciones, como a continuación:@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); }
La respuesta de @Tarun ya no funciona.
fuente
La respuesta de @Tarun funcionaba perfectamente. Pero ahora no, debido a los cambios recientes de Google en el sitio web de Google Play.
Simplemente cambie estos de la respuesta de @Tarun.
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); } }
y no olvide agregar la biblioteca JSoup
dependencies { compile 'org.jsoup:jsoup:1.8.3'}
y en 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(); }
eso es todo .. Gracias a este enlace
fuente
Google ha introducido la API de actualizaciones en la aplicación
Actualmente, la API admite dos flujos:
fuente
Hay una biblioteca AppUpdater . Cómo incluir:
fuente
Procedente de una aplicación híbrida POV. Este es un ejemplo de javascript, tengo un pie de página de Actualización disponible en mi menú principal. Si hay una actualización disponible (es decir, mi número de versión dentro del archivo de configuración es menor que la versión recuperada, mostrar el pie de página) Esto dirigirá al usuario a la aplicación / tienda de juegos, donde el usuario puede hacer clic en el botón actualizar.
También obtengo los datos nuevos (es decir, notas de la versión) y los muestro en un modal al iniciar sesión si es la primera vez en esta versión.
En dispositivo listo, configure la URL de su tienda
if (device.platform == 'iOS') storeURL = 'https://itunes.apple.com/lookup?bundleId=BUNDLEID'; else storeURL = 'https://play.google.com/store/apps/details?id=BUNDLEID';
El método Actualización disponible se puede ejecutar con la frecuencia que desee. El mío se ejecuta cada vez que el usuario navega a la pantalla de inicio.
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); }); } }
Devolución de llamada de iOS: Apple tiene una API, por lo que es muy fácil de obtener
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); } }
Devolución de llamada de Android: PlayStore tiene que raspar, como puede ver, la versión es relativamente fácil de agarrar y, lo que es nuevo, tomo el html en lugar del texto, ya que de esta manera puedo usar su formato (es decir, nuevas líneas, 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); } }
La lógica de la tienda abierta es sencilla, pero para completar
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') }
Asegúrese de que Play Store y App Store estén en la lista blanca:
<access origin="https://itunes.apple.com"/> <access origin="https://play.google.com"/>
fuente
Firebase Remote Config es mejor.
Implementar Remote Config en Android
Agregar la dependencia de Remote Config
compile 'com.google.firebase:firebase-config:9.6.0'
Una vez hecho esto, podemos acceder a la instancia de FirebaseRemoteConfig en toda nuestra aplicación cuando sea necesario:
Recuperando valores de 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");
Obtener valores del lado del 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... } } });
Ahora, una vez cargada la nueva versión en Play Store, tenemos que actualizar el número de versión dentro de Firebase. Ahora, si es una nueva versión, se mostrará el cuadro de diálogo de actualización.
fuente
Dentro del método OnCreate, escriba el código a continuación.
VersionChecker versionChecker = new VersionChecker(); try { latestVersion = versionChecker.execute().get(); Toast.makeText(getBaseContext(), latestVersion , Toast.LENGTH_SHORT).show(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }
esto le da la versión de Play Store de la aplicación.
entonces tienes que verificar la versión de la aplicación como se muestra a continuación
PackageManager manager = getPackageManager(); PackageInfo info = null; try { info = manager.getPackageInfo(getPackageName(), 0); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } assert info != null; version = info.versionName;
después de eso, puede compararlo con la versión de la tienda y configurar sus propias pantallas de actualización
if(version.equals(latestVersion)){ Toast.makeText(getBaseContext(), "No Update" , Toast.LENGTH_SHORT).show(); }else { Toast.makeText(getBaseContext(), "Update" , Toast.LENGTH_SHORT).show(); }
Y agregue VersionChecker.class como se muestra a continuación
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; } }
fuente
Configure un servidor que exponga una URL HTTP que informe la última versión, luego use un AlarmManager para llamar a esa URL y ver si la versión del dispositivo es la misma que la última versión. Si no es así, aparece un mensaje o notificación y envíelos al mercado para actualizar.
Hay algunos ejemplos de código: ¿Cómo permitir que los usuarios busquen la última versión de la aplicación desde dentro de la aplicación?
fuente
Además de usar JSoup, también podemos hacer una coincidencia de patrones para obtener la versión de la aplicación de playStore.
Para hacer coincidir el último patrón de Google Play Store, es decir
<div class="BgcNfc">Current Version</div><span class="htlgb"><div><span class="htlgb">X.X.X</span></div>
, primero tenemos que hacer coincidir la secuencia de nodo anterior y luego de la secuencia anterior obtener el valor de la versión. A continuación se muestra el fragmento de código para el mismo: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; }
Lo resolví a través de esto, ya que esto también funciona para los últimos cambios de Google Play Store. Espero que ayude.
fuente
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; } }
fuente
No hay una API oficial de GooglePlay para hacerlo.
Pero puede usar esta biblioteca no oficial para obtener datos de la versión de la aplicación.
Y, si lo anterior no funciona para usted, siempre puede http conectarse a la página de su aplicación (por ejemplo, https://play.google.com/store/apps/details?id=com.shots.android&hl=en ) y analizar el campo "Versión actual".
fuente
Puedes probar el siguiente código usando Jsoup
String latestVersion = doc.getElementsContainingOwnText("Current Version").parents().first().getAllElements().last().text();
fuente
Google introdujo la API de actualización en la aplicación. Usando eso, podemos pedirle al usuario que actualice la aplicación dentro de la aplicación. Si el usuario acepta, podemos descargar directamente la última aplicación e instalarla sin redirigir a Play Store. para obtener más detalles, consulte el siguiente enlace
enlace1 enlace2
fuente
confirmó solo que el método funciona ahora:
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();
fuente
Google introdujo la función de actualizaciones en la aplicación , ( https://developer.android.com/guide/app-bundle/in-app-updates ) funciona en Lollipop + y le brinda la posibilidad de solicitar al usuario una actualización con un buen diálogo (FLEXIBLE) o con mensaje obligatorio en pantalla completa (INMEDIATO).
Así es como se verá la actualización flexible :
y aquí está el flujo de actualización inmediato :
Puede consultar mi respuesta aquí https://stackoverflow.com/a/56808529/5502121 para obtener el código de muestra completo de implementación de flujos de actualización flexibles e inmediatos . ¡Espero eso ayude!
fuente