--- a/app/src/main/AndroidManifest.xml Tue Jun 16 09:48:12 2015 +0200
+++ b/app/src/main/AndroidManifest.xml Tue Oct 27 01:04:13 2015 +0100
@@ -62,8 +62,12 @@
-->
<provider android:name=".providers.AvatarProvider"
android:authorities="com.beem.project.beem.providers.avatarprovider"
- android:exported="true"
- />
+ android:exported="false" android:grantUriPermissions="true" >
+
+ <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
+ android:resource="@xml/avatar_paths" />
+
+ </provider>
<service android:name="BeemService" android:enabled="true"
android:label="Beem Service" android:permission="com.beem.project.beem.BEEM_SERVICE">
--- a/app/src/main/java/com/beem/project/beem/providers/AvatarProvider.java Tue Jun 16 09:48:12 2015 +0200
+++ b/app/src/main/java/com/beem/project/beem/providers/AvatarProvider.java Tue Oct 27 01:04:13 2015 +0100
@@ -44,59 +44,20 @@
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;
-import android.database.Cursor;
-import android.database.MatrixCursor;
import android.net.Uri;
-import android.os.Environment;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
+import android.support.v4.content.FileProvider;
/**
* A simple content provider we expose the differents avatar downloaded.
*
*/
-public class AvatarProvider extends ContentProvider {
+public class AvatarProvider extends FileProvider {
/** The content uri of this provider. */
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";
-
- /**
- * Id of the user avatar.
- */
- public static final String MY_AVATAR_ID = "my_avatar";
-
-
- private static final String TAG = AvatarProvider.class.getSimpleName();
- private static final String AUTHORITY = "com.beem.project.beem.providers.avatarprovider";
-
- private static String[] columnNames = new String[] {Columns.ID, Columns.DATA};
-
- private static final int AVATAR = 1;
- private static final int AVATAR_ID = 2;
- private static final UriMatcher URIMATCHER = new UriMatcher(AVATAR);
-
- static
- {
- URIMATCHER.addURI(AUTHORITY, "*", AVATAR_ID);
- // should not be needed if we pass AVATAR on the constructor but it does not work
- URIMATCHER.addURI(AUTHORITY, null, AVATAR);
- }
-
- private String mDataPath;
+ Uri.parse("content://com.beem.project.beem.providers.avatarprovider/avatars/");
/**
* Create an AvatarProvider.
@@ -106,165 +67,10 @@
@Override
public boolean onCreate() {
- File cacheDir = Environment.getExternalStorageDirectory();
- File dataPath = new File(cacheDir, "/Android/data/com.beem.project.beem/cache/avatar");
- dataPath.mkdirs();
- mDataPath = dataPath.getAbsolutePath();
- return true;
- }
-
- @Override
- public ParcelFileDescriptor openFile(Uri uri, String mode)
- throws FileNotFoundException {
- return openFileHelper(uri, mode);
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
- MatrixCursor c = new MatrixCursor(columnNames);
- int match = URIMATCHER.match(uri);
- switch (match) {
- case AVATAR:
- File[] files = new File(mDataPath).listFiles();
- if (files != null) {
- for (File f : files) {
- c.newRow().add(f.getName()).add(f.getAbsolutePath());
- }
- }
- break;
- case AVATAR_ID:
- String id = uri.getPathSegments().get(0);
- File f = new File(mDataPath, id);
- if (f.exists() || MY_AVATAR_ID.equals(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;
- 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";
+ File cacheDir = getContext().getCacheDir();
+ File users = new File(cacheDir, "avatar/users");
+ users.mkdirs();
+ return super.onCreate();
}
}
--- a/app/src/main/java/com/beem/project/beem/service/BeemAvatarCache.java Tue Jun 16 09:48:12 2015 +0200
+++ b/app/src/main/java/com/beem/project/beem/service/BeemAvatarCache.java Tue Oct 27 01:04:13 2015 +0100
@@ -56,6 +56,7 @@
import android.database.Cursor;
import android.net.Uri;
+import android.provider.OpenableColumns;
import com.beem.project.beem.providers.AvatarProvider;
import com.beem.project.beem.smack.avatar.AvatarCache;
@@ -85,7 +86,6 @@
@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);
@@ -97,7 +97,6 @@
@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];
@@ -129,7 +128,12 @@
public boolean contains(String key) {
Uri uri = AvatarProvider.CONTENT_URI.buildUpon().appendPath(key).build();
Cursor c = mContentResolver.query(uri, null, null, null, null);
- boolean res = c.getCount() > 0;
+ boolean res = false;
+ if (c.moveToNext()) {
+ int sizeIdx = c.getColumnIndex(OpenableColumns.SIZE);
+ long size = c.getLong(sizeIdx);
+ res = size > 0;
+ }
c.close();
return res;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/res/xml/avatar_paths.xml Tue Oct 27 01:04:13 2015 +0100
@@ -0,0 +1,3 @@
+<paths xmlns:android="http://schemas.android.com/apk/res/android">
+ <cache-path name="avatars" path="avatar/users"/>
+</paths>