как задать путь, по которому команда aapt add добавляет файл

#path #add #aapt

#путь #Добавить #aapt

Вопрос:

Я использую инструмент aapt для удаления некоторых файлов из разных папок моего apk. Это работает нормально.

Но когда я хочу добавить файлы в apk, команда aapt tool add не позволяет мне указать путь, по которому я хочу добавить файл, поэтому я могу добавлять файлы только в корневую папку apk. Это странно, потому что я не думаю, что разработчики никогда не захотели бы добавлять файлы во вложенную папку apk (например, папку res). Возможно ли это с помощью aapt или любого другого метода? Причина удаления файлов из любой папки работает нормально, а добавление файла работает только для корневой папки apk. Не могу использовать это для любой другой папки.

Спасибо

Ответ №1:

Инструмент aapt сохраняет структуру каталогов, указанную в команде add, если вы хотите добавить что-либо в существующую папку в apk, у вас просто должна быть похожая папка в вашей системе, и вы должны указать каждый файл, чтобы добавить полный список каталогов. Пример

 $ aapt list test.apk
res/drawable-hdpi/pic1.png
res/drawable-hdpi/pic2.png
AndroidManifest.xml

$ aapt remove test.apk res/drawable-hdpi/pic1.png
$ aapt add test.apk res/drawable-hdpi/pic1.png
  

Добавляемый файл pic1.png находится в папке в текущем рабочем каталоге терминала res / drawable-hdpi / , надеюсь, это ответило на ваш вопрос

Комментарии:

1. Я уже написал свой собственный инструмент для замены aapt на то, что мне было нужно. Но спасибо за идею. Полезно знать на будущее. Я бы проголосовал за ваш ответ, но у меня пока нет необходимой репутации.

Ответ №2:

На самом деле в aapt есть ошибка, которая сделает это случайным образом невозможным. Предполагается, что это должно работать так, как утверждается в другом ответе: пути сохраняются, если вы не передадите -k . Давайте посмотрим, как это реализовано:

Флаг, который определяет, игнорируется ли путь, является mJunkPath :

 bool        mJunkPath;
  

Эта переменная находится в классе с именем Bundle и управляется двумя средствами доступа:

 bool getJunkPath(void) const { return mJunkPath; }
void setJunkPath(bool val) { mJunkPath = val; }
  

Если пользователь указал -k в командной строке, для него установлено значение true :

 case 'k':
    bundle.setJunkPath(true);
    break;
  

И, когда данные добавляются в файл, он проверяется:

 if (bundle->getJunkPath()) {
    String8 storageName = String8(fileName).getPathLeaf();
    printf(" '%s' as '%s'...n", fileName, storageName.string());
    result = zip->add(fileName, storageName.string(),
                      bundle->getCompressionMethod(), NULL);
} else {
    printf(" '%s'...n", fileName);
    result = zip->add(fileName, bundle->getCompressionMethod(), NULL);
}
  

К сожалению, один экземпляр, Bundle используемый приложением, выделен в main стеке, и в конструкторе нет инициализации mJunkPath , поэтому значение переменной является случайным; без способа явно установить его на false , в моей системе я (по-видимому, детерминированно) не могу добавлять файлы по указанным путям.

Однако вы также можете просто использовать zip , поскольку APK — это просто Zip-файл, и zip инструмент работает нормально.

(Для справки, я еще не отправил тривиальное исправление для этого в виде патча для Android, если кто-то еще захочет, мир, вероятно, станет лучше. Мой опыт работы с процессом отправки кода Android заключался в том, что мне приходилось мириться с невероятно сложным механизмом отправки, который в итоге занял шесть месяцев, прежде чем кто-то перезвонил мне, в некоторых случаях с незначительными изменениями, которые могли быть просто внесены с их стороны, если бы процесс отправки не был таким ужасно сложным. Учитывая, что существует действительно простое решение этой проблемы, я не считаю это достаточно важным, чтобы снова беспокоиться обо всем этом.)

Комментарии:

1. спасибо за информацию, Джей. Я, наконец, написал простой инструмент Java, который добавляет файл в apk (считая его [как вы сказали] zip), используя ZipInputStream и ZipEntry.

2. Я предполагаю, что под «zip tool» вы имеете в виду какой-либо инструмент с именем «zip», а не тип архива, потому что разархивировать apk и добавить некоторые файлы довольно просто, но сжать его обратно, а также создать вновь добавленные файлы, что невозможно с «zip» 😉 Для этого я использовал apktool.

3. Я не понимаю, что вы подразумеваете под «созданием вновь добавленных файлов»; в моем случае я добавляю такие вещи, как classes.dex (созданные с помощью dx ), в существующий APK с помощью zip my.apk classes.dex без проблем.

4. Например, если я захочу изменить значок моего приложения, просто заменив изображение значка в папке res / drawable, это не сработает. Я предполагаю, что новому ресурсу нужен идентификатор в автоматически сгенерированном классе R, который генерируется при сборке. Итак, я использовал apktool для декодирования apk, затем добавил свое новое изображение, а затем снова собрал apk, снова используя apktool.

5. Привет, Джей, у меня к тебе вопрос. Мне нужно удалить «classes.dex» из существующих файлов .apk в папке data / app. Затем мне нужно переупаковать его как обычный .apk. Я должен сделать это с помощью zipfile на java. Но что происходит, когда я запускаю его в эмуляторе, вместо исходного значка появляется какой-то фиктивный значок. Но переустановите папку и manifest.xml там есть все. Можете ли вы ввести некоторые входные данные??