Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to set the path to where aapt add command adds the file

Tags:

path

add

aapt

I'm using aapt tool to remove some files from different folders of my apk. This works fine.

But when I want to add files to the apk, the aapt tool add command doesn't let me specify the path to where I want the file to be added, therefore I can add files only to the root folder of the apk. This is strange because I don't think that developers would never want to add files to a subfolder of the apk (res folder for example). Is this possible with aapt or any other method? Cause removing files from any folder works fine, and adding file works only for the root folder of the apk. Can't use it for any other folder.

Thanks

like image 848
philtz Avatar asked Jun 02 '11 15:06

philtz


2 Answers

The aapt tool retains the directory structure specified in the add command, if you want to add something to an existing folder in an apk you simply must have a similar folder on your system and must specify each file to add fully listing the directory. Example

$ 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

The pic1.png that will is added resides in a folder in the current working directory of the terminal res/drawable-hdpi/ , hope this answered your question

like image 200
ReenignE Avatar answered Oct 20 '22 18:10

ReenignE


There is actually a bug in aapt that will make this randomly impossible. The way it is supposed to work is as the other answer claims: paths are kept, unless you pass -k. Let's see how this is implemented:

The flag that controls whether the path is ignored is mJunkPath:

bool        mJunkPath;

This variable is in a class called Bundle, and is controlled by two accessors:

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

If the user specified -k at the command line, it is set to true:

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

And, when the data is being added to the file, it is checked:

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

Unfortunately, the one instance of Bundle used by the application is allocated in main on the stack, and there is no initialization of mJunkPath in the constructor, so the value of the variable is random; without a way to explicitly set it to false, on my system I (seemingly deterministically) am unable to add files at specified paths.

However, you can also just use zip, as an APK is simply a Zip file, and the zip tool works fine.

(For the record, I have not submitted the trivial fix for this as a patch to Android yet, if someone else wants to the world would likely be a better place. My experience with the Android code submission process was having to put up with an incredibly complex submission mechanism that in the end took six months for someone to get back to me, in some cases with minor modifications that could have just been made on their end were their submission process not so horribly complex. Given that there is a really easy workaround to this problem, I do not consider it important enough to bother with all of that again.)

like image 8
Jay Freeman -saurik- Avatar answered Oct 20 '22 18:10

Jay Freeman -saurik-