【问题标题】:How to force app uninstall in order to update?如何强制应用卸载以更新?
【发布时间】:2012-11-24 23:47:12
【问题描述】:


我犯了一个错误,显然只能通过卸载然后重新安装我的应用程序来解决。

我向用户发送了一条消息,但似乎没有人卸载它。

AFAIK,如果我更改证书文件,Play 商店不会让我上传应用程序,并且 显然我不想上传新应用。

有没有办法强制卸载才能更新?

谢谢!

【问题讨论】:

  • 出了什么错误,为什么你不能用更新的版本来修复它?
  • 我在清单中添加了SharedUserId,但在上传到市场之前忘记将其删除。它会导致 SharedPreferences 未被保存
  • @Android Joker,你确定根本原因是你认为的那样吗?有没有可能不是 SharedUserId 问题?
  • 我不明白。新版本的代码中无法修复的卸载有什么作用?
  • @full.stack.ex 是的,我确定。我记得我在某处读到它可能会导致问题,而且,当您设置 SharedUserId 应该用于在多个应用程序之间共享首选项时,因此它连接到 SharedPreferences ...和 ​​Squonk,我不知道...它似乎工作

标签: java android certificate google-play code-signing


【解决方案1】:

我不知道这是否可以帮助你,但我遇到了同样的问题。我的解决方案是每次用户打开它时检查应用程序版本并将其与存储在 apache 服务器上的版本代码(在 checkversion.php 文件中)进行比较。 如果版本不匹配,我会显示一个不可取消的对话框,要求用户去市场下载更新。

这是一个示例(请记住,我使用Volley library 来处理连接):

    public class UpdateManager {

        private Activity ac;
        private HashMap<String,String> params;

        public UpdateManager(Activity ac) {
            this.ac = ac;
        }

        public void checkForUpdates() {
            Log.d("UpdateManager","checkForUpdates() - Started...");

            params = new HashMap<String,String>();
            params.put("request","checkforupdates");
            try {
                params.put("versioncode", String.valueOf(ac.getPackageManager().getPackageInfo(ac.getPackageName(), 0).versionCode));
            } catch (NameNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            if (Helper.isInternetAvailable(ac)) { //this is a class i made to check internet connection availability
                checkAppVersion();
            } else { Log.d("UpdateManager","CheckForUpdates(): Impossible to update version due to lack of connection"); }
        }

        private void checkAppVersion() {
            Log.d("UpdateManager","checkAppVersion() - Request started...");

            JsonObjectRequest req = new JsonObjectRequest("http://yourserver/checkappversion.php", new JSONObject(params),
                    new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    if (response != null && response.has("result")) {
                        try {
                            Log.d("UpdateManager","checkAppVersion() - Request finished - Response: "+response.getString("result"));
                            if (response.getString("result").matches("updaterequested")) { //Update requested. Show the relative dialog
                                Log.d("UpdateManager","Update requested");

                                askUserForUpdate();
                            }
                            else if (response.getString("result").matches("current")) { //Same version. Do nothing 
                                Log.d("UpdateManager","Version is up to date");
                            }
                            else if (response.getString("result").matches("error")) { //You can return an error message if error occurred on server
                                Log.d("UpdateManager","checkappversion Error - "+response.getString("error"));
                            }

                            VolleyLog.v("Response:%n %s", response.toString(4));
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.e("UpdateManager","Volley Error - "+error.getMessage());
                }
            });
            req.setRetryPolicy(new DefaultRetryPolicy(60000,0,DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
            ConnectionController.getInstance().addToRequestQueue(req);
        }

        public void askUserForUpdate() {
            final Dialog diag = new Dialog(ac);
            diag.requestWindowFeature(Window.FEATURE_NO_TITLE);
            diag.setContentView(R.layout.updatemanager_requestupdate_dialog);
            diag.setCancelable(false);
            diag.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
            TextView t = (TextView)diag.findViewById(R.id.requestupdate_dialog_main_text);
            ImageView im_ok = (ImageView)diag.findViewById(R.id.requestupdate_dialog_ok);
            ImageView im_canc = (ImageView)diag.findViewById(R.id.requestupdate_dialog_canc);
            t.setText(ac.getResources().getString(R.string.update_manager_askuserforupdate));
            im_canc.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    diag.dismiss();
                    ac.finish();
                }
            });
            im_ok.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.setData(Uri.parse("market://details?id="+ac.getPackageName()));
                    diag.dismiss();
                    ac.startActivity(intent);
                    ac.finish();
                }
            });
            diag.show();
        }
    }

然后您可以在您的主要活动(或登录活动)像这样开始时使用它:

     UpdateManager updateManager = new UpdateManager(MainActivity.this); //i assume MainActicity as the calling activity
     updateManager.checkForUpdates();

显然,这必须在应用程序代码中实现,因此,第一次,您必须仅依靠用户手动升级它。但是,如果您以后遇到同样的问题,这会有所帮助。

这是我个人代码的摘录,因此您必须根据需要重新排列它。希望这对某人有所帮助。

【讨论】:

    【解决方案2】:

    用户应该能够转到Settings &gt; Applications &gt; Manage Applications 并选择要删除的应用程序。我从未见过无法以这种方式删除应用程序的情况,除非是需要根设备才能删除的内置应用程序。

    【讨论】:

    • 我说要自动删除
    • 哦,在那种情况下,你就不走运了。只有使用 Google 自己的签名密钥签名的应用程序才能安装和卸载应用程序。您所能做的就是将更新版本放在安卓市场上,并希望用户检查应用程序的“自动升级”功能。或者让他们使用有根手机。
    【解决方案3】:

    没有用于远程强制卸载的 killswitch(那将是一场安全噩梦)。您可以做的是在 Google Play 上发布一个固定版本,等待用户升级。

    【讨论】:

      猜你喜欢
      • 2013-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-09
      • 2010-09-18
      • 2014-04-10
      • 2016-01-15
      相关资源
      最近更新 更多