Complete the avatar provider to support insert update and delete.
It is now usable following the standard Android interface.
--- 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";
+ }
+
}
--- 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];