# HG changeset patch # User Da Risk # Date 1327618486 -3600 # Node ID 24474027eb455adf209f2e56a9ec494bdbf5f7ee # Parent f27ce0166608590cd896a261bd3e001ba4fc1dad Complete the avatar provider to support insert update and delete. It is now usable following the standard Android interface. diff -r f27ce0166608 -r 24474027eb45 src/com/beem/project/beem/providers/AvatarProvider.java --- a/src/com/beem/project/beem/providers/AvatarProvider.java Tue Feb 21 21:07:42 2012 +0100 +++ b/src/com/beem/project/beem/providers/AvatarProvider.java Thu Jan 26 23:54:46 2012 +0100 @@ -43,6 +43,10 @@ */ package com.beem.project.beem.providers; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + import android.content.ContentProvider; import android.content.ContentValues; import android.content.UriMatcher; @@ -53,8 +57,6 @@ import android.os.ParcelFileDescriptor; import android.util.Log; -import java.io.File; -import java.io.FileNotFoundException; /** * A simple content provider we expose the differents avatar downloaded. @@ -66,19 +68,17 @@ public static final Uri CONTENT_URI = Uri.parse("content://com.beem.project.beem.providers.avatarprovider"); + /** The MIME type of a CONTENT_URI directory of Beem avatars. */ + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.com.beem.project.beem.avatar"; + + /** The MIME type of a CONTENT_URI subdirectory of a single Beem avatar. */ + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.com.beem.project.beem.avatar"; + + private static final String TAG = AvatarProvider.class.getSimpleName(); private static final String AUTHORITY = "com.beem.project.beem.providers.avatarprovider"; - /** - * The differents columns available in the AvatarProvider. - */ - public static interface Columns { - - /** The id of the avatar. */ - String ID = "_id"; - } - - private static String[] columnNames = new String[] {Columns.ID }; + private static String[] columnNames = new String[] {Columns.ID, Columns.DATA}; private static final int AVATAR = 1; private static final int AVATAR_ID = 2; @@ -99,40 +99,6 @@ public AvatarProvider() { } - /** - * Translate the mode passed to {@link #openFile} into mode passed to {@link ParcelFileDescriptor#open}. - * - * @param uri the uri to open - * @param mode the mode - * @return the mode - * @throws FileNotFoundException if the mode passed is illegal - */ - public static int modeToMode(Uri uri, String mode) throws FileNotFoundException { - int modeBits; - if ("r".equals(mode)) { - modeBits = ParcelFileDescriptor.MODE_READ_ONLY; - } else if ("w".equals(mode) || "wt".equals(mode)) { - modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY - | ParcelFileDescriptor.MODE_CREATE - | ParcelFileDescriptor.MODE_TRUNCATE; - } else if ("wa".equals(mode)) { - modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY - | ParcelFileDescriptor.MODE_CREATE - | ParcelFileDescriptor.MODE_APPEND; - } else if ("rw".equals(mode)) { - modeBits = ParcelFileDescriptor.MODE_READ_WRITE - | ParcelFileDescriptor.MODE_CREATE; - } else if ("rwt".equals(mode)) { - modeBits = ParcelFileDescriptor.MODE_READ_WRITE - | ParcelFileDescriptor.MODE_CREATE - | ParcelFileDescriptor.MODE_TRUNCATE; - } else { - throw new FileNotFoundException("Bad mode for " + uri + ": " - + mode); - } - return modeBits; - } - @Override public boolean onCreate() { File cacheDir = Environment.getExternalStorageDirectory(); @@ -145,10 +111,7 @@ @Override public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { - String id = uri.getPath(); - File data = new File(mDataPath, id); - int modeBits = AvatarProvider.modeToMode(uri, mode); - return ParcelFileDescriptor.open(data, modeBits); + return openFileHelper(uri, mode); } @Override @@ -160,7 +123,7 @@ File[] files = new File(mDataPath).listFiles(); if (files != null) { for (File f : files) { - c.newRow().add(f.getName()); + c.newRow().add(f.getName()).add(f.getAbsolutePath()); } } break; @@ -168,37 +131,135 @@ String id = uri.getPathSegments().get(0); File f = new File(mDataPath, id); if (f.exists()) - c.newRow().add(f.getName()); + c.newRow().add(f.getName()).add(f.getAbsolutePath()); break; default: Log.w(TAG, "Unsupported uri for query match = " + match); } + if (c != null) + c.setNotificationUri(getContext().getContentResolver(), uri); return c; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + int match = URIMATCHER.match(uri); + String id = null; + switch (match) { + case AVATAR_ID: + id = uri.getPathSegments().get(0); + break; + default: + Log.w(TAG, "Unsupported uri for query match = " + match); + } + + if (id == null) + return 0; + + File f = new File(mDataPath, id); + try { + f.createNewFile(); + getContext().getContentResolver().notifyChange(uri, null); + return 1; + } catch (IOException e) { + Log.e(TAG, "Error while creating file", e); + } return 0; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { int res = 0; - String id = uri.getPath(); - File data = new File(mDataPath, id); - if (data.exists() && data.delete()) { - res++; + boolean all = false; + String id = null; + int match = URIMATCHER.match(uri); + switch (match) { + case AVATAR_ID: + id = uri.getPathSegments().get(0); + break; + case AVATAR: + all = true; + break; + default: + Log.w(TAG, "Unsupported uri for query match = " + match); } + File[] list = null; + if (id != null) { + list = new File[] {new File(mDataPath, id) }; + } else if (all) { + list = new File(mDataPath).listFiles(); + } + + if (list == null) + return res; + for (File data : list) { + if (data.exists() && data.delete()) + res++; + } + if (res > 0) + getContext().getContentResolver().notifyChange(uri, null); return res; } @Override public Uri insert(Uri uri, ContentValues values) { + int match = URIMATCHER.match(uri); + String id = null; + Uri result = null; + switch (match) { + case AVATAR: + id = values.getAsString(Columns.ID); + result = Uri.withAppendedPath(uri, id); + break; + case AVATAR_ID: + id = uri.getPathSegments().get(0); + result = uri; + break; + default: + Log.w(TAG, "Unsupported uri for query match = " + match); + } + if (id == null) + return null; + + File f = new File(mDataPath, id); + try { + f.createNewFile(); + if (result != null) + getContext().getContentResolver().notifyChange(result, null); + return result; + } catch (IOException e) { + Log.e(TAG, "Error while creating file", e); + } return null; } @Override public String getType(Uri uri) { + int match = URIMATCHER.match(uri); + switch (match) { + case AVATAR: + return CONTENT_TYPE; + case AVATAR_ID: + return CONTENT_ITEM_TYPE; + default: + Log.w(TAG, "Unsupported uri for query match = " + match); + } return null; } + + /** + * The differents columns available in the AvatarProvider. + */ + public interface Columns { + + /** The id of the avatar. + * type: string */ + String ID = "_id"; + + /** The path of the avatar file. + * type: string + * This field is readonly */ + String DATA = "_data"; + } + } diff -r f27ce0166608 -r 24474027eb45 src/com/beem/project/beem/service/BeemAvatarCache.java --- a/src/com/beem/project/beem/service/BeemAvatarCache.java Tue Feb 21 21:07:42 2012 +0100 +++ b/src/com/beem/project/beem/service/BeemAvatarCache.java Thu Jan 26 23:54:46 2012 +0100 @@ -43,6 +43,13 @@ */ package com.beem.project.beem.service; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + import android.content.ContentResolver; import android.content.Context; @@ -53,12 +60,6 @@ import com.beem.project.beem.providers.AvatarProvider; import com.beem.project.beem.smack.avatar.AvatarCache; -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.io.IOException; -import java.io.OutputStream; /** * An implementation of an AvatarCache which store the data of the filesystem. @@ -84,6 +85,7 @@ @Override public void put(String key, byte[] data) throws IOException { Uri uri = AvatarProvider.CONTENT_URI.buildUpon().appendPath(key).build(); + mContentResolver.insert(uri, null); OutputStream os = new BufferedOutputStream(mContentResolver.openOutputStream(uri)); try { os.write(data); @@ -95,6 +97,7 @@ @Override public void put(String key, InputStream in) throws IOException { Uri uri = AvatarProvider.CONTENT_URI.buildUpon().appendPath(key).build(); + mContentResolver.insert(uri, null); OutputStream os = new BufferedOutputStream(mContentResolver.openOutputStream(uri)); try { byte[] data = new byte[1024];