inputstream - How to store large blobs in an android content provider? -


i have large files (images , video) need store in content provider. android documentation indicates...

if exposing byte data that's big put in table — such large bitmap file — field exposes data clients should contain content: uri string. field gives clients access data file. record should have field, named "_data" lists exact file path on device file. field not intended read client, contentresolver. client call contentresolver.openinputstream() on user-facing field holding uri item. contentresolver request "_data" field record, , because has higher permissions client, should able access file directly , return read wrapper file client. -- http://developer.android.com/guide/topics/providers/content-providers.html#creating

i having difficulty finding example. in particular wish use bitmap in context imageview. consider following code quasi-code (it doesn't work)...

imageview iv = .... string iconuri = cursor.getstring(cursor.getcolumnindex(table.icon)); iv.setimageuri(uri.parse(iconuri)); 

observations/problems...

  1. how can stored/recovered uri reconstructed correctly? (it text in table)
  2. the setimageuri implementation makes use of content resolve openinputstream should work.

    string scheme = muri.getscheme(); ... } else if (contentresolver.scheme_content.equals(scheme)         || contentresolver.scheme_file.equals(scheme)) {   try {     d = drawable.createfromstream(             mcontext.getcontentresolver().openinputstream(muri),             null); 

    --frameworks/base/core/java/android/widget/imageview.java

i got working. took hint mediastore , mediaprovider. files contain data named based on content provider (directory), column name, row id , media type. content resolver acquires file descriptor so...

uri iconuri = uri.withappendedpath(table.geturi(cursor), table.icon); ib.setimageuri(iconuri); 

...and content provider responds in kind...

@override public parcelfiledescriptor openfile (uri uri, string mode) { int imode = 0; if (mode.contains("w")) imode |= parcelfiledescriptor.mode_write_only; if (mode.contains("r")) imode |= parcelfiledescriptor.mode_read_only; if (mode.contains("+")) imode |= parcelfiledescriptor.mode_append; list<string> pseg = uri.getpathsegments(); if (pseg.size() < 3) return null;  try {     file filepath = filepathfromrecord(pseg.get(2), pseg.get(1));     return parcelfiledescriptor.open(filepath, imode); } catch (filenotfoundexception e) {     e.printstacktrace(); } return null; } 

the solution phreed gives in bottom half of question correct. i'll try add more details here.

when getcontentresolver().openinputstream(...), content resolver go content provider , call openfile method. how openfile looks in contentprovider.java:

public parcelfiledescriptor openfile(uri uri, string mode)      throws filenotfoundexception {  throw new filenotfoundexception("no files supported provider @ "          + uri); } 

so explains "no files supported ..." error comes from! around overriding openfile method in subclass , providing own implementation. it's neat: perfect control of files placed when client openinputstream or openoutputstream.

code sample in phreed's question gives hint how implementation like. here's modified version creates directories , files needed. i'm novice @ stuff might not optimal way of doing things, gives idea. 1 thing, should check if external storage available.

@override public parcelfiledescriptor openfile(uri uri, string mode) throws filenotfoundexception {     file root = new file(environment.getexternalstoragedirectory(),              "/android/data/com.example.myapp/cache");     root.mkdirs();     file path = new file(root, uri.getencodedpath());     // so, if uri content://com.example.myapp/some/data.xml,     // we'll end accessing /android/data/com.example.myapp/cache/some/data.xml      int imode = 0;     if (mode.contains("w")) {             imode |= parcelfiledescriptor.mode_write_only;             if (!path.exists()) {                 try {                     path.createnewfile();                 } catch (ioexception e) {                     // todo decide it, whom notify...                     e.printstacktrace();                 }             }     }     if (mode.contains("r")) imode |= parcelfiledescriptor.mode_read_only;     if (mode.contains("+")) imode |= parcelfiledescriptor.mode_append;              return parcelfiledescriptor.open(path, imode); } 

Comments

Popular posts from this blog

ASP.NET/SQL find the element ID and update database -

jquery - appear modal windows bottom -

c++ - Compiling static TagLib 1.6.3 libraries for Windows -