capacitor-community / media

Capacitor plugin for saving and retrieving photos and videos, and managing photo albums.
https://www.npmjs.com/package/@capacitor-community/media
103 stars 50 forks source link

Error while copying media file #66

Closed fireonmac closed 10 months ago

fireonmac commented 1 year ago

File: MediaPlugin Line: 299 Code fragment:

try {
    // generate image file name using current date and time
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmssSSS").format(new Date());
    String fileName = call.getString("fileName", "IMG_" + timeStamp);
    File expFile = copyFile(inputFile, albumDir, fileName);
    scanPhoto(expFile);

    JSObject result = new JSObject();
    result.put("filePath", expFile.toString());
    call.resolve(result);
} catch (RuntimeException e) {
    call.reject(e.getLocalizedMessage(), null, e); // I changed this line to get the error message in javascript layer.
}

Explanation. Some of Android users can't download media files regardress of OS versions. I couldn't reproduce this error on my devices. Error logs starting with "RuntimeException occurred ..." didn't help at all, so to check the detailed error message I changed the catch clause in the plugin file and attached the new logs reported on my server below.

# case 1 
[Error]
Copy file not found: /storage/emulated/0/iPhoneData/Pictures/학교종이/IMG_20230830_152558883.jpg, error: /storage/emulated/0/iPhoneData/Pictures/학교종이/IMG_20230830_152558883.jpg: open failed: EPERM (Operation not permitted)

[Parms] 
path: file:///storage/emulated/0/Android/data/com.schoolbell_e.schoolbell_e/files/intermediate.jpg
albumIdentifier: 학교종이

[Device info]
"os_version": "13",
"app_version": "5.0.51",
"device": "SM-F731N",

# case 2 
[Error]
Copy file not found: /storage/emulated/0/학교종이/IMG_20230830_144007181.jpg, error: /storage/emulated/0/학교종이/IMG_20230830_144007181.jpg: open failed: EPERM (Operation not permitted)

[Parms] 
path: file:///storage/emulated/0/Android/data/com.schoolbell_e.schoolbell_e/files/cdv_photo_000_high.jpg
albumIdentifier: 학교종이

[Device info]
"platform": "android",
"os_version": "13",

"device": "SM-S908N",

# case 3
[Error]
Copy file not found: /storage/emulated/0/학교종이/IMG_20230830_125834428.jpg, error: /storage/emulated/0/학교종이/IMG_20230830_125834428.jpg: open failed: EPERM (Operation not permitted)

[Parms] 
path: file:///storage/emulated/0/Android/data/com.schoolbell_e.schoolbell_e/files/%EA%B5%90%EC%9C%A1%EA%B3%B5%EB%8F%99%EC%B2%B4%EC%9D%98%20%EB%82%A0%20%EC%95%88%EB%82%B4%EB%AC%B8001.jpg
albumIdentifier: 학교종이

[Device info]
"platform": "android",
"os_version": "13",
"device": "SM-G996N",
nkalupahana commented 1 year ago

Looks like the common thread between the devices is that they're on Android 13. Do you have the following in your manifest?

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
fireonmac commented 1 year ago

The 'getAlbums()' method seems to retrieve all albums, not just those within the application specific path, but also from other paths that require MANAGE_EXTERNAL_STORAGE permission to access. Certain Android users with a version above 10 are encountering crashes, presumably because there are albums with identical names located outside of the designated path for the app. (storage/emulated/.../com.schoolbell_e.schoolbell_e/...)

nkalupahana commented 1 year ago

Got it, okay. getAlbums returning all albums is expected behavior. I think the best course of action, then, is to check for your bundle ID in getAlbums calls on Android when filtering.

jabi11 commented 1 year ago

Hi, I'm also running into same issue. Any ETA when it will be fixed?

fireonmac commented 1 year ago

Hi, I'm also running into same issue. Any ETA when it will be fixed?

I may need to do some more tracking, but it seems that checking the bundle ID on Android 10 and above versions could resolve the issue.

fireonmac commented 1 year ago

Android users with a version under 9 don't need bundle ID, but still get the permission error when they use any album in the external storage of SD card. (https://developer.android.com/about/versions/11/privacy/storage)

[Android 9 Test] getAlbums: Internal(O) External(O) copyFile: Internal(O) External(X)

[Error] Copy file not found: /storage/6439-3263/Gallery/학교종이/IMG_20230912_152806379.jpg, error: /storage/6439-3263/Gallery/학교종이/IMG_20230912_152806379.jpg (Permission denied)

nkalupahana commented 1 year ago

@fireonmac are you saying this issue shows up for all albums, including ones you created using the app, or just when album names conflict? I'm confused about the status of this issue right now.

fireonmac commented 1 year ago

@nkalupahana I think the problem is the album name conflict. Is it intentional that user can't save image to albums in external storage? The problem I encountered was some of my users copied the folder by using file explorer and paste it in SD card, so those are recognized when getAlbums() called though it's in external, but users can't copy files from there due to the lack of permission to access.

nkalupahana commented 1 year ago

Maybe you need to specify a different permission in your manifest? Not sure what that would be though.

If the problem is an album name conflict, I would also recommend using a different album name that's less likely to conflict, or using some URL parser to determine what storage volume the album is on.

I've also been considering adding a getAlbumPath() function or similar, that would return the path that the plugin stores its albums at. Then, you could just use that to compare the path. If that would be useful, please let me know.

nkalupahana commented 10 months ago

@fireonmac let me know if this would be useful, or if you need any help! Otherwise, I'll close this issue.