Open file downloaded within React-Native app with another app - react-native

I am trying to open files (images, pdfs, videos, etc) downloaded with my React-Native app from my server.
So I'm using RNFetchBlob to download the file then I'm doing the following depending if it's an iOS or Android device:
openFile = (item, path) => {
if (Platform.OS === 'ios') {
RNFetchBlob.ios.previewDocument(path)
} else {
// I've tried setting a real mimetype instead of / but it still doesn't work
RNFetchBlob.android.actionViewIntent(path, '/')
}
}
On iOS it works as expected but nothing happens on Android even though I have apps that can read images, pdfs or videos on the device I'm testing on.
Any ideas why this doesn't work or how I could make the same thing with another library ?

Found out the reason for this, it's a know bug of the library and has a PR waiting to be merged (no timeframe from the repo owner).
Here is the link to the PR: https://github.com/joltup/rn-fetch-blob/pull/317
So basically this needs to be added to line 122-123 of file android/src/main/java/com/RNFetchBlob/RNFetchBlob.java:
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
If above is not working do to the below step:
overwrite the 121 line in android/src/main/java/com/RNFetchBlob/RNFetchBlob.java:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 121 line
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // 122 line

Related

Expo, how to save file from app directory to local directory

Im new to React Native and im using Expo to create an iOS and Android app. All I want to do is save a file that is stored in the application to the users device.
Using downloadAsync and shareAsync I can download from a remote url and save it but I can not download or just share a local file stored in in the apps directory.
Ive tried
await shareAsync('file://./manuals/mypdf.pdf');
await shareAsync('./manuals/mypdf.pdf');
await shareAsync(require('./manuals/mypdf.pdf'));
and I get the error
[Unhandled promise rejection: Error: You don't have access to provided file.] or the app just crashes
Use loadAsync to download asset data to a local file in the device's cache directory. After that the asset file is accessible like any other file.
const [{ localUri }] = await Asset.loadAsync(require('./manuals/mypdf.pdf'));

decodeAudioData issue in Chrome

I have some simple web react-native code that opens a local audio file and then prints the duration.
var reader = new FileReader();
reader.onload = function (event) {
var context = new AudioContext();
var data = event.target.result
context.decodeAudioData(data, function (buffer) {
console.log(buffer.duration);
});
};
reader.readAsArrayBuffer(files[0]);
files[0] has the type File
The code is working in Safari 15.6.1 but will not work in Chrome 108 for .aif filetypes. If I try to run in Chrome with the same local .aif audio file, I get the following error message:
DOMException: Failed to execute 'decodeAudioData' on
'BaseAudioContext': Unable to decode audio data
What causes Chrome to break with .aif file types and what's the fix?
AIFF filetype variants have not been supported on many browsers for a while (circa 2019). Chrome, Firefox and Edge definitely ceased support around that time or earlier.
As AIFF is an Apple media format it is still supported by Safari, macOS and iOS.
There maybe a possibility to use 3rd party libraries (like Aurora.js) to get browsers to download codecs to open the AIFF formats. Of course that would require permissions etc. by end user.

react native file system, fs, cannot find taken pictures

In my ReactNative application I am using "react-native-vision-camera": "^2.13.5" for taking pictures.
After the picture is taken and uploaded, I want to delete it from the device, but the RNFS (react-native-fs) cannot find the file by the given path on iOS and Android devicess:
I get the error
iOS ; [Error: ENOENT: no such file or directory, open
'/private/var/mobile/Containers/Data/Application/1BB2256A-ED83-407D-9C76-07431268779B/tmp/ReactNative/CE2FA429-76C8-4BD9-925A-BED09B0B77BB.jpeg']
Android ; [Error: File does not exist]
The path in Android is like: /data/user/0/packagename/cache/mrousavy2423256141715663083.jpg
const photo = await camera.current.takePhoto(); // camera: React.RefObject<Camera>
const task = storage().ref(<ref>).putFile(photo.path)
const result = await task.then(); // Firebase Storage can read and upload the photo
RNFS.stat(photo.path) // <-- Error: The file “CE2FA429-76C8-4BD9-925A-BED09B0B77BB.jpeg” couldn’t be opened because there is no such file.
RNFS.unlink(photo.path) // <-- [Error: ENOENT: no such file or directory, open '/private/var/mobile/Containers/Data/Application/1BB2256A-ED83-407D-9C76-07431268779B/tmp/ReactNative/CE2FA429-76C8-4BD9-925A-BED09B0B77BB.jpeg']
// Prepending file:// Does not work too
RNFS.unlink(`file://${photo.path}`)
RNFS.stat(`file://${photo.path}`)
Is it because of access permission that react-native-fs needs?
How does the firebase storage have access to the photo?
Is the path a real temp folder that gets cleared after the app is closed?
why react-native-vision-camera saves media there by default?
Do I really need to remove that media manually or does it get removed?
env:
"react-native": "0.68.2",
"react-native-fs": "^2.20.0",
"react-native-vision-camera": "^2.13.5",
physical device : iPhone 8 Plus with iOS 15.5
There is no need to delete the file as the photos are being stored in a temporary directory. It will be deleted when the app closes.
https://mrousavy.com/react-native-vision-camera/docs/api/interfaces/PhotoFile
Instead of calling RNFS.unlink(photo.path) try RNFS.unlink(photo.uri). The react-native-vision-camera API outputs a File object with a URI not a path.

react-native-sound does not work on ios emulator

the below code works fine on android and the sound is played....however on ios simulator it does not.
Ive added my sound file to Xcode project, and no error is caught.....when I step through code, it runs this.sound.play() successfully and callback function is called...however you dont hear any sound.
import Sound from 'react-native-sound';
sound = new Sound('sound.mp3');
try {
this.sound.setCategory('Playback');
this.sound.play(() => {
this.sound.stop();
this.sound.release();
});
} catch (e) {
console.log('cannot play the sound file', e);
}
If you have the newest Xcode 11.6, did you try messing around with the settings in
Simulator > I/O > Audio Output
(if it's an older xcode, maybe Simulator > Hardware > Audio Output)?
Where you have put the sound file, please note that the sound clip files should be placed under the directory android/app/src/main/res/raw for android and For iOS, Add your sounds to Resources in Xcode project

MediaPlayer Error (1, -2147483648) android programing

I have been having some issues with my code to play html5 vide.
I created a short presentation in powerpoint and exported it html5, it contain a
video, I have copy the exported files into my assets files in android buy my video
is not playing.
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebChromeClient;
import android.webkit.WebViewClient;
public class WebViewActivity7 extends Activity {
private WebView webView7;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webview7);
webView7 = (WebView) findViewById(R.id.webView8);
webView7.getSettings().setJavaScriptEnabled(true);
webView7.getSettings().setAllowFileAccess(true);
webView7.getSettings().setPluginsEnabled(true);
webView7.getSettings().setAllowFileAccess(true);
webView7.setWebChromeClient(new WebChromeClient());
webView7.setWebViewClient(new WebViewClient());
webView7.getSettings().setBuiltInZoomControls(true);
webView7.loadUrl(url);
}
String url ="file:///android_asset/HTML5.html";
}
Everything else on my presentation works like a charm except the video, it does not play and i get the following error, when I tabbed on the video to play it on the scree on my android tablet - Android 4.0:
MediaPlayer Error (1, -2147483648)
I have been trying to get a solution to my problem for the last 5 days, I have read quite a few forums, change my code several times and nothing.
I found on a post that the reasons for the above error are:
File path is in error. Incorrect directory or Url or Uri found.
Media file is in error, incompatible format.
Missing permissions.
I have checked all the above on my app and still can't find how to solve it.
Everything else on my html5 file and folder works fine, so i don't think is a directory problem.
My embedded video files are .mp4 and .webm sand there are supposed to be supported.
I look at the permission of my files and folder and all seems to be fine.
I have an iPad version of my app working fine with the same html5 files and folder and the videos work fine.
Anyone have any idea how can I fix this problem, coding is supposed to be fun but after 5 days on this problems i am having second thoughts.
Thank you.
DPP
Addition to above:
I found in another forum that android does not allow to play video files larger than 1MB, Is this true? One of my videos is 3.2 MB and the other one is 29MB.
Answer:
the data about the video size is not true per what I have observed. I have set up my videos (Video files MP4 only with not HTML5 code) to play from the "res/raw" folder and it is all good. I just can't get them to play from the assets folder embedded on HTML5.
Still looking around for solutions, but having my videos on the "res/raw" folder it is a good alternative to my problem.
DPP
I have solved this problem by using copyAssets into sd card and running the index.HTML from the sdcard. see post Running an html5 site withing android app