如何让用户在应用内查看最新的应用版本?

Posted

技术标签:

【中文标题】如何让用户在应用内查看最新的应用版本?【英文标题】:How to allow users to check for the latest app version from inside the app? 【发布时间】:2011-11-10 00:25:48 【问题描述】:

我想在应用程序中添加一个“检查更新”按钮,以便当有人单击它时,它将显示一个 toast 消息/进度对话框以检查应用程序的版本。

如果发现新版本,应用程序会自动将其下载到手机上,并让用户手动安装更新的应用程序。

或者任何其他方法都可以,只要它可以检查最新版本并通知用户更新。


更新:现在您可以使用https://developer.android.com/guide/playcore/in-app-updates在您的应用中执行此操作

【问题讨论】:

用户如何从设置中做到这一点:android.stackexchange.com/questions/2016/… 【参考方案1】:

您可以使用此 Android 库:https://github.com/danielemaddaluno/Android-Update-Checker。它旨在提供一种可重用的工具来异步检查应用商店中是否存在任何较新发布的应用更新。 它是基于使用 Jsoup (http://jsoup.org/) 来测试是否真的存在新的更新解析 Google Play Store 上的应用页面:

private boolean web_update()
    try        
        String curVersion = applicationContext.getPackageManager().getPackageInfo(BuildConfig.APPLICATION_ID, 0).versionName;   
        String newVersion = curVersion;
        newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID + "&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("div[itemprop=softwareVersion]")
                .first()
                .ownText();
        return (value(curVersion) < value(newVersion)) ? true : false;
     catch (Exception e) 
        e.printStackTrace();
        return false;
    

并且作为“值”函数如下(如果值在 0-99 之间有效):

private long value(String string) 
    string = string.trim();
    if( string.contains( "." )) 
        final int index = string.lastIndexOf( "." );
        return value( string.substring( 0, index ))* 100 + value( string.substring( index + 1 )); 
    
    else 
        return Long.valueOf( string ); 
    

如果您只想验证版本之间的不匹配,您可以更改:

value(curVersion) &lt; value(newVersion)value(curVersion) != value(newVersion)

【讨论】:

代码真的很有帮助。我假设它使用版本代码,但它使用版本名称, 如何获取版本代码? 这段代码给了我 UNKNOWNHOSTEXCEPTION。我不知道为什么 您必须披露隶属关系,因为您似乎编写了这个库【参考方案2】:

如果它是 Market 上的应用程序,则在应用程序启动时,触发 Intent 以希望打开 Market 应用程序,这将导致它检查更新。

否则实现和更新检查器相当容易。这是我的代码(大致):

String response = SendNetworkUpdateAppRequest(); // Your code to do the network request
                                                 // should send the current version
                                                 // to server
if(response.equals("YES")) // Start Intent to download the app user has to manually install it by clicking on the notification
    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("URL TO LATEST APK")));

当然,您应该重写它以在后台线程上执行请求,但您明白了。

如果您喜欢稍微复杂一点的东西,但允许您的应用 自动应用更新见here。

【讨论】:

由于这是java代码response == "YES" 不起作用,你需要使用.equals方法。 为什么不使用布尔值? @Jasoneer : 在 SendNetworkUpdateAppRequest() 函数中写什么?【参考方案3】:

Google 两个月前更新了 Play 商店。 这是现在对我有用的解决方案..

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);

    

别忘了添加 JSoup 库

dependencies 
compile 'org.jsoup:jsoup:1.8.3'

在 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();


就是这样。。 感谢this link

【讨论】:

以上代码在get(); 处抛出异常Java.Lang.RuntimeException:抛出了“Java.Lang.RuntimeException”类型的异常 @PriyankaAgrawal 对不起,妈妈耽搁了,刚才我检查了我的项目,它的工作..你添加了 Jsoup 库吗? 上述问题已通过使用AsyncTask类下的代码解决。但是document.getElementsContainingOwnText("Current Version"); 行返回值当前版本。所以我认为前进没有意义。我正在使用 Xamarin.android。 @PriyankaAgrawal 可能是 mainThread() 问题。感谢您指出,我已经在 Android Studio 中开发了它,不知道 Xamarin ..【参考方案4】:

导航到您的播放页面:

https://play.google.com/store/apps/details?id=com.yourpackage

使用标准的 HTTP GET。 现在下面的 jQuery 会为你找到重要的信息:

当前版本

$("[itemprop='softwareVersion']").text()

新功能

$(".recent-change").each(function()  all += $(this).text() + "\n"; )

现在您可以手动提取这些信息,只需在您的应用中创建一个方法来为您执行这些信息。

