Proguard breaking audio file in assets or raw
Asked Answered
S

3

7

I have an activity that plays a beep sound with MediaPlayer that works fine and used to work fine even in the proguarded production version. With the latest release it now suddenly crashes with

Caused by: android.content.res.Resources$NotFoundException: File res/raw/beep.ogg from drawable resource ID #0x7f060000
at android.content.res.Resources.openRawResourceFd(Resources.java:994)
at android.media.MediaPlayer.create(MediaPlayer.java:855)
at com.digikey.mobile.activity.CaptureActivity.onCreate(SourceFile:135)
at android.app.Activity.performCreate(Activity.java:5206)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2064)
... 11 more
Caused by: java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed
at android.content.res.AssetManager.openNonAssetFdNative(Native Method)
at android.content.res.AssetManager.openNonAssetFd(AssetManager.java:428)
at android.content.res.Resources.openRawResourceFd(Resources.java:991)
... 16 more

I tried a number of different ways of loading and playing the sound including storing it in assets instead of the original res/raw and they all work when I use in the app that has not been proguarded but they all fail with the release version that is proguarded/zipaligned and signed.

My proguard file is rather large and it does contain the often suggested fix of

-keepclassmembers class **.R$* {public static <fields>;}
-keep class **.R$*

Anybody have any ideas or encountered something like this before?

Update: I also tried with mp3 files and it has the same problems.

Update 2: An interesting thing is that it seem to take quite a while (close to 1s) to crash with this message. As if it is searching or processing some file or something .. but the file is really small so its weird.

Slipstream answered 29/1, 2014 at 19:21 Comment(4)
How big is this file? Also, have you fiddled with any aapt switches as part of some custom build script?Reformed
Its extremely small and I have not fiddled with aapt switches. But I am using the Android Maven Plugin as you can imagine. Is there any aapt switch that might be useful?Slipstream
It's more that it feels like this file is getting compressed when it shouldn't be. aapt always used to be aware of .ogg files and did not compress them. I have no idea why/how ProGuard/zipalign would affect that. The exception would be if you're using DexGuard instead of ProGuard, as I don't know what impact their resource encryption might have on matters.Reformed
Getting the same problem with mp3 files btw. and just using ProGuard only.Slipstream
B
17

The error suggests that the zip entry beep.ogg is compressed, when it shouldn't be.

Individual entries in zip files can optionally be compressed. This compression is typically transparent to the application that reads the zip file. However, Android accesses some types of files (like .ogg and .mp3) directly, without unpacking them, which only works if they are not compressed.

You can see which entries are compressed with

unzip -lv MyApplication.apk

In the column 'Method', 'Defl' means compressed and 'Stored' means uncompressed.

ProGuard doesn't perform the final packaging of the apk file -- aapt, apkbuilder, jarsigner, zipalign, and possible post-processing steps do. At the proper stages, they should leave .ogg and .mp3 files uncompressed. You may need to check their integration in the Maven build process.

DexGuard incidentally does perform the final packaging. It has an option -dontcompress to control which files or file types are left uncompressed. The default configuration leaves .ogg and .mp3 files uncompressed.

(I am the developer of ProGuard and DexGuard)

Update by Manfred Moser:

This was indeed the problem. Turns out that this has nothing to do with the proguard integration or the Android Maven Plugin. The problem was caused by the Maven Jarsigner Plugin configuration I used. I had set removeExistingSignatures to true, which is not the default value and caused all files in the archive to be compressed. I consider this a weird bug of the jarsigner plugin at this stage. In any case... the default config is to for this parameter to be set to false so nobody should have any problem ... unless of course you set it to true like I did ;-)

Bracket answered 2/2, 2014 at 11:15 Comment(5)
Thanks for answering Eric. I will have to investigate this further. PS I of course know that you are the author of ProGuard ;-)Slipstream
Wow... unbelievable. I did a check and it seems that everything is compressed now. This is probably some regression in the Android Maven Plugin I manage so I will go for a bug hunt now ;-) Thanks a LOT Eric.Slipstream
And for the benefit of others I am using 3.8.2 of the Android Maven Plugin. Once I figure out the problem I will post here and the mailing list.Slipstream
Proguard obfuscate my db file which is under assets folder. Can you please give me any way to avoid assets's file obfuscation? Or something else to prevent my assets folder from proguard.Dumbstruck
Fixed by excluding the model classes from proguard.Dumbstruck
C
7

I had a similar case where my app regressed after ProGuard (even in debug? though I've explicitly turned it off).

08-30 22:10:32.360 561-18619/? E/FileSource: Failed to open file 'android.resource://com.mycompany.myapp/2131230720'. (No such file or directory)

Eventually I had to add keep.xml file as suggested here under Customizing Which Resources to Keep

with something like (@ /res/raw/keep.xml):

    <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@raw/*">
</resources>

You can ofcourse set it more explicitly but I only had mp3's on my RAW folder.

My unzip -lv app-release.apk was showing my mp3 files as:

0 Stored 0 0% 00-00-1980 00:00 00000000 res/raw/audio.mp3

which was odd (0 bytes?!).

Callous answered 30/8, 2017 at 19:47 Comment(0)
M
1

I find it odd that it is telling you that is a drawable resource:

File res/raw/beep.ogg from drawable resource ID

I think you need to tell it to also keep the R class. This is what I use in an app that also loads .ogg files from raw.

-keep class *.R

-keepclasseswithmembers class **.R$* {
    public static <fields>;
}
Marsupium answered 29/1, 2014 at 20:32 Comment(2)
This is already configured like you can see in the question and yes.. the error message is odd.Slipstream
No, this configuration is different from yours.Marsupium

© 2022 - 2024 — McMap. All rights reserved.