【问题标题】:Automatically install Android application自动安装安卓应用
【发布时间】:2012-12-12 09:11:03
【问题描述】:

我需要将各种企业应用程序部署和更新到分配给有限数量用户的 Android 设备。

这些应用程序不应在 Google Play 上发布,但必须通过单独的渠道分发。

我需要做的是一个“企业包管理器”应用程序来自动检查新的应用程序/更新并自动触发安装新的或更新的 APK,而无需事先征得用户同意。

我知道,从设计上讲,Android 不允许第三方应用程序与已安装的应用程序进行交互。我也知道root手机没有这个问题,因为你可以将任何APK注入设备。

  • 如果我用“企业包管理器”作为系统应用程序安装,但没有su 二进制文件(它仍然是企业电话......),制作一个ROM(甚至基于CWM),该程序是否能够安装自动添加新应用?
  • 如何在不征得同意的情况下安装应用程序?我的意思是,如果需要,我需要一个基本的代码示例和权限
  • 无论如何,系统应用程序是否以 root 用户身份运行?我记得是这样的

【问题讨论】:

    标签: android package-managers


    【解决方案1】:

    如果您想检查服务器上某处的应用程序,您必须每 24 小时检查一次更新,如果有任何可用更新,那么它将导航到您的更新版本构建将执行的异步任务开始安装

    public void checkforUpdate() {
    
            /* Get Last Update Time from Preferences */
            SharedPreferences prefs = getPreferences(0);
            lastUpdateTime = prefs.getLong("lastUpdateTime", 0);
            if ((lastUpdateTime + CommonString.timeCheckDuration) < System.currentTimeMillis() && System.currentTimeMillis()>lastUpdateTime) {
                // Asynch task
                new VersionCheckTask().execute();
            }
            else{
                // do nothing
            }
        }
    

    现在它将导航到:

    private class VersionCheckTask extends AsyncTask<Void, Void, Void> {
            ProgressDialog progressDialog;
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                try {
                    progressDialog = new ProgressDialog(Login.this, android.R.style.Theme_Holo_Light_Dialog);
                    //progressDialog.setTitle("AppName");
                    progressDialog.setMessage("Checking for updates...");
                    progressDialog.setCancelable(false);
                    progressDialog.setIndeterminate(true);
                    progressDialog.show();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            protected Void doInBackground(Void... params) {
                /**
                 *  Simulates a background job.
                 */
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
    
                HashMap<String, String> map = new HashMap<String, String>();
                map.put("build",CommonString.buildVersion);
                map.put("en", CommonString.en);
    
                responce = CommonFunction.PostRequest("updateCheck", map);
                return null;
            }
    
            @Override
            protected void onPostExecute(Void result) {
                if (progressDialog != null && progressDialog.isShowing())
                    progressDialog.dismiss();
                if(!CommonFunction.isNetworkAvailable()){
                    Toast.makeText(ClaimColonyApplication.getAppContext(), CommonString.NO_NETWORK, Toast.LENGTH_SHORT).show();
                    return;
                }
                ParseUpdateResponse(responce);
                if(rCodeUpdate == 100 && ApkLink.length() >0){
                    new AlertDialog.Builder(Login.this,android.R.style.Theme_Holo_Light_Dialog)
                    .setIcon(R.drawable.ic_launcher)
                    .setTitle("Update Available")
                    .setMessage(""+UpdateMessage)
                    .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                             //User clicked OK so do some stuff 
                            new VersionCheckTaskDialog().execute();
                        }
                    })
                    .setNegativeButton("No", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                             //User clicked Cancel 
                            finish();
                        }
                    })
                    .show();
                }else{
                    if(rCodeUpdate == 100){
                        lastUpdateTime = System.currentTimeMillis();
                        SharedPreferences.Editor editor = getPreferences(0).edit();
                        editor.putLong("lastUpdateTime", lastUpdateTime);
    
                        editor.commit();
                    }
                }
                super.onPostExecute(result);
            }
        }
    
        private class VersionCheckTaskDialog extends AsyncTask<Void, Void, Void> {
            ProgressDialog progressDialogUpdate;
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                try {
                    progressDialogUpdate = new ProgressDialog(Login.this, android.R.style.Theme_Holo_Light_Dialog);
                    //progressDialog.setTitle("AppName");
                    progressDialogUpdate.setMessage("Fetching updates...");
                    progressDialogUpdate.setCancelable(false);
                    progressDialogUpdate.setIndeterminate(true);
                    progressDialogUpdate.show();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            protected Void doInBackground(Void... params) {
                /**
                 *  Simulates a background job.
                 */
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
    
                String extStorageDirectory =    Environment.getExternalStorageDirectory().toString();
                File folder = new File(extStorageDirectory, "pdf");
                folder.mkdir();
                File file = new File(folder, "AppName."+"apk");
                try {
                        file.createNewFile();
                } catch (IOException e1) {
                        e1.printStackTrace();
                }
                /**
                 * replace url to ApkLink
                 */
                 //DownloadFile(ApkLink, file);
                 DownloadFile("URL", file);
    
                return null;
            }
    
            @Override
            protected void onPostExecute(Void result) {
                if (progressDialogUpdate != null && progressDialogUpdate.isShowing())
                    progressDialogUpdate.dismiss();
                if(!CommonFunction.isNetworkAvailable()){
                    Toast.makeText(ClaimColonyApplication.getAppContext(), CommonString.NO_NETWORK, Toast.LENGTH_SHORT).show();
                    return;
                }
                try {
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/pdf/" + "AppName.apk")), "application/vnd.android.package-archive");
                    startActivity(intent);
                    lastUpdateTime = System.currentTimeMillis();
                    SharedPreferences.Editor editor = getPreferences(0).edit();
                    editor.putLong("lastUpdateTime", lastUpdateTime);
    
                    editor.commit();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    System.out.println("Exception in start intent for launch app-------: "+e.toString());
                    e.printStackTrace();
                } 
                super.onPostExecute(result);
            }
        }
    

    我每 24 小时检查一次更新,如果有任何可用更新,则会弹出升级您的应用程序的窗口,否则将保存您在首选项中的最后一次检查时间。 现在这将允许您更新和安装您的应用程序,这将在 24 小时后检查下一次更新,您可能需要根据条件检查更新。请更改 .apk 文件的名称和 URL。

    您将需要以下权限:

    <uses-permission android:name="android.permission.INTERNET"/>
        <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    

    祝你好运。

    【讨论】:

    • 感谢您的代码。这可能不是我真正想问的。我的意思是......查询应用程序更新是非常简单的任务。 VersionCheckTaskDialog 的 onPostExecute 是最有趣的部分。我需要做的是触发 unsupervisioned 安装。您的代码应该征求用户同意,但由于我尚未对其进行测试,并且因为它应该是“纸上”概念证明,所以我想问您是否触发 ACTION_VIEW 意图从系统应用程序可以触发不受监督的安装。谢谢
    • 我也在做同样的事情,但在这里我强制用户更新他的版本,直到他不会更新他将无法登录应用程序,当我的服务器上有任何可用更新时,我将获得我的新版本的一些网址并显示弹出窗口,如果用户允许更新将自动在设备中下载应用程序 apk 并要求安装,安装后用户将不得不再次启动应用程序,
    • +1 是执行最新发布规则的可行方式
    猜你喜欢
    • 1970-01-01
    • 2011-10-23
    • 1970-01-01
    • 2015-08-09
    • 1970-01-01
    • 2018-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多