Установить приложение программно на Android

Мне интересно узнать, можно ли программно установить динамически загруженный apk из пользовательского приложения для Android.

Solutions Collecting From Web of "Установить приложение программно на Android"

Вы можете легко запустить рыночную ссылку или запрос на установку:

Intent promptInstall = new Intent(Intent.ACTION_VIEW) .setDataAndType(Uri.parse("file:///path/to/your.apk"), "application/vnd.android.package-archive"); startActivity(promptInstall); 

источник

 Intent goToMarket = new Intent(Intent.ACTION_VIEW) .setData(Uri.parse("market://details?id=com.package.name")); startActivity(goToMarket); 

источник

Однако вы не можете установить .apks без явного разрешения пользователя ; Если устройство и ваша программа не внедрены.

 File file = new File(dir, "App.apk"); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); startActivity(intent); 

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

Ну, я углубился глубже и нашел источники приложения PackageInstaller от Android Source.

https://github.com/android/platform_packages_apps_packageinstaller

Из манифеста я обнаружил, что для этого требуется разрешение:

  <uses-permission android:name="android.permission.INSTALL_PACKAGES" /> 

И фактический процесс установки происходит после подтверждения

 Intent newIntent = new Intent(); newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, mPkgInfo.applicationInfo); newIntent.setData(mPackageURI); newIntent.setClass(this, InstallAppProgress.class); String installerPackageName = getIntent().getStringExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME); if (installerPackageName != null) { newIntent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, installerPackageName); } startActivity(newIntent); 

Решения, предоставленные для этого вопроса, применимы к targetSdkVersion s 23 и ниже. Однако для Android N, т.е. уровня API 24 и выше, они не работают и не сбой со следующим Исключением:

 android.os.FileUriExposedException: file:///storage/emulated/0/... exposed beyond app through Intent.getData() 

Это связано с тем, что, начиная с Android 24, Uri для адресации загруженного файла изменился. Например, установочный файл с именем appName.apk хранящийся в первичной внешней файловой системе приложения с именем пакета com.example.test будет таким же

file:///storage/emulated/0/Android/data/com.example.test/files/appName.apk

Для API 23 и ниже, тогда как что-то вроде

 content://com.example.test.authorityStr/pathName/Android/data/com.example.test/files/appName.apk 

Для API 24 и выше.

Более подробную информацию об этом можно найти здесь, и я не собираюсь ее просматривать.

Чтобы ответить на вопрос для targetSdkVersion 24 и выше, нужно выполнить следующие действия: Добавить в AndroidManifest.xml следующее:

 <application android:allowBackup="true" android:label="@string/app_name"> <provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.authorityStr" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/paths"/> </provider> </application> 

2. Добавьте следующий файл paths.xml в папку xml по res в src, main:

 <?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="pathName" path="pathValue"/> </paths> 

Имя pathName – это то, что показано в примерном примере uri контента выше, а pathValue – это фактический путь в системе. Было бы неплохо поставить «.». (Без кавычек) для pathValue в приведенном выше примере, если вы не хотите добавлять дополнительный подкаталог.

  1. Напишите следующий код для установки apk с именем appName.apk в основной внешней файловой системе:

     File directory = context.getExternalFilesDir(null); File file = new File(directory, fileName); Uri fileUri = Uri.fromFile(file); if (Build.VERSION.SDK_INT >= 24) { fileUri = FileProvider.getUriForFile(context, context.getPackageName(), file); } Intent intent = new Intent(Intent.ACTION_VIEW, fileUri); intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true); intent.setDataAndType(fileUri, "application/vnd.android" + ".package-archive"); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); context.startActivity(intent); activity.finish(); 

При записи в личный каталог вашего собственного приложения во внешней файловой системе не требуется никаких разрешений.

Здесь я написал библиотеку AutoUpdate, в которой я использовал выше.

Я просто хочу поделиться фактом, что мой файл apk был сохранен в моем каталоге «Данные» и что мне нужно было изменить разрешения на файл apk, чтобы он был доступен для чтения, чтобы он мог быть установлен таким образом, иначе система Метался «Ошибка анализа: есть проблема с анализом пакета»; Поэтому с помощью решения от @Horaceman, который делает:

 File file = new File(dir, "App.apk"); file.setReadable(true, false); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); startActivity(intent); 

Да, это возможно. Но для этого вам нужен телефон для установки непроверенных источников. Например, slideMe делает это. Я думаю, что самое лучшее, что вы можете сделать, это проверить, присутствует ли приложение и отправить намерение Android Market. Вы должны использовать что-то URL-схему для Android-рынка.

 market://details?id=package.name 

Я не знаю, как начать работу, но если вы начнете работу с такого рода URL. Он должен открыть рынок Android и дать вам выбор для установки приложений.

Стоит отметить, что если вы используете DownloadManager чтобы начать загрузку, обязательно сохраните его во внешнее местоположение, например setDestinationInExternalFilesDir(c, null, "<your name here>).apk"; , Намерение с типом пакета-архива похоже не похоже на content: схема, используемая при загрузке во внутреннее местоположение, но похожа на file: (Попытка обернуть внутренний путь в объект File, а затем получить путь не работает, даже если он приводит к file: url, так как приложение не будет анализировать apk, похоже, что оно должно быть внешним.)

Пример:

 int uriIndex = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI); String downloadedPackageUriString = cursor.getString(uriIndex); File mFile = new File(Uri.parse(downloadedPackageUriString).getPath()); Intent promptInstall = new Intent(Intent.ACTION_VIEW) .setDataAndType(Uri.fromFile(mFile), "application/vnd.android.package-archive") .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); appContext.startActivity(promptInstall); 

Просто расширение, если кому-то нужна библиотека, это может помочь. Благодаря Рагхаву

Другое решение, которое не требует жесткого кодирования получающего приложения, и, следовательно, более безопасно:

 Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); intent.setData( Uri.fromFile(new File(pathToApk)) ); startActivity(intent); 

UpdateNode предоставляет API для Android для установки пакетов APK из другого приложения.

Вы можете просто определить свое обновление онлайн и интегрировать API в свое приложение – вот и все.
В настоящее время API находится в состоянии бета-тестирования, но вы уже можете выполнять некоторые тесты самостоятельно.

Кроме того, UpdateNode предлагает также отображение сообщений, хотя система – очень полезно, если вы хотите сказать что-то важное для ваших пользователей.

Я являюсь частью команды клиента dev и использую хотя бы функциональность сообщений для своего собственного приложения для Android.

См. Здесь описание того, как интегрировать API

попробуй это

 String filePath = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME)); String title = filePath.substring( filePath.lastIndexOf('/')+1, filePath.length() ); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(new File(filePath)), "application/vnd.android.package-archive"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // without this flag android returned a intent error! MainActivity.this.startActivity(intent); 

Попробуйте это – Напишите на манифесте:

 uses-permission android:name="android.permission.INSTALL_PACKAGES" tools:ignore="ProtectedPermissions" 

Напишите код:

 File sdCard = Environment.getExternalStorageDirectory(); String fileStr = sdCard.getAbsolutePath() + "/Download";// + "app-release.apk"; File file = new File(fileStr, "app-release.apk"); Intent promptInstall = new Intent(Intent.ACTION_VIEW).setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); startActivity(promptInstall);