Установка приложений в автоматическом режиме с предоставленным разрешением INSTALL_PACKAGES - PullRequest
82 голосов
/ 27 апреля 2011

Я пытаюсь тихо установить apk в систему.Мое приложение находится в / system / app и успешно получило разрешение "android.permission.INSTALL_PACKAGES"

Однако я нигде не могу найти, как использовать это разрешение.Я пытался скопировать файлы в / data / app, но безуспешно.Также я попытался использовать этот код

    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(
            Uri.parse("file:///sdcard/app.apk"),
            "application/vnd.android.package-archive");
    startActivity(intent);

Но этот код открывает стандартное диалоговое окно установки.Как я могу установить приложение в автоматическом режиме без рута с предоставленным android.permission.INSTALL_PACKAGES?

PS Я пишу приложение, которое при первом запуске установит множество apks из папки в систему (заменит Мастер установки).Мне нужно, чтобы сделать прошивку легче.

Если вы считаете, что я пишу вирус: все программы установлены в / data / app.Разрешение Install_packages может быть предоставлено только программам системного уровня, расположенным в / system / app или подписанным системным ключом.Так что вирус не может туда попасть.

Как уже было сказано http://www.mail-archive.com/android-porting@googlegroups.com/msg06281.html приложения МОГУТ быть беззвучно установлены, если у них есть install_packagesразрешение.Более того, вам не нужно разрешение Install_packages для установки пакетов без вывода сообщений.Плюс http://www.androidzoom.com/android_applications/tools/silent-installer_wgqi.html

Ответы [ 15 ]

0 голосов
/ 26 июля 2018

Необходимое условие:

Ваш APK должен быть подписан системой, как правильно указано ранее.Одним из способов достижения этого является создание образа AOSP самостоятельно и добавление исходного кода в сборку.

Код:

После установки в качестве системного приложения вы можете использоватьметоды менеджера пакетов для установки и удаления APK:

Install:

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;
    }
}

Uninstall:

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;
    }
}

Чтобы получить обратный вызов после установки APK/ удалено, вы можете использовать это:

/**
 * 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);
}

===> Протестировано на Android 8.1 и хорошо работало.

0 голосов
/ 16 февраля 2018

Стороннее приложение не может установить приложение Android плавно. Однако стороннее приложение может попросить ОС Android установить приложение.

Итак, вы должны определить это:

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file:///sdcard/app.apk", "application/vnd.android.package-archive");
startActivity(intent);

Вы также можете попытаться установить его как системное приложение, чтобы предоставить разрешение и игнорировать это определение. (Требуется рут)

Вы можете запустить следующую команду в стороннем приложении, чтобы установить приложение на корневом устройстве.

Код:

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();
    }
 }
}

Я надеюсь, что этот ответ полезен для вас.

0 голосов
/ 06 июня 2014

! / 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

Это работает для меня.Я запускаю это на Ubuntu 12.04, на терминале оболочки.

0 голосов
/ 04 февраля 2014

Попробуйте это LD_LIBRARY_PATH=/vendor/lib:/system/lib перед установкой в ​​личку. Хорошо работает.

0 голосов
/ 13 февраля 2013

Я сделал тестовое приложение для автоматической установки, используя метод PackageManager.installPackage.

Я получил метод installPackage с помощью отражения и сделал интерфейс android.content.pm.IPackageInstallObserver в своей папке src (поскольку он скрыт вПакет android.content.pm).

Когда я запускаю installPackage, я получаю SecurityException со строковым указанием, что у моего приложения нет android.permission.INSTALL_PACKAGES, но оно определено в AndroidManifest.xml.

Так что, я думаю, использовать этот метод невозможно.

PS.Я тестировал Android SDK 2.3 и 4.0.Может быть, это будет работать с более ранними версиями.

...