package com.RNFetchBlob; import android.app.Activity; import android.app.DownloadManager; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import androidx.core.content.FileProvider; import android.util.SparseArray; import com.facebook.react.bridge.ActivityEventListener; import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; // Cookies import com.facebook.react.bridge.WritableMap; import com.facebook.react.modules.network.ForwardingCookieHandler; import com.facebook.react.modules.network.CookieJarContainer; import com.facebook.react.modules.network.OkHttpClientProvider; import okhttp3.OkHttpClient; import okhttp3.JavaNetCookieJar; import java.io.File; import java.util.Map; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import static android.app.Activity.RESULT_OK; import static com.RNFetchBlob.RNFetchBlobConst.GET_CONTENT_INTENT; public class RNFetchBlob extends ReactContextBaseJavaModule { private final OkHttpClient mClient; static ReactApplicationContext RCTContext; private static LinkedBlockingQueue taskQueue = new LinkedBlockingQueue<>(); private static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 10, 5000, TimeUnit.MILLISECONDS, taskQueue); static LinkedBlockingQueue fsTaskQueue = new LinkedBlockingQueue<>(); private static ThreadPoolExecutor fsThreadPool = new ThreadPoolExecutor(2, 10, 5000, TimeUnit.MILLISECONDS, taskQueue); private static boolean ActionViewVisible = false; private static SparseArray promiseTable = new SparseArray<>(); public RNFetchBlob(ReactApplicationContext reactContext) { super(reactContext); mClient = OkHttpClientProvider.getOkHttpClient(); ForwardingCookieHandler mCookieHandler = new ForwardingCookieHandler(reactContext); CookieJarContainer mCookieJarContainer = (CookieJarContainer) mClient.cookieJar(); mCookieJarContainer.setCookieJar(new JavaNetCookieJar(mCookieHandler)); RCTContext = reactContext; reactContext.addActivityEventListener(new ActivityEventListener() { @Override public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) { if(requestCode == GET_CONTENT_INTENT && resultCode == RESULT_OK) { Uri d = data.getData(); promiseTable.get(GET_CONTENT_INTENT).resolve(d.toString()); promiseTable.remove(GET_CONTENT_INTENT); } } @Override public void onNewIntent(Intent intent) { } }); } @Override public String getName() { return "RNFetchBlob"; } @Override public Map getConstants() { return RNFetchBlobFS.getSystemfolders(this.getReactApplicationContext()); } @ReactMethod public void createFile(final String path, final String content, final String encode, final Promise promise) { threadPool.execute(new Runnable() { @Override public void run() { RNFetchBlobFS.createFile(path, content, encode, promise); } }); } @ReactMethod public void createFileASCII(final String path, final ReadableArray dataArray, final Promise promise) { threadPool.execute(new Runnable() { @Override public void run() { RNFetchBlobFS.createFileASCII(path, dataArray, promise); } }); } @ReactMethod public void actionViewIntent(String path, String mime, final Promise promise) { try { Uri uriForFile = FileProvider.getUriForFile(getCurrentActivity(), this.getReactApplicationContext().getPackageName() + ".provider", new File(path)); if (Build.VERSION.SDK_INT >= 24) { // Create the intent with data and type Intent intent = new Intent(Intent.ACTION_VIEW) .setDataAndType(uriForFile, mime); // Set flag to give temporary permission to external app to use FileProvider intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // All the activity to be opened outside of an activity intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // All the activity to be opened outside of an activity intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // Validate that the device can open the file PackageManager pm = getCurrentActivity().getPackageManager(); if (intent.resolveActivity(pm) != null) { this.getReactApplicationContext().startActivity(intent); } } else { Intent intent = new Intent(Intent.ACTION_VIEW) .setDataAndType(Uri.parse("file://" + path), mime).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); this.getReactApplicationContext().startActivity(intent); } ActionViewVisible = true; final LifecycleEventListener listener = new LifecycleEventListener() { @Override public void onHostResume() { if(ActionViewVisible) promise.resolve(null); RCTContext.removeLifecycleEventListener(this); } @Override public void onHostPause() { } @Override public void onHostDestroy() { } }; RCTContext.addLifecycleEventListener(listener); } catch(Exception ex) { promise.reject("EUNSPECIFIED", ex.getLocalizedMessage()); } } @ReactMethod public void writeArrayChunk(final String streamId, final ReadableArray dataArray, final Callback callback) { RNFetchBlobFS.writeArrayChunk(streamId, dataArray, callback); } @ReactMethod public void unlink(String path, Callback callback) { RNFetchBlobFS.unlink(path, callback); } @ReactMethod public void mkdir(String path, Promise promise) { RNFetchBlobFS.mkdir(path, promise); } @ReactMethod public void exists(String path, Callback callback) { RNFetchBlobFS.exists(path, callback); } @ReactMethod public void cp(final String path, final String dest, final Callback callback) { threadPool.execute(new Runnable() { @Override public void run() { RNFetchBlobFS.cp(path, dest, callback); } }); } @ReactMethod public void mv(String path, String dest, Callback callback) { RNFetchBlobFS.mv(path, dest, callback); } @ReactMethod public void ls(String path, Promise promise) { RNFetchBlobFS.ls(path, promise); } @ReactMethod public void writeStream(String path, String encode, boolean append, Callback callback) { new RNFetchBlobFS(this.getReactApplicationContext()).writeStream(path, encode, append, callback); } @ReactMethod public void writeChunk(String streamId, String data, Callback callback) { RNFetchBlobFS.writeChunk(streamId, data, callback); } @ReactMethod public void closeStream(String streamId, Callback callback) { RNFetchBlobFS.closeStream(streamId, callback); } @ReactMethod public void removeSession(ReadableArray paths, Callback callback) { RNFetchBlobFS.removeSession(paths, callback); } @ReactMethod public void readFile(final String path, final String encoding, final Promise promise) { threadPool.execute(new Runnable() { @Override public void run() { RNFetchBlobFS.readFile(path, encoding, promise); } }); } @ReactMethod public void writeFileArray(final String path, final ReadableArray data, final boolean append, final Promise promise) { threadPool.execute(new Runnable() { @Override public void run() { RNFetchBlobFS.writeFile(path, data, append, promise); } }); } @ReactMethod public void writeFile(final String path, final String encoding, final String data, final boolean append, final Promise promise) { threadPool.execute(new Runnable() { @Override public void run() { RNFetchBlobFS.writeFile(path, encoding, data, append, promise); } }); } @ReactMethod public void lstat(String path, Callback callback) { RNFetchBlobFS.lstat(path, callback); } @ReactMethod public void stat(String path, Callback callback) { RNFetchBlobFS.stat(path, callback); } @ReactMethod public void scanFile(final ReadableArray pairs, final Callback callback) { final ReactApplicationContext ctx = this.getReactApplicationContext(); threadPool.execute(new Runnable() { @Override public void run() { int size = pairs.size(); String [] p = new String[size]; String [] m = new String[size]; for(int i=0;i