App is crashing when i try to download in realme devices (Android 9)
Hi Please help me to solve the problem , When i try to download file, app is crashing it is happening in realme devices (Android 9 & 10) only "rn-fetch-blob": "^0.12.0", "react-native": "0.63.2", SAmple Code .
RNFetchBlob
.config({
fileCache: true,
addAndroidDownloads: {
useDownloadManager: true,
notification: true,
mediaScannable: true,
title: fileName,
path: `${downloadDest}/${fileName}`,
},
})
.fetch("GET", url, {}).then(result => {
);
})
Crash Log
com.facebook.react.bridge.CallbackImpl.invoke CallbackImpl.java, line 26 java.lang.RuntimeException: Illegal callback invocation from native module. This callback type only permits a single invocation from native code.
com.facebook.react.bridge.CallbackImpl.invoke CallbackImpl.java:26 com.RNFetchBlob.RNFetchBlobReq.onReceive RNFetchBlobReq.java:778 android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0 LoadedApk.java:1501 android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0 LoadedApk.java:1532 android.app.-$$Lambda$LoadedApk$ReceiverDispatcher$Args$_BumDX2UKsnxLVrE6UJsJZkotuA.run android.os.Handler.handleCallback Handler.java:873 android.os.Handler.dispatchMessage Handler.java:99 android.os.Looper.loop Looper.java:226 android.app.ActivityThread.main ActivityThread.java:7178 java.lang.reflect.Method.invoke Method.java com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run RuntimeInit.java:503 com.android.internal.os.ZygoteInit.main ZygoteInit.java:942
Thanks in Advance
+1, also the error occurs on Huawei Devices:
The error would be: java.lang.ClassCastException okhttp3.internal.http.RealResponseBody cannot be cast to com.RNFetchBlob.Response.RNFetchBlobFileResp RNFetchBlobReq.java:544 com.RNFetchBlob.RNFetchBlobReq.done RNFetchBlobReq.java:67 com.RNFetchBlob.RNFetchBlobReq.access$100 RNFetchBlobReq.java:445 com.RNFetchBlob.RNFetchBlobReq$3.onResponse RealCall.java:174 okhttp3.RealCall$AsyncCall.execute NamedRunnable.java:32 okhttp3.internal.NamedRunnable.run ThreadPoolExecutor.java:1113 java.util.concurrent.ThreadPoolExecutor.runWorker ThreadPoolExecutor.java:588 java.util.concurrent.ThreadPoolExecutor$Worker.run Thread.java:818 java.lang.Thread.run
any solution to issue mentioned by @xsephtion ?
any solution to issue mentioned by @xsephtion ?
As far as I remember I used
android:requestLegacyExternalStorage="true"
on my Android Manifest.
Hope that would help you.
Just to add:
RNFetchBlob.fetch('POST', 'http://192.168.1.6:8001/media2', {
'Content-Type' : 'multipart/form-data',
}, [data]).then((resp) => {
console.log("Server Image Response", resp);
}).catch((err) => {
console.error("There's an error:", error)
})
Previously I was using the same code structure with OP. I had to change it same as above. If you are needing notifications, I suggest that you bind a local notification every time the fetch returns a response.
thanks @xsephtion
I has same issue. In my case, every download time, i change name of file.
it is solved by changing file name of downloadble. ✅
here is code :
const randomNum = Math.floor(Math.random() * 100000);
// Generate a unique filename for the downloaded image
const filename = url.split('/').pop();
const imagePath = `${cacheDir}/${randomNum+filename}`;
Here is full code of common function
import RNFetchBlob from 'rn-fetch-blob';
import { Platform, PermissionsAndroid } from 'react-native';
/// grant permission in android
export const getDownloadPermissionAndroid = async () => {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
{
title: 'File Download Permission',
message: 'Your permission is required to save Files to your device',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
},
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) return true;
} catch (err) {
console.log('err', err);
}
};
export const downloadFile = async url => {
// Get the app's cache directory
const { config, fs } = RNFetchBlob;
const cacheDir = fs.dirs.DownloadDir;
const randomNum = Math.floor(Math.random() * 100000);
// Generate a unique filename for the downloaded image/file
const filename = url.split('/').pop();
const imagePath = `${cacheDir}/${randomNum+filename}`;
try {
// Download the file and save it to the cache directory
const configOptions = Platform.select({
ios: {
fileCache: true,
path: imagePath,
appendExt: filename.split(`-${randomNum}.`).pop(),
},
android: {
fileCache: false,
path: imagePath,
appendExt: filename.split(`${randomNum}.`).pop(),
addAndroidDownloads: {
// Related to the Android only
useDownloadManager: true,
notification: true,
path: imagePath,
description: 'File',
},
},
});
const response = await RNFetchBlob.config(configOptions).fetch('GET', url);
console.log("Response of download", response)
// Return the path to the downloaded file
return response;
} catch (error) {
console.error(error);
return null;
}
};
I have called here this code:
<TouchableOpacity style={{
backgroundColor: '#36BA98',
padding: heightPercentageToDP(0.7),
borderRadius: 100,
position: 'absolute',
bottom: 0,
right: 0
}}
onPress={() => {
console.log("pressed")
if (Platform.OS === 'android') {
getDownloadPermissionAndroid().then(granted => {
if (granted) {
downloadFile(fileUrl);
}
});
} else {
downloadFile(fileUrl).then(res => {
RNFetchBlob.ios.previewDocument(res.path());
});
}
}}
>
<AntDesign name='download' size={heightPercentageToDP(2.35)} color={'#fff'} />
</TouchableOpacity>