Skip to content

Commit 62c93f7

Browse files
authored
Merge pull request #149 from elimu-ai/feat/support_scoped_storage_images_sharing
[feat] Support scoped storage when sharing images #148
2 parents 0d6edfd + 9bab2b9 commit 62c93f7

File tree

5 files changed

+72
-5
lines changed

5 files changed

+72
-5
lines changed

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ apply plugin: 'com.android.application'
22
apply plugin: 'org.ajoberstar.grgit'
33

44
android {
5-
compileSdk 34
5+
compileSdk 35
66
namespace 'ai.elimu.content_provider'
77

88
defaultConfig {
99
applicationId "ai.elimu.content_provider"
1010
minSdkVersion 24
11-
targetSdkVersion 34
11+
targetSdkVersion 35
1212
versionCode 1002029
1313
versionName "1.2.29-SNAPSHOT"
1414
setProperty("archivesBaseName", "${applicationId}-${versionCode}")

app/src/main/AndroidManifest.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,12 @@
5252
android:name=".provider.ImageContentProvider"
5353
android:authorities="${applicationId}.provider.image_provider"
5454
android:enabled="true"
55-
android:exported="true" />
55+
android:exported="true"
56+
android:grantUriPermissions="true">
57+
<meta-data
58+
android:name="android.support.FILE_PROVIDER_PATHS"
59+
android:resource="@xml/image_file_path"/>
60+
</provider>
5661
<provider
5762
android:name=".provider.AudioContentProvider"
5863
android:authorities="${applicationId}.provider.audio_provider"

app/src/main/java/ai/elimu/content_provider/provider/ImageContentProvider.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,18 @@
66
import android.content.UriMatcher;
77
import android.database.Cursor;
88
import android.net.Uri;
9+
import android.os.ParcelFileDescriptor;
910
import android.util.Log;
1011

12+
import java.io.File;
13+
import java.io.FileNotFoundException;
1114
import java.util.List;
1215

1316
import ai.elimu.content_provider.BuildConfig;
1417
import ai.elimu.content_provider.room.dao.ImageDao;
1518
import ai.elimu.content_provider.room.db.RoomDb;
19+
import ai.elimu.content_provider.room.entity.Image;
20+
import ai.elimu.content_provider.util.FileHelper;
1621

1722
public class ImageContentProvider extends ContentProvider {
1823

@@ -24,6 +29,7 @@ public class ImageContentProvider extends ContentProvider {
2429
private static final int CODE_IMAGES_BY_WORD_LABEL_ID = 3;
2530

2631
private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
32+
private String TAG = ImageContentProvider.class.getName();
2733

2834
static {
2935
MATCHER.addURI(AUTHORITY, TABLE_IMAGES, CODE_IMAGES);
@@ -150,4 +156,41 @@ public int delete(Uri uri, String selection, String[] selectionArgs) {
150156

151157
throw new UnsupportedOperationException("Not yet implemented");
152158
}
159+
160+
@Override
161+
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
162+
List<String> segments = uri.getPathSegments();
163+
if (segments.size() < 2) {
164+
throw new FileNotFoundException("Invalid URI: " + uri);
165+
}
166+
String fileId = segments.get(1);
167+
168+
RoomDb roomDb = RoomDb.getDatabase(getContext());
169+
ImageDao imageDao = roomDb.imageDao();
170+
171+
long imageId;
172+
try {
173+
imageId = Long.parseLong(fileId);
174+
} catch (NumberFormatException e) {
175+
Log.e(TAG, "Failed to parse image ID: " + fileId, e);
176+
throw new FileNotFoundException("Invalid image ID format: " + fileId);
177+
}
178+
179+
Image image = imageDao.load(imageId);
180+
181+
if (image == null) {
182+
throw new FileNotFoundException("File not found with id: " + imageId);
183+
}
184+
185+
File imageFile = FileHelper.getImageFile(image, getContext());
186+
if (imageFile == null) {
187+
throw new FileNotFoundException("imageFile not found with id: " + imageId);
188+
}
189+
if (!imageFile.exists()) {
190+
Log.e(TAG, "imageFile doesn't exist: " + imageFile.getAbsolutePath());
191+
throw new FileNotFoundException("File not found: " + imageFile.getAbsolutePath());
192+
}
193+
return ParcelFileDescriptor.open(imageFile, ParcelFileDescriptor.MODE_READ_ONLY);
194+
}
195+
153196
}

app/src/main/java/ai/elimu/content_provider/util/FileHelper.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
import android.content.Context;
44
import android.os.Environment;
55

6+
import androidx.annotation.RestrictTo;
7+
68
import java.io.File;
79

10+
import ai.elimu.content_provider.room.entity.Image;
811
import ai.elimu.model.v2.gson.content.AudioGson;
912
import ai.elimu.model.v2.gson.content.ImageGson;
1013
import ai.elimu.model.v2.gson.content.VideoGson;
@@ -19,8 +22,20 @@ public static File getImageFile(ImageGson imageGson, Context context) {
1922
return null;
2023
}
2124
File imagesDirectory = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
22-
File file = new File(imagesDirectory, imageGson.getId() + "_r" + imageGson.getRevisionNumber() + "." + imageGson.getImageFormat().toString().toLowerCase());
23-
return file;
25+
return new File(imagesDirectory, imageGson.getId()
26+
+ "_r" + imageGson.getRevisionNumber() + "."
27+
+ imageGson.getImageFormat().toString().toLowerCase());
28+
}
29+
30+
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
31+
public static File getImageFile(Image imageGson, Context context) {
32+
if ((imageGson.getId() == null) || (imageGson.getRevisionNumber() == null)) {
33+
return null;
34+
}
35+
File imagesDirectory = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
36+
return new File(imagesDirectory, imageGson.getId()
37+
+ "_r" + imageGson.getRevisionNumber() + "."
38+
+ imageGson.getImageFormat().toString().toLowerCase());
2439
}
2540

2641
public static File getAudioFile(AudioGson audioGson, Context context) {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<paths>
3+
<external-files-path name="pictures" path="Pictures/" />
4+
</paths>

0 commit comments

Comments
 (0)