moberwasserlechner / capacitor-filesharer

Capacitor plugin to download and share files for the Web, Android and iOS! Stop the war in Ukraine!
MIT License
82 stars 20 forks source link

Bug: Writing exception to parcel on Android #52

Open pkzOR opened 8 months ago

pkzOR commented 8 months ago

Capacitor version:

Capacitor Doctor

Latest Dependencies:       

  @capacitor/cli: 5.6.0    
  @capacitor/core: 5.6.0   
  @capacitor/android: 5.6.0
  @capacitor/ios: 5.6.0    

Installed Dependencies:    

  @capacitor/cli: 4.6.1    
  @capacitor/core: 4.7.1   
  @capacitor/android: 4.8.0
  @capacitor/ios: 4.6.1    

[success] Android looking great! 👌
[error] Xcode is not installed

Library version:

Your Plugin Configuration

{
   import { FileSharer, type ShareFileOptions } from '@byteowls/capacitor-filesharer';

  public async shareFile(fileUrl:string, shareFilename:string,  contentType: string) {
 try {

      const copyOfSharedFile  = await Filesystem.copy({
        from: fileUrl!,
        to: shareFilename,
        toDirectory: Directory.Data
      });

      const base64FileContents =  await this.readFileAsBase64(copyOfSharedFile ); 
      if(base64FileContents === null || base64FileContents.length === 0){
        throw new Error('Error sharing file. Unable to readFileAsBase64');
      }

      const shareOptions: ShareFileOptions = {filename: shareFilename, contentType:contentType, path:copyOfSharedFile.uri, base64Data:base64FileContents};
      await FileSharer.share(shareOptions);
      await Filesystem.deleteFile({path: copyOfSharedFile.uri, directory:Directory.Data});
    } catch (error) {
      const errMsg =  <string> error;
      if(errMsg == 'USER_CANCELLED'){
        toastr.info('Cancelled');
        return;
      }
      throw new Error('Error sharing log file:' +  <string> error);
    }
  }

  async readFileAsBase64(file: CopyResult): Promise<string> {
    try {
      const fileStat = await Filesystem.stat({
        path: file.uri,
      });

      if (!fileStat || !fileStat.size) {
        throw new Error ('Error sharing file: file does not exist or is empty.');
      }

      const fileData = await Filesystem.readFile({ path: file.uri });

      if (!fileData || !fileData.data) {
        throw new Error('Error sharing file: Unable to read file data.');
      }

      return fileData.data;//base64
    } catch (error) {
      const errMsg = <string> error;
      throw new Error(errMsg);
    }
  }
}

Affected Platform(s):

Current Behavior

A sqlite db is copied to a backup file and the backup file is shared. This works. However, when reviewing the Android LogCat is see: Writing exception to parcel java.lang.SecurityException: Permission Denial: reading com.byteowls.capacitor.filesharer.FileSharerProvider uri content://com.xxx.yyy.zzz.filesharer.fileprovider/capfilesharer/myLog-20231227-093441.db from pid=14783, uid=1000 requires the provider be exported, or grantUriPermission() at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:918) at android.content.ContentProvider.semEnforceReadPermission(ContentProvider.java:836) at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:712) at android.content.ContentProvider$Transport.query(ContentProvider.java:251) at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:107) at android.os.Binder.execTransactInternal(Binder.java:1316) at android.os.Binder.execTransact(Binder.java:1280) 2023-12-27 09:34:43.039 14783-14783 ChooserActivity android:ui W Could not load (content://com.xxx.yyy.zzz.filesharer.fileprovider/capfilesharer/myLog-20231227-093441.db) thumbnail/name for preview. If desired, consider using Intent#createChooser to launch the ChooserActivity, and set your Intent's clipData and flags in accordance with that method's documentation 2023-12-27 09:34:43.044 14502-14521 DatabaseUtils com.xxx.yyy.zzz E Writing exception to parcel java.lang.SecurityException: Permission Denial: reading com.byteowls.capacitor.filesharer.FileSharerProvider uri content://com.xxx.yyy.zzz.filesharer.fileprovider/capfilesharer/myLog-20231227-093441.db from pid=14783, uid=1000 requires the provider be exported, or grantUriPermission() at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:918) at android.content.ContentProvider.semEnforceReadPermission(ContentProvider.java:836) at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:712) at android.content.ContentProvider$Transport.query(ContentProvider.java:251) at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:107) at android.os.Binder.execTransactInternal(Binder.java:1316) at android.os.Binder.execTransact(Binder.java:1280)

Expected Behavior

No errors in logcat.

Sample Code or Sample Application Repo

see above

Reproduction Steps

share a file on Android, review the logcat in Android Studio.

Other Information

I dont think I need to add grantUriPermission in my app... but maybe.