public static String[] getAppVersionInfo(String playUrl) 
    htmlCleaner cleaner = new HtmlCleaner();
    CleanerProperties props = cleaner.getProperties();
    props.setAllowHtmlInsideAttributes(true);
    props.setAllowMultiWordAttributes(true);
    props.setRecognizeUnicodeChars(true);
    props.setOmitComments(true);
    try 
        URL url = new URL(playUrl);
        URLConnection conn = url.openConnection();
        TagNode node = cleaner.clean(new InputStreamReader(conn.getInputStream()));
        Object[] new_nodes = node.evaluateXPath("//*[@class='recent-change']");
        Object[] version_nodes = node.evaluateXPath("//*[@itemprop='softwareVersion']");

        String version = "", whatsNew = "";
        for (Object new_node : new_nodes) 
            TagNode info_node = (TagNode) new_node;
            whatsNew += info_node.getAllChildren().get(0).toString().trim()
                    + "\n";
        
        if (version_nodes.length > 0) 
            TagNode ver = (TagNode) version_nodes[0];
            version = ver.getAllChildren().get(0).toString().trim();
        
        return new String[]version, whatsNew;
     catch (IOException | XPatherException e) 
        e.printStackTrace();
        return null;
    

使用HtmlCleaner

【讨论】:

在这里查看问题的答案,我不想承认,但这似乎是唯一可行的解​​决方案,无需花费数小时试图破解 Google Play 的“api”...... 我正在获取版本名称。如何通过上面的代码获取versionCode?​​span> @AjitSharma 调用该方法,并使用返回的数组。 String res[] = getAppVersionInfo("myplayurl"); String version = res[0]; @Kilanny,我正在这样做,但我得到的版本名称与 android 中的版本代码不同。例如。版本代码 1 和版本名称“1.0”。 @AjitSharma 请参阅此以检索代码/名称***.com/a/6593822/4795214【参考方案5】:

APP LEVEL build.gradle

中添加compile 'org.jsoup:jsoup:1.10.2'

&

只需添加以下代码即可。

private class GetVersionCode extends AsyncTask<Void, String, String> 
    @Override
    protected String doInBackground(Void... voids) 

        try 
            newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + SplashActivity.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("div[itemprop=softwareVersion]")
                    .first()
                    .ownText();
            return newVersion;
         catch (Exception e) 
            return newVersion;
        
    

    @Override
    protected void onPostExecute(String onlineVersion) 
        super.onPostExecute(onlineVersion);

        if (!currentVersion.equalsIgnoreCase(onlineVersion)) 
            //show dialog
            new AlertDialog.Builder(context)
                    .setTitle("Updated app available!")
                    .setMessage("Want to update app?")
                    .setPositiveButton("Update", new DialogInterface.OnClickListener() 
                        public void onClick(DialogInterface dialog, int which) 
                            // continue with delete
                            final String appPackageName = getPackageName(); // getPackageName() from Context or Activity object
                            try 
                                Toast.makeText(getApplicationContext(), "App is in BETA version cannot update", Toast.LENGTH_SHORT).show();
                                startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName)));
                             catch (ActivityNotFoundException anfe) 
                                startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
                            
                        
                    )
                    .setNegativeButton("Later", new DialogInterface.OnClickListener() 
                        public void onClick(DialogInterface dialog, int which) 
                            // do nothing
                            dialog.dismiss();
                            new MyAsyncTask().execute();
                        
                    )
                    .setIcon(android.R.drawable.ic_dialog_alert)
                    .show();

        
    

【讨论】:

div[itemprop=softwareVersion] 不再在 Play 商店页面中使用,将不再起作用。 是的,div[itemprop=softwareVersion] 不再在我的应用程序中工作。现在,我如何使用 jsop 库来获取最新版本的应用程序?【参考方案6】:

没有用于此的 API,您不能自动安装它,您可以将它们重定向到它的市场页面,以便他们可以升级。您可以将最新版本保存在 Web 服务器上的文件中,并让应用程序对其进行检查。这是它的一个实现:

http://code.google.com/p/openintents/source/browse/#svn%2Ftrunk%2FUpdateCheckerApp

【讨论】:

供以后参考,应用现在好像是here。【参考方案7】:

我确实使用了in-app updates。这仅适用于运行 Android 5.0(API 级别 21)或更高版本的设备,

【讨论】:

【参考方案8】:

以下是查找当前和最新可用版本的方法:

       try 
            String curVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
            String newVersion = curVersion;
            newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + 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()
                    .select("div.hAyfc:nth-child(4) .IQ1z0d .htlgb")
                    .first()
                    .ownText();
            Log.d("Curr Version" , curVersion);
            Log.d("New Version" , newVersion);

         catch (Exception e) 
            e.printStackTrace();
            return false;
        

【讨论】:

【参考方案9】:

