Created
August 29, 2017 15:44
-
-
Save progmonster/ff8ea9bc40f55ca1cd97c84419117605 to your computer and use it in GitHub Desktop.
react native document picker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.smsapprn; | |
import android.app.Activity; | |
import android.content.Context; | |
import android.content.Intent; | |
import android.net.Uri; | |
import android.os.AsyncTask; | |
import android.support.annotation.RequiresPermission; | |
import android.telephony.SubscriptionInfo; | |
import android.telephony.SubscriptionManager; | |
import android.util.Base64; | |
import com.facebook.react.bridge.ActivityEventListener; | |
import com.facebook.react.bridge.Arguments; | |
import com.facebook.react.bridge.BaseActivityEventListener; | |
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.WritableArray; | |
import com.facebook.react.bridge.WritableMap; | |
import java.io.BufferedInputStream; | |
import java.io.ByteArrayOutputStream; | |
import java.io.FileNotFoundException; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.util.List; | |
public class ExpModule extends ReactContextBaseJavaModule { | |
private static final int READ_REQUEST_CODE = 42; | |
public ExpModule(ReactApplicationContext reactContext) { | |
super(reactContext); | |
} | |
@Override | |
public String getName() { | |
return "ExpModule"; | |
} | |
@ReactMethod | |
public void getSimList(final Promise promise) { | |
try { | |
SubscriptionManager subscriptionManager = (SubscriptionManager) getReactApplicationContext() | |
.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); | |
WritableArray result = Arguments.createArray(); | |
for (SubscriptionInfo subscriptionInfo : subscriptionManager.getActiveSubscriptionInfoList()) { | |
WritableMap simInfo = Arguments.createMap(); | |
simInfo.putInt("slotIndex", subscriptionInfo.getSimSlotIndex()); | |
simInfo.putInt("subscriptionId", subscriptionInfo.getSubscriptionId()); | |
simInfo.putString("carrierName", subscriptionInfo.getCarrierName().toString()); | |
simInfo.putString("displayName", subscriptionInfo.getDisplayName().toString()); | |
result.pushMap(simInfo); | |
} | |
promise.resolve(result); | |
} catch (Exception e) { | |
promise.reject(e); | |
} | |
} | |
@ReactMethod | |
public void sayHello(ReadableArray mimeTypes, final Promise promise) { | |
String[] mimeTypesArr = new String[mimeTypes.size()]; | |
for (int mimeTypeIdx = 0; mimeTypeIdx < mimeTypes.size(); mimeTypeIdx++) { | |
mimeTypesArr[mimeTypeIdx] = mimeTypes.getString(mimeTypeIdx); | |
} | |
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); | |
// Filter to only show results that can be "opened", such as a | |
// file (as opposed to a list of contacts or timezones) | |
intent.addCategory(Intent.CATEGORY_OPENABLE); | |
// Filter to show only images, using the image MIME data type. | |
// If one wanted to search for ogg vorbis files, the type would be "audio/ogg". | |
// To search for all documents available via installed storage providers, | |
// it would be "*/*". | |
intent.setType("*/*"); | |
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypesArr); | |
Activity currentActivity = getCurrentActivity(); | |
if (currentActivity == null) { | |
promise.reject(new RuntimeException("Can't obtain current activity.")); | |
return; | |
} | |
if (intent.resolveActivity(getReactApplicationContext().getPackageManager()) == null) { | |
promise.reject(new RuntimeException("Can't resolve activity.")); | |
return; | |
} | |
ActivityEventListener openDocumentActivityEventListener = new BaseActivityEventListener() { | |
@Override | |
public void onActivityResult(final Activity activity, int requestCode, int resultCode, Intent data) { | |
if (requestCode != READ_REQUEST_CODE) { | |
return; | |
} | |
getReactApplicationContext().removeActivityEventListener(this); | |
if (resultCode != Activity.RESULT_OK) { | |
promise.resolve(null); | |
return; | |
} | |
AsyncTask<Uri, Integer, AsyncTaskResult<byte[]>> downloadTask = new AsyncTask<Uri, Integer, AsyncTaskResult<byte[]>>() { | |
protected AsyncTaskResult<byte[]> doInBackground(Uri... uris) { | |
try { | |
InputStream inputStream = activity.getContentResolver().openInputStream(uris[0]); | |
try (BufferedInputStream bis = new BufferedInputStream(inputStream)) { | |
return new AsyncTaskResult<>(readBytes(bis, isCancelled())); | |
} catch (IOException e) { | |
return new AsyncTaskResult<>(e); | |
} | |
} catch (FileNotFoundException e) { | |
return new AsyncTaskResult<>(e); | |
} | |
} | |
@Override | |
protected void onPostExecute(AsyncTaskResult<byte[]> asyncTaskResult) { | |
if (asyncTaskResult.getError() == null) { | |
try { | |
promise.resolve(Base64.encodeToString(asyncTaskResult.getResult(), Base64.NO_WRAP)); | |
} catch (Exception e) { | |
promise.reject(e); | |
} | |
} else { | |
asyncTaskResult.getError().printStackTrace(); | |
promise.reject(asyncTaskResult.getError()); | |
} | |
} | |
}; | |
downloadTask.execute(data.getData()); | |
} | |
}; | |
getReactApplicationContext().addActivityEventListener(openDocumentActivityEventListener); | |
currentActivity.startActivityForResult(intent, READ_REQUEST_CODE); | |
} | |
private byte[] readBytes(InputStream inputStream, boolean cancelled) throws IOException { | |
// this dynamically extends to take the bytes you read | |
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream(); | |
// this is storage overwritten on each iteration with bytes | |
int bufferSize = 1024; | |
byte[] buffer = new byte[bufferSize]; | |
// we need to know how may bytes were read to write them to the byteBuffer | |
int len; | |
while ((len = inputStream.read(buffer)) != -1) { | |
if (cancelled) { | |
return null; | |
} | |
byteBuffer.write(buffer, 0, len); | |
} | |
// and then we can return your byte array. | |
return byteBuffer.toByteArray(); | |
} | |
private static class AsyncTaskResult<T> { | |
private T result; | |
private Exception error; | |
public T getResult() { | |
return result; | |
} | |
public Exception getError() { | |
return error; | |
} | |
public AsyncTaskResult(T result) { | |
super(); | |
this.result = result; | |
} | |
public AsyncTaskResult(Exception error) { | |
super(); | |
this.error = error; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {NativeModules} from "react-native" | |
module.exports = NativeModules.ExpModule; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.smsapprn; | |
import com.facebook.react.ReactPackage; | |
import com.facebook.react.bridge.NativeModule; | |
import com.facebook.react.bridge.ReactApplicationContext; | |
import com.facebook.react.uimanager.ViewManager; | |
import java.util.ArrayList; | |
import java.util.Collections; | |
import java.util.List; | |
public class ExpReactPackage implements ReactPackage { | |
@Override | |
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { | |
List<NativeModule> modules = new ArrayList<>(); | |
modules.add(new ExpModule(reactContext)); | |
return modules; | |
} | |
@Override | |
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { | |
return Collections.emptyList(); | |
} | |
} |
thanks @progmonster. I think this requires APPI 22 and higher
subscriptionManager.getActiveSubscriptionInfoList
this needs 22 or higher
note: ok i suppose i can delete this function :)
Don't i have to connect ExpReactPackage in MainActivity (get packages or sth) ?
@progmonster It opens the file picker but after i pick a file it closes and doesn't fire the then() or catch() callback..
update: it doesn't go in the onActivityResult of BaseActivityEventListener
I get this error in logcat:
https://gist.github.com/flieks/f34c30a83b5995025ccba499c1bfe9fb
I'm runnnig on android 7.0
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
"Exp" because of "experimental" not because of Expo. Works only for Android with API Level 19 or higher (https://developer.android.com/guide/topics/providers/document-provider.html)
Method to call is "sayHello", rename it as you want :)
Example of usage:
import ExpModule from "ExpModule";