Android: установить программный код .apk

Я сделал это с помощью проблем с бинарными файлами Android и установил приложение программно на Android .

Я хочу сделать автоматическое обновление и автоматически установить сразу. Это локально, поэтому это нерыночное приложение.

Вот мой код для этого:

public void Update(String apkurl){ try { URL url = new URL(apkurl); HttpURLConnection c = (HttpURLConnection) url.openConnection(); c.setRequestMethod("GET"); c.setDoOutput(true); c.connect(); String PATH = Environment.getExternalStorageDirectory() + "/download/"; File file = new File(PATH); file.mkdirs(); File outputFile = new File(file, "app.apk"); FileOutputStream fos = new FileOutputStream(outputFile); InputStream is = c.getInputStream(); byte[] buffer = new byte[1024]; int len1 = 0; while ((len1 = is.read(buffer)) != -1) { fos.write(buffer, 0, len1); } fos.close(); is.close();//till here, it works fine - .apk is download to my sdcard in download file Intent promptInstall = new Intent(Intent.ACTION_VIEW) .setData(Uri.parse(PATH+"app.apk")) .setType("application/android.com.app"); startActivity(promptInstall);//installation is not working } catch (IOException e) { Toast.makeText(getApplicationContext(), "Update error!", Toast.LENGTH_LONG).show(); } } 

Мое разрешение – INTERNET , WRITE_EXTERNAL_STORAGE , INSTALL_PACKAGES и DELETE_PACKAGES .

Когда Intent promptInstall загружен, приложение вылетает = /

Итак, я пропускаю разрешения или неправильно код, или есть лучший способ сделать это?

Я решил проблему. Я допустил ошибку в setData(Uri) и setType(String) .

 Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" + "app.apk")), "application/vnd.android.package-archive"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); 

Теперь это правильно, мое автоматическое обновление работает. Спасибо за помощь. знак равно

Изменить 20.7.2016:

После долгого времени мне пришлось снова использовать этот способ обновления в другом проекте. Я столкнулся с рядом проблем со старым решением. За это время многое изменилось, поэтому я должен был сделать это с помощью другого подхода. Вот код:

  //get destination to update file and set Uri //TODO: First I wanted to store my update .apk file on internal storage for my app but apparently android does not allow you to open and install //aplication with existing package from there. So for me, alternative solution is Download directory in external storage. If there is better //solution, please inform us in comment String destination = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/"; String fileName = "AppName.apk"; destination += fileName; final Uri uri = Uri.parse("file://" + destination); //Delete update file if exists File file = new File(destination); if (file.exists()) //file.delete() - test this, I think sometimes it doesnt work file.delete(); //get url of app on server String url = Main.this.getString(R.string.update_app_url); //set downloadmanager DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); request.setDescription(Main.this.getString(R.string.notification_description)); request.setTitle(Main.this.getString(R.string.app_name)); //set destination request.setDestinationUri(uri); // get download service and enqueue file final DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); final long downloadId = manager.enqueue(request); //set BroadcastReceiver to install app when .apk is downloaded BroadcastReceiver onComplete = new BroadcastReceiver() { public void onReceive(Context ctxt, Intent intent) { Intent install = new Intent(Intent.ACTION_VIEW); install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); install.setDataAndType(uri, manager.getMimeTypeForDownloadedFile(downloadId)); startActivity(install); unregisterReceiver(this); finish(); } }; //register receiver for when .apk download is compete registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); 

Для ICS я реализовал ваш код и создал class, который расширяет AsyncTask . Надеюсь, вы это оцените! Спасибо за ваш код и решение.

 public class UpdateApp extends AsyncTask{ private Context context; public void setContext(Context contextf){ context = contextf; } @Override protected Void doInBackground(String... arg0) { try { URL url = new URL(arg0[0]); HttpURLConnection c = (HttpURLConnection) url.openConnection(); c.setRequestMethod("GET"); c.setDoOutput(true); c.connect(); String PATH = "/mnt/sdcard/Download/"; File file = new File(PATH); file.mkdirs(); File outputFile = new File(file, "update.apk"); if(outputFile.exists()){ outputFile.delete(); } FileOutputStream fos = new FileOutputStream(outputFile); InputStream is = c.getInputStream(); byte[] buffer = new byte[1024]; int len1 = 0; while ((len1 = is.read(buffer)) != -1) { fos.write(buffer, 0, len1); } fos.close(); is.close(); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(new File("/mnt/sdcard/Download/update.apk")), "application/vnd.android.package-archive"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // without this flag android returned a intent error! context.startActivity(intent); } catch (Exception e) { Log.e("UpdateAPP", "Update error! " + e.getMessage()); } return null; } } 

Чтобы использовать его, в основном вызове вашей деятельности следующим образом:

 atualizaApp = new UpdateApp(); atualizaApp.setContext(getApplicationContext()); atualizaApp.execute("http://serverurl/appfile.apk"); 

Этот вопрос очень полезен. Но не забудьте установить SD-карту в свой эмулятор, если вы этого не сделаете, это не сработает.

Я теряю время, прежде чем открыть это.

 /* * Code Prepared by **Muhammad Mubashir**. * Analyst Software Engineer. Email Id : [email protected] Skype Id : muhammad.mubashir.ansari Code: **August, 2011.** Description: **Get Updates(means New .Apk File) from IIS Server and Download it on Device SD Card, and Uninstall Previous (means OLD .apk) and Install New One. and also get Installed App Version Code & Version Name.** All Rights Reserved. */ package com.SelfInstall01; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.List; import com.SelfInstall01.SelfInstall01Activity; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.AlertDialog.Builder; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageInfo; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class SelfInstall01Activity extends Activity { class PInfo { private String appname = ""; private String pname = ""; private String versionName = ""; private int versionCode = 0; //private Drawable icon; /*private void prettyPrint() { //Log.v(appname + "\t" + pname + "\t" + versionName + "\t" + versionCode); }*/ } public int VersionCode; public String VersionName=""; public String ApkName ; public String AppName ; public String BuildVersionPath=""; public String urlpath ; public String PackageName; public String InstallAppPackageName; public String Text=""; TextView tvApkStatus; Button btnCheckUpdates; TextView tvInstallVersion; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //Text= "Old".toString(); Text= "New".toString(); ApkName = "SelfInstall01.apk";//"Test1.apk";// //"DownLoadOnSDcard_01.apk"; // AppName = "SelfInstall01";//"Test1"; // BuildVersionPath = "http://10.0.2.2:82/Version.txt".toString(); PackageName = "package:com.SelfInstall01".toString(); //"package:com.Test1".toString(); urlpath = "http://10.0.2.2:82/"+ Text.toString()+"_Apk/" + ApkName.toString(); tvApkStatus =(TextView)findViewById(R.id.tvApkStatus); tvApkStatus.setText(Text+" Apk Download.".toString()); tvInstallVersion = (TextView)findViewById(R.id.tvInstallVersion); String temp = getInstallPackageVersionInfo(AppName.toString()); tvInstallVersion.setText("" +temp.toString()); btnCheckUpdates =(Button)findViewById(R.id.btnCheckUpdates); btnCheckUpdates.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { GetVersionFromServer(BuildVersionPath); if(checkInstalledApp(AppName.toString()) == true) { Toast.makeText(getApplicationContext(), "Application Found " + AppName.toString(), Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(getApplicationContext(), "Application Not Found. "+ AppName.toString(), Toast.LENGTH_SHORT).show(); } } }); }// On Create END. private Boolean checkInstalledApp(String appName){ return getPackages(appName); } // Get Information about Only Specific application which is Install on Device. public String getInstallPackageVersionInfo(String appName) { String InstallVersion = ""; ArrayList apps = getInstalledApps(false); /* false = no system packages */ final int max = apps.size(); for (int i=0; i apps = getInstalledApps(false); /* false = no system packages */ final int max = apps.size(); for (int i=0; i apps.get(i).versionCode) { isInstalled = true; /*Toast.makeText(getApplicationContext(), "Install Code is better.!", Toast.LENGTH_SHORT).show();*/ DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { switch (which) { case DialogInterface.BUTTON_POSITIVE: //Yes button clicked //SelfInstall01Activity.this.finish(); Close The App. DownloadOnSDcard(); InstallApplication(); UnInstallApplication(PackageName.toString()); break; case DialogInterface.BUTTON_NEGATIVE: //No button clicked break; } } }; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("NO need to Install.").setPositiveButton("Install Forcely", dialogClickListener) .setNegativeButton("Cancel.", dialogClickListener).show(); } } } return isInstalled; } private ArrayList getInstalledApps(boolean getSysPackages) { ArrayList res = new ArrayList(); List packs = getPackageManager().getInstalledPackages(0); for(int i=0;i= '0' && s.charAt(i) <= '9' || s.charAt(i) == '.')) { temp = temp.toString().concat(Character.toString(s.charAt(i))) ; i++; } // s = s.substring(i); // Move to Next to Process.! temp = temp + " "; // Separate wrt Space Version Code and Version Name. } String[] fields = temp.split(" ");// Make Array for Version Code and Version Name. VersionCode = Integer.parseInt(fields[0].toString());// .ToString() Return String Value. VersionName = fields[1].toString(); baos.close(); } catch (MalformedURLException e) { Toast.makeText(getApplicationContext(), "Error." + e.getMessage(), Toast.LENGTH_SHORT).show(); e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); Toast.makeText(getApplicationContext(), "Error." + e.getMessage(), Toast.LENGTH_SHORT).show(); } //return true; }// Method End. // Download On My Mobile SDCard or Emulator. public void DownloadOnSDcard() { try{ URL url = new URL(urlpath.toString()); // Your given URL. HttpURLConnection c = (HttpURLConnection) url.openConnection(); c.setRequestMethod("GET"); c.setDoOutput(true); c.connect(); // Connection Complete here.! //Toast.makeText(getApplicationContext(), "HttpURLConnection complete.", Toast.LENGTH_SHORT).show(); String PATH = Environment.getExternalStorageDirectory() + "/download/"; File file = new File(PATH); // PATH = /mnt/sdcard/download/ if (!file.exists()) { file.mkdirs(); } File outputFile = new File(file, ApkName.toString()); FileOutputStream fos = new FileOutputStream(outputFile); // Toast.makeText(getApplicationContext(), "SD Card Path: " + outputFile.toString(), Toast.LENGTH_SHORT).show(); InputStream is = c.getInputStream(); // Get from Server and Catch In Input Stream Object. byte[] buffer = new byte[1024]; int len1 = 0; while ((len1 = is.read(buffer)) != -1) { fos.write(buffer, 0, len1); // Write In FileOutputStream. } fos.close(); is.close();//till here, it works fine - .apk is download to my sdcard in download file. // So please Check in DDMS tab and Select your Emulator. //Toast.makeText(getApplicationContext(), "Download Complete on SD Card.!", Toast.LENGTH_SHORT).show(); //download the APK to sdcard then fire the Intent. } catch (IOException e) { Toast.makeText(getApplicationContext(), "Error! " + e.toString(), Toast.LENGTH_LONG).show(); } } } 

Спасибо за то, что поделился этим. Я реализовал и работал. Однако:

1) Я устанавливаю ver 1 моего приложения (работа без проблем) 2) Я устанавливаю ver 2 на сервер. приложение извлекает ver2 и сохраняет на SD-карту и запрашивает у пользователя установку нового пакета ver2 3) ver2 устанавливает и работает как ожидалось 4) Проблема в том, что при каждом запуске приложения пользователь хочет снова установить версию 2.

Поэтому я думал, что решение просто удалит APK на SD-карте, но их задача Async просто вернет ver2 снова для сервера.

Таким образом, единственный способ остановить попытку установки v2 apk – удалить с SD-карты и с удаленного сервера.

Как вы можете себе представить, на самом деле это не сработает, так как я никогда не узнаю, когда все пользователи получили последнюю версию.

Любая помощь в решении этой проблемы очень ценится.

Я ОСУЩЕСТВЛЯЛ метод «ldmuniz», указанный выше.

NEW EDIT: Я просто думал, что все мои APK названы одинаковыми. Должен ли я называть myapk_v1.0xx.apk и в этой версии проактивно установить удаленный путь для поиска v.2.0 всякий раз, когда он будет выпущен?

Я протестировал теорию, и она РЕШАЕТ проблему. Вы должны назвать свой файл APK файлом какого-то типа, не забывая всегда устанавливать версию NEXT версии # в текущем выпуске приложения. Не идеальный, но функциональный.

Есть ли способ читать версию Android APK с удаленным доступом, как было запущено в манифесте, или загрузить ansible файл APK на сервере, и перед тем, как запросить установку, сравните ли версию, чтобы узнать, загружен ли APK = или <текущая установленная версия?

  • Как я могу получить последнюю версию JRE / JDK как zip-файл, а не EXE или MSI-установщик?
  • Ошибка: невозможно найти adb в SDK в Android Studio
  • Получить установленную дату приложения на Android
  • Как вручную установить артефакт в Maven 2?
  • Создание настройки приложения в visual studio 2013
  • Ошибка установки углового с использованием npm из-за необходимости использовать строку
  • Ошибка установки SSDT (Не удалось выполнить пакет EXE.)
  • Ошибка , когда я пытался обновить приложение
  • Как регистрировать типы файлов / расширения с помощью установщика WiX?
  • Visual Studio 2013 - Нет установленных веб-шаблонов Visual Basic / Visual C #
  • невозможно загрузить, $ GOPATH не установлен
  • Давайте будем гением компьютера.