Programowo instaluj aplikację na Androidzie
Interesuje mnie, czy można programowo zainstalować dynamicznie pobrany apk z niestandardowej aplikacji na Androida.
14 answers
Możesz łatwo uruchomić link market lub monit instalacyjny:
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);
Nie można jednak zainstalować .apks bez użytkownika wyraźnej zgody ; nie, chyba że urządzenie i program jest zakorzenione.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:12
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);
Miałem ten sam problem i po kilku próbach wyszło mi to w ten sposób. Nie wiem dlaczego, ale ustawienie danych i typu osobno spieprzyło mój zamiar.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-28 14:31:05
Cóż, kopałem głębiej i znalazłem źródła aplikacji PackageInstaller ze źródła Android.
Https://github.com/android/platform_packages_apps_packageinstaller
Z manifestu stwierdziłem, że wymaga pozwolenia:
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
I rzeczywisty proces instalacji następuje po potwierdzeniu
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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-13 13:05:13
Rozwiązania przedstawione w tym pytaniu mają zastosowanie do targetSdkVersion
s z 23 i poniżej. API na poziomie 24 i wyższym, jednak nie działają i ulegają awarii z następującym wyjątkiem:
android.os.FileUriExposedException: file:///storage/emulated/0/... exposed beyond app through Intent.getData()
Wynika to z faktu, że począwszy od Androida 24, zmieniono {[6] } adresowanie pobranego pliku. Na przykład plik instalacyjny o nazwie appName.apk
przechowywany w głównym zewnętrznym systemie plików aplikacji o nazwie pakietu com.example.test
byłby as
file:///storage/emulated/0/Android/data/com.example.test/files/appName.apk
Dla API 23
i poniżej, natomiast coś w rodzaju
content://com.example.test.authorityStr/pathName/Android/data/com.example.test/files/appName.apk
Dla API 24
i powyżej.
Więcej szczegółów na ten temat można znaleźć tutaj i nie zamierzam przez to przechodzić.
Aby odpowiedzieć na pytanie targetSdkVersion
z 24
i wyżej, należy wykonać następujące kroki:
Dodaj następujące do 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. Dodaj następujący plik paths.xml
do folderu xml
na res
W 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
jest to pokazane w przykładowym przykładzie Uri treści powyżej i {[18] } jest rzeczywistą ścieżką w systemie.
Dobrze byłoby umieścić"."(bez cudzysłowów) dla pathValue w powyższym przykładzie, jeśli nie chcesz dodawać żadnego dodatkowego podkatalogu.
-
Napisz następujący kod, aby zainstalować plik apk o nazwie
appName.apk
na głównym zewnętrznym systemie plików: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();
Nie jest również konieczne pozwolenie podczas pisania do prywatnego katalogu Twojej aplikacji na zewnętrznym system plików.
Napisałem bibliotekę AutoUpdate tutaj , w której użyłem powyższego.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-16 07:55:14
Chcę tylko podzielić się faktem, że mój plik apk został zapisany w katalogu "Data" mojej aplikacji i że musiałem zmienić uprawnienia do pliku apk, aby był czytelny dla świata, aby umożliwić jego instalację w ten sposób, w przeciwnym razie system rzucał "Parse error: there is a Problem Parsing the Package"; więc używając rozwiązania z @ Horaceman, który sprawia, że:
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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-11 15:00:11
Wykonaj następujące kroki:
1 - Dodaj do AndroidManifest.xml
:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/paths"/>
</provider>
2 - Dodaj następujące ścieżki.plik xml do folderu xml (jeśli nie istnieje utwórz go) na res w src, main
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="external_file"
path="."/>
</paths>
Nazwa ścieżki jest pokazana w przykładowym przykładzie Uri zawartości powyżej, a pathValue jest rzeczywistą ścieżką w systemie. Dobrze byłoby umieścić"."dla pathValue w powyższym przykładzie, jeśli nie chcesz dodawać żadnego dodatkowego podkatalogu.
3 - Pisz poniższy kod do uruchamiania plików Apk:
File file = "path of yor apk file";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri fileUri = FileProvider.getUriForFile(getBaseContext(), getApplicationContext().getPackageName() + ".provider", 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);
startActivity(intent);
} else {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
I dzięki Ali Nemati Hayati jako pierwszy napisać rozwiązanie profil ali-nemati-hayati
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:20:27
Tak, to możliwe. Ale do tego potrzebujesz telefonu, aby zainstalować niezweryfikowane źródła. Na przykład slideMe tak robi. Myślę, że najlepszą rzeczą, jaką możesz zrobić, to sprawdzić, czy aplikacja jest obecna i wysłać intencję do Android Market. powinieneś użyć czegoś schematu url dla android Market.
market://details?id=package.name
Nie wiem dokładnie, jak rozpocząć aktywność, ale jeśli zaczniesz aktywność z tego rodzaju adresem url. Powinien otworzyć android market i dać ci wybór, aby zainstalować aplikacje.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-06 17:21:44
Warto zauważyć, że jeśli użyjesz DownloadManager
do rozpoczęcia pobierania, pamiętaj, aby zapisać go w zewnętrznej lokalizacji, np. setDestinationInExternalFilesDir(c, null, "<your name here>).apk";
. Intent z typem package-archive nie wydaje się podobać schematowi content:
używanemu przy pobieraniu plików do wewnętrznej lokalizacji, ale podoba się file:
. (Próba zawinięcia wewnętrznej ścieżki do obiektu File, a następnie uzyskanie ścieżki również nie działa, mimo że skutkuje to adresem URL file:
, ponieważ aplikacja nie przetworzy apk; wygląda na to, że musi być zewnętrzne.)
Przykład:
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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-27 09:27:03
Inne rozwiązanie, które nie wymaga twardego kodowania aplikacji odbierającej i dlatego jest bezpieczniejsze:
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setData( Uri.fromFile(new File(pathToApk)) );
startActivity(intent);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-22 21:30:52
Tylko rozszerzenie, jeśli ktoś potrzebuje biblioteki to to może pomóc. Dzięki
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:23
Spróbuj tego
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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-22 11:08:20
UpdateNode zapewnia API dla Androida do instalowania pakietów APK z poziomu innej aplikacji.
Możesz po prostu zdefiniować swoją aktualizację online i zintegrować API z aplikacją - to wszystko.
Obecnie API jest w stanie Beta, ale możesz już wykonać kilka testów samodzielnie.
Poza tym, UpdateNode oferuje również wyświetlanie wiadomości przez system - całkiem przydatne, jeśli chcesz powiedzieć coś ważnego użytkownikom.
Jestem częścią client dev team i jestem korzystając przynajmniej z funkcji wiadomości dla mojej własnej aplikacji na Androida.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-17 20:20:23
Spróbuj tego - Zapis na manifeście:
uses-permission android:name="android.permission.INSTALL_PACKAGES"
tools:ignore="ProtectedPermissions"
Wpisz kod:
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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-23 14:37:49
Najpierw dodaj następujący wiersz do AndroidManifest.xml:
<uses-permission android:name="android.permission.INSTALL_PACKAGES"
tools:ignore="ProtectedPermissions" />
Następnie użyj następującego kodu, aby zainstalować apk:
File sdCard = Environment.getExternalStorageDirectory();
String fileStr = sdCard.getAbsolutePath() + "/MyApp";// + "app-release.apk";
File file = new File(fileStr, "TaghvimShamsi.apk");
Intent promptInstall = new Intent(Intent.ACTION_VIEW).setDataAndType(Uri.fromFile(file),
"application/vnd.android.package-archive");
startActivity(promptInstall);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-22 14:26:03