Instaluj aplikacje po cichu, z przyznanym pozwoleniem INSTALL PACKAGES
Próbuję po cichu zainstalować apk w systemie. Moja aplikacja znajduje się w /system / app i pomyślnie przyznano uprawnienia " android.pozwolenie.INSTALL_PACKAGES "
Jednak nigdzie nie mogę znaleźć, jak wykorzystać to pozwolenie. Próbowałem skopiować pliki do /data / app i nie powiodło mi się. Również próbowałem użyć tego kodu
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(
Uri.parse("file:///sdcard/app.apk"),
"application/vnd.android.package-archive");
startActivity(intent);
Ale ten kod otwiera standardowe okno instalacji. Jak zainstalować aplikację bez roota z granted android.permission.INSTALL_PACKAGES
?
Jeśli uważasz, że piszę wirusa: Wszystkie programy są zainstalowane w /data/app. Uprawnienia Install_packages mogą być przyznane tylko programom na poziomie systemu znajdującym się w /system/app lub podpisanym kluczem systemowym. Więc wirus nie może się tam dostać.
Jak powiedział http://www.mail-archive.com/[email protected]/msg06281.html aplikacje mogą być ciche zainstalowane, jeśli mają uprawnienia install_packages. Co więcej, nie potrzebujesz uprawnień Install_packages, aby instalować pakiety nie po cichu. Plus http://www.androidzoom.com/android_applications/tools/silent-installer_wgqi.html
14 answers
Twoim pierwszym zakładem jest sprawdzenie natywnego pakietu Androida PackageInstaller . Polecam modyfikowanie tej aplikacji tak, jak chcesz, lub po prostu wyodrębnić wymaganą funkcjonalność.
W szczególności, jeśli przyjrzysz się Pakietinstalleractivity i jej metodzie onClickListener
:
public void onClick(View v) {
if(v == mOk) {
// Start subactivity to actually install the application
Intent newIntent = new Intent();
...
newIntent.setClass(this, InstallAppProgress.class);
...
startActivity(newIntent);
finish();
} else if(v == mCancel) {
// Cancel and finish
finish();
}
}
Wtedy zauważysz, że rzeczywisty instalator znajduje się w klasie InstallAppProgress. Sprawdzając tę klasę przekonasz się, że initView
jest podstawową funkcją Instalatora, a ostateczna to, co robi, to wywołanie PackageManager
' s installPackage
function:
public void initView() {
...
pm.installPackage(mPackageURI, observer, installFlags, installerPackageName);
}
Kolejnym krokiem jest sprawdzenie Packagemanagera, czyli klasy abstrakcyjnej. Znajdziesz tam installPackage(...)
funkcję. Zła wiadomość jest taka, że jest oznaczona @hide. Oznacza to, że nie jest bezpośrednio dostępna (nie będzie można kompilować z wywołaniem tej metody).
/**
* @hide
* ....
*/
public abstract void installPackage(Uri packageURI,
IPackageInstallObserver observer,
int flags,String installerPackageName);
Ale będziesz mógł uzyskać dostęp do tych metod poprzez refleksję.
Jeśli interesuje Cię jak zaimplementowana jest funkcja PackageManager
, spójrz na PackageManagerService .
Podsumowanie
Musisz pobrać obiekt package manager Poprzez Context
' s getPackageManager()
. Następnie wywołasz installPackage
funkcję poprzez odbicie.
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
2011-04-27 14:34:35
Sprawdziłem jak ADB instaluje aplikacje.
- Kopiuje apk do /data / local / tmp
- uruchamia powłokę: pm install/data/local/tmp / app.apk"
Próbowałem odtworzyć to zachowanie robiąc: (na pc, za pomocą kabla usb)adb push app.apk /sdcard/app.apk
adb shell
$ pm install /sdcard/app.apk
To działa. Aplikacja jest zainstalowana.
Zrobiłem aplikację (o nazwie AppInstall), która powinna zainstalować drugą aplikację.
(zainstalowany normalnie, urządzenie nie rooted)
Tak.:Runtime.getRuntime().exec("pm install /sdcard/app.apk").waitFor();
Ale to daje błąd:java.lang.SecurityException: Neither user 10019 nor current process has android.permission.INSTALL_PACKAGES.
Wygląda na to, że błąd jest wyrzucany przez pm, a nie przez AppInstall.
Ponieważ SecurityException nie jest przechwytywany przez AppInstall i aplikacja nie ulega awarii.
Próbowałem tego samego na zakorzenionym urządzeniu (ta sama aplikacja i AppInstall) i działało jak urok.
(Również normalnie zainstalowany, Nie w / system lub cokolwiek)
AppInstall nawet nie zapytał root-uprawnienia.
Ale to dlatego, że powłoka jest zawsze #
zamiast $
na tym urządzeniu.
Btw, ty potrzebujesz roota, aby zainstalować aplikację w systemie, prawda?
Próbowałem ADB remount na urządzeniu non-rooted i dostałem: remount failed: Operation not permitted.
Dlatego nie mogłem wypróbować / system rzeczy na urządzeniu non-rooted.
Wniosek: powinieneś użyć zakorzenionego urządzenia
Mam nadzieję, że to pomoże:)
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
2012-05-20 13:51:40
Powinieneś zdefiniować
<uses-permission
android:name="android.permission.INSTALL_PACKAGES" />
W manifeście, to jeśli jesteś w partycji systemowej (/system / app) lub masz aplikację podpisaną przez producenta, Będziesz mieć uprawnienia INSTALL_PACKAGES.
Moja sugestia to stworzenie małego projektu dla Androida z poziomem kompatybilności 1.5 używanego do wywoływania installPackages poprzez reflection i eksportowania jar z metodami do instalowania pakietów i wywoływania rzeczywistych metod. Następnie, importując jar do swojego projektu, będziesz bądź gotowy do instalacji pakietów.
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-11-03 21:57:24
Od niedawna realizuję instalację bez zgody Użytkownika - była to aplikacja kiosk dla poziomu API 21+ , gdzie miałem pełną kontrolę nad środowiskiem.
Podstawowe wymagania to
- API poziom 21 +
- root access aby zainstalować updater jako systemową aplikację uprzywilejowaną.
Następująca metoda odczytuje i instaluje APK z InputStream:
public static boolean installPackage(Context context, InputStream in, String packageName)
throws IOException {
PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
params.setAppPackageName(packageName);
// set params
int sessionId = packageInstaller.createSession(params);
PackageInstaller.Session session = packageInstaller.openSession(sessionId);
OutputStream out = session.openWrite("COSU", 0, -1);
byte[] buffer = new byte[65536];
int c;
while ((c = in.read(buffer)) != -1) {
out.write(buffer, 0, c);
}
session.fsync(out);
in.close();
out.close();
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra("info", "somedata"); // for extra data if needed..
Random generator = new Random();
PendingIntent i = PendingIntent.getActivity(context, generator.nextInt(), intent,PendingIntent.FLAG_UPDATE_CURRENT);
session.commit(i.getIntentSender());
return true;
}
Poniższy kod wywołuje instalację
try {
InputStream is = getResources().openRawResource(R.raw.someapk_source);
installPackage(MainActivity.this, is, "com.example.apk");
} catch (IOException e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
Dla całego do pracy potrzebujesz INSTALL_PACKAGES
pozwolenia, albo powyższy kod zawiedzie po cichu
<uses-permission
android:name="android.permission.INSTALL_PACKAGES" />
Aby uzyskać to pozwolenie, musisz zainstalować APK jako aplikację systemową, która wymaga roota (jednak po zainstalowaniu aplikacji updater wydaje się działać bez roota)
Aby zainstalować jako aplikację systemową utworzyłem podpisany APK i wcisnąłem go za pomocą
adb push updater.apk /sdcard/updater.apk
A następnie przeniósł go do system/priv-app
- co wymaga remountu FS (dlatego root jest wymagane)
adb shell
su
mount -o rw,remount /system
mv /sdcard/updater.apk /system/priv-app
chmod 644 /system/priv-app/updater.apk
Z jakiegoś powodu nie działa z prostą wersją debugowania, ale logcat pokazuje przydatne informacje, jeśli aplikacja w priv-app
nie jest z jakiegoś powodu pobierana.
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
2016-11-06 07:08:44
Próbowałem na rooted Android 4.2.2 i ta metoda działa dla mnie:
private void installApk(String filename) {
File file = new File(filename);
if(file.exists()){
try {
final String command = "pm install -r " + file.getAbsolutePath();
Process proc = Runtime.getRuntime().exec(new String[] { "su", "-c", command });
proc.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
}
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-20 09:44:08
Nie miałem pojęcia, jak to zrobić, ponieważ nikt nie odpowiedział tym razem, i nie znalazłem dokumentacji na temat tego pozwolenia. Więc znalazłem własne rozwiązanie. To gorsze niż Twoje, ale i tak jest to rozwiązanie.
Zainstalowałem busybox, który ustawił uprawnienia 777 do /data / app(nie dbam o bezpieczeństwo). Następnie wykonaj "busybox install" z aplikacji. To działa, ale ma duży przeciek bezpieczeństwa. Jeśli ustawisz uprawnienia 777, nie jest Wymagany root.
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
2011-07-19 11:25:26
Możesz użyć ukrytego API android.content.pm.IPackageInstallObserver
poprzez odbicie:
public class PackageManagement {
public static final int INSTALL_REPLACE_EXISTING = 0x00000002;
public static final int INSTALL_SUCCEEDED = 1;
private static Method installPackageMethod;
private static Method deletePackageMethod;
static {
try {
installPackageMethod = PackageManager.class.getMethod("installPackage", Uri.class, IPackageInstallObserver.class, Integer.TYPE, String.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
public static void installPackage(PackageManager pm, Uri mPackageUri, IPackageInstallObserver observer, int installFlags, String installerPackageName) {
try {
installPackageMethod.invoke(pm, mPackageUri, observer, installFlags, installerPackageName);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Importuj android.content.pm.IPackageInstallObserver
do swojego projektu. Twoja aplikacja musi być systemowa. Musisz aktywować uprawnienia android.permission.INSTALL_PACKAGES
w swoim pliku manifestu.
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
2016-03-08 02:42:58
Tutaj jest bardzo ładny post na ten temat. Bardzo mi to pomogło.
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-07-04 18:29:02
Możesz po prostu użyć polecenia install adb, aby zainstalować / zaktualizować APK w ciszy. Przykładowy kod znajduje się poniżej
public static void InstallAPK(String filename){
File file = new File(filename);
if(file.exists()){
try {
String command;
filename = StringUtil.insertEscape(filename);
command = "adb install -r " + filename;
Process proc = Runtime.getRuntime().exec(new String[] { "su", "-c", command });
proc.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
}
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-29 10:37:14
Zrobiłem aplikację testową do cichych instalacji, używając PackageManager.metoda installPackage.
Otrzymałem metodę installPackage poprzez odbicie i zrobiłem interfejs android. content. pm. IPackageInstallObserver w moim folderze src (bo jest ukryty w android.content.pm pakiet).
Kiedy uruchamiam installPackage, mam SecurityException ze wskazaniem string, że moja aplikacja nie ma Androida.pozwolenie.INSTALL_PACKAGES, ale zdefiniowany w AndroidManifest.xml.
Więc myślę, że to nie możliwość zastosowania tej metody.
PS. Testowałem na Android SDK 2.3 i 4.0. Może zadziała z wcześniejszymi wersjami.
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-02-13 18:48:58
Spróbuj tego LD_LIBRARY_PATH=/vendor/lib:/system/lib
przed instalacją pm. Działa dobrze.
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-04 05:32:54
Aplikacja innej firmy nie może zainstalować aplikacji na Androida. Jednak aplikacja innej firmy może poprosić SYSTEM OPERACYJNY Android o zainstalowanie aplikacji.
Więc powinieneś zdefiniować to:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file:///sdcard/app.apk", "application/vnd.android.package-archive");
startActivity(intent);
Możesz również spróbować zainstalować go jako aplikację systemową, aby przyznać uprawnienia i zignorować to zdefiniowanie. (Root Required)
Możesz uruchomić następujące polecenie w aplikacji 3rd party, aby zainstalować aplikację na urządzeniu zakorzenionym.
Kod to:
private void installApk(String filename) {
File file = new File(filename);
if(file.exists()){
try {
final String command = "pm install -r " + file.getAbsolutePath();
Process proc = Runtime.getRuntime().exec(new String[] { "su", "-c", command });
proc.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Mam nadzieję, że ta odpowiedź jest pomocne dla Ciebie.
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-02-16 17:55:40
Warunek:
Twój APK musi być podpisany przez system, jak poprawnie wskazano wcześniej. Jednym ze sposobów, aby to osiągnąć, jest samodzielne zbudowanie obrazu AOSP i dodanie kodu źródłowego do kompilacji.
Kod:
Po zainstalowaniu jako aplikacja systemowa, możesz użyć metod menedżera pakietów, aby zainstalować i odinstalować APK w następujący sposób:
Zainstaluj:
public boolean install(final String apkPath, final Context context) {
Log.d(TAG, "Installing apk at " + apkPath);
try {
final Uri apkUri = Uri.fromFile(new File(apkPath));
final String installerPackageName = "MyInstaller";
context.getPackageManager().installPackage(apkUri, installObserver, PackageManager.INSTALL_REPLACE_EXISTING, installerPackageName);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
Odinstaluj:
public boolean uninstall(final String packageName, final Context context) {
Log.d(TAG, "Uninstalling package " + packageName);
try {
context.getPackageManager().deletePackage(packageName, deleteObserver, PackageManager.DELETE_ALL_USERS);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
Aby uzyskać oddzwonienie po zainstalowaniu / odinstalowaniu APK możesz użyć tego:
/**
* Callback after a package was installed be it success or failure.
*/
private class InstallObserver implements IPackageInstallObserver {
@Override
public void packageInstalled(String packageName, int returnCode) throws RemoteException {
if (packageName != null) {
Log.d(TAG, "Successfully installed package " + packageName);
callback.onAppInstalled(true, packageName);
} else {
Log.e(TAG, "Failed to install package.");
callback.onAppInstalled(false, null);
}
}
@Override
public IBinder asBinder() {
return null;
}
}
/**
* Callback after a package was deleted be it success or failure.
*/
private class DeleteObserver implements IPackageDeleteObserver {
@Override
public void packageDeleted(String packageName, int returnCode) throws RemoteException {
if (packageName != null) {
Log.d(TAG, "Successfully uninstalled package " + packageName);
callback.onAppUninstalled(true, packageName);
} else {
Log.e(TAG, "Failed to uninstall package.");
callback.onAppUninstalled(false, null);
}
}
@Override
public IBinder asBinder() {
return null;
}
}
/**
* Callback to give the flow back to the calling class.
*/
public interface InstallerCallback {
void onAppInstalled(final boolean success, final String packageName);
void onAppUninstalled(final boolean success, final String packageName);
}
===> testowany na Androidzie 8.1 i działał dobrze.
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-07-26 17:06:51
!/ bin / bash
f=/home/cox/myapp.apk #or $1 if input from terminal.
#backup env var
backup=$LD_LIBRARY_PATH
LD_LIBRARY_PATH=/vendor/lib:/system/lib
myTemp=/sdcard/temp.apk
adb push $f $myTemp
adb shell pm install -r $myTemp
#restore env var
LD_LIBRARY_PATH=$backup
To mi pasuje.
Uruchamiam to na ubuntu 12.04, na terminalu shell.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-06 05:53:12