您应该首先查看市场上的应用版本,并将其与设备上的应用版本进行比较。如果它们不同,则可能是可用的更新。在这篇文章中,我写下了获取当前市场版本和设备上当前版本的代码,并将它们放在一起进行比较。我还展示了如何显示更新对话框并将用户重定向到更新页面。请访问此链接:https://***.com/a/33925032/5475941

【讨论】:

【参考方案10】:

我知道 OP 很老了,当时in-app-update 不可用。 但从 API 21 开始,您可以使用应用内更新检查。 您可能需要密切关注一些写得很好的观点here:

【讨论】:

【参考方案11】:

我们可以通过添加这些代码来检查更新:

首先我们需要添加依赖:

实现'org.jsoup:jsoup:1.10.2'

其次,我们需要创建 Java 文件:

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.widget.Toast;

import org.jsoup.Jsoup;

public class CurrentVersion
    private Activity activity;
    public CurrentVersion(Activity activity) 
        this.activity = activity;
    
    //current version of app installed in the device
private String getCurrentVersion()
        PackageManager pm = activity.getPackageManager();
        PackageInfo pInfo = null;
        try 
        pInfo = pm.getPackageInfo(activity.getPackageName(),0);
         catch (PackageManager.NameNotFoundException e1) 
        e1.printStackTrace();
        
        return pInfo.versionName;
        
private class GetLatestVersion extends AsyncTask<String, String, String> 
    private String latestVersion;
    private ProgressDialog progressDialog;
    private boolean manualCheck;
    GetLatestVersion(boolean manualCheck) 
        this.manualCheck = manualCheck;
    
    @Override
    protected void onPostExecute(String s) 
        super.onPostExecute(s);
        if (manualCheck)
        
            if (progressDialog!=null)
            
                if (progressDialog.isShowing())
                
                    progressDialog.dismiss();
                
            
        
        String currentVersion = getCurrentVersion();
        //If the versions are not the same
        if(!currentVersion.equals(latestVersion)&&latestVersion!=null)
            final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
            builder.setTitle("An Update is Available");
            builder.setMessage("Its better to update now");
            builder.setPositiveButton("Update", new DialogInterface.OnClickListener() 
                @Override
                public void onClick(DialogInterface dialog, int which) 
                    //Click button action
                    activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id="+activity.getPackageName())));
                    dialog.dismiss();
                
            );
            builder.setCancelable(false);
            builder.show();
        
        else 
            if (manualCheck) 
                Toast.makeText(activity, "No Update Available", Toast.LENGTH_SHORT).show();
            
        
    
  
    @Override
    protected String doInBackground(String... params) 
        try 
            //It retrieves the latest version by scraping the content of current version from play store at runtime
            latestVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + activity.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 latestVersion;
         catch (Exception e) 
            return latestVersion;
        
    

    public void checkForUpdate(boolean manualCheck)
    
        new GetLatestVersion(manualCheck).execute();
    

第三,我们需要在你想要显示更新的主类中添加这个类:

AppUpdateChecker appUpdateChecker=new AppUpdateChecker(this); 
 appUpdateChecker.checkForUpdate(false);

希望对你有帮助

【讨论】:

【参考方案12】:

使用jsoup HTML解析库@https://jsoup.org/

implementation 'org.jsoup:jsoup:1.13.1'

您可以简单地为此创建一个方法;

private void IsUpdateAvailable() 
    new Thread(new Runnable() 
        @Override
        public void run() 
            String newversion = "no";
            String newversiondot = "no";
            try 
                newversiondot = Jsoup.connect("https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID + "&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("div.hAyfc:nth-child(4) > span:nth-child(2) > div:nth-child(1) > span:nth-child(1)")
                        .first()
                        .ownText();

                newversion = newversiondot.replaceAll("[^0-9]", "");

             catch (IOException e) 
                Log.d("TAG NEW", "run: " + e);
            

            final String finalNewversion = newversion;
            final String finalNewversiondot = newversiondot;
            runOnUiThread(new Runnable() 
                @Override
                public void run() 
                    try 
                        if (Integer.parseInt(finalNewversion) > Integer.parseInt(getApplicationContext().getPackageManager().getPackageInfo(BuildConfig.APPLICATION_ID, 0).versionName.replaceAll("[^0-9]", ""))) 
                            showDialog(UsersActivity.this, "Version: "+finalNewversiondot);
                        
                     catch (PackageManager.NameNotFoundException e) 
                        e.printStackTrace();
                    
                
            );
        
    ).start();

【讨论】:

以上是关于如何让用户在应用内查看最新的应用版本?的主要内容,如果未能解决你的问题,请参考以下文章

强制用户在 Android 中拥有最新的应用版本

如何让 Chrome 应用尽快更新?

检测当前订阅是否在Google Play商店试用版中?

通过应用内计费查看付费应用版本

如何查看 ios 游戏内购消费订单?

OAuth 2.0