Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem while opening Asset File with the help of Content Provider

My requirement is to open one app's Asset file from another app via content provider.(I am exposing that file with ContentProvider implementation)

I am able to open few files and read, but while opening some files I am getting exception. Please find the implementation for opening Asset File.

@Override
public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
    AssetManager am = getContext().getAssets();
    String file_name = uri.getLastPathSegment();
    if(file_name == null) 
        throw new FileNotFoundException();
    AssetFileDescriptor afd = null;
    try {
        afd = am.openFd(file_name);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return afd;//super.openAssetFile(uri, mode);
}

Some times, am.openFd(file_name); is throwing an exception saying that,

java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed
at android.content.res.AssetManager.openAssetFd(Native Method)
at android.content.res.AssetManager.openFd(AssetManager.java:329)
at com.pineone.swfinstaller.SwfProvider.openAssetFile(SwfProvider.java:25)
at android.content.ContentProvider$Transport.openAssetFile(ContentProvider.java:218)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:234)
at android.os.Binder.execTransact(Binder.java:288)
at dalvik.system.NativeStart.run(Native Method)

But, the same file I can open in my PC or even in Android device in some other manner.

Can anyone point out me, in what scenarios, we will get this exception.

Thanks in advance.

like image 204
Andhravaala Avatar asked Jul 05 '10 02:07

Andhravaala


People also ask

How do I access my content provider?

Accessing a provider. When you want to access data in a content provider, you use the ContentResolver object in your application's Context to communicate with the provider as a client. The ContentResolver object communicates with the provider object, an instance of a class that implements ContentProvider .

How do you read data from a content provider?

To access the data from a content provider, URI is used as a query string. Details of different parts of Content URI: content:// – Mandatory part of the URI as it represents that the given URI is a Content URI. authority – Signifies the name of the content provider like contacts, browser, etc.

What does a content provider do?

Content providers can help an application manage access to data stored by itself, stored by other apps, and provide a way to share data with other apps. They encapsulate the data, and provide mechanisms for defining data security.

Which of the following methods is used to initialize a content provider?

onCreate() which is called to initialize the provider.


1 Answers

Android tries to compress all assets, unless it's useless, like for *.mp3 files. I don't know if there is a complete list of filetypes that don't get compressed, but you should be fine if you just rename your files to .mp3 (the decision to compress or not is only based on the extension)

A little google search revealed:

http://osdir.com/ml/android-ndk/2010-04/msg00086.html

If you have sufficient control over the build process, you can use the "-0" flag with zip or aapt to add the assets.

-0  specifies an additional extension for which such files will not
    be stored compressed in the .apk.  An empty string means to not
    compress any files at all.

aapt is located in your

android-sdk\platforms\android-VERSION\tools

directory

from the link cited above:

static const char* kNoCompressExt[] = {
".jpg", ".jpeg", ".png", ".gif",
".wav", ".mp2", ".mp3", ".ogg", ".aac",
".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet",
".rtttl", ".imy", ".xmf", ".mp4", ".m4a",
".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2",
".amr", ".awb", ".wma", ".wmv"
};
like image 178
slup Avatar answered Sep 23 '22 05:09

slup