I have a webview component of React Native. The webview should support input type is file, so I do it as:
File Upload in WebView
and the webview implements ActivityEventListener and override onActivityResult.But the onActivityResult not working.
The Code is
class RNWebView extends WebView implements ActivityEventListener {
protected class GeoWebChromeClient extends WebChromeClient {
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
...
mActivity.startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
return true;
}
}
public RNWebView(ReactContext reactContext, Activity activity) {
super(reactContext);
// Add the listener for `onActivityResult`
reactContext.addActivityEventListener(this);
...
}
@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
// Your logic here
Log.d("Tanck", "requestCode:" + requestCode + "----" + "resultCode:" + resultCode);
}
}
Maybe late hope it helps.
native module's onActivityResult
is called by ReactContext
which is called by ReactInstanceManagerImpl
which in 0.29 is called by ReactActivity
. In the example above MyWb
extends Activity not ReactActivity
, so ReactInstanceManagerImpl
is never called.
The solution is just in your activity's onActivityResult
call ReactInstanceManager
's onActivityResult
since you already have your own ReactInstanceManager object reference.
The Activity you are launching React Native from should have an override like this:
// Manually pass along the `onActivityResult` event to React Native event listeners.
// We are not extending from `ReactActivity` so we need to do this manually.
//
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
mReactInstanceManager.onActivityResult( this, requestCode, resultCode, data );
}
To make the solution complete:
in your MainActivity (or in the Activity, where RN is initialized and mReactInstanceManager is used if it is a part of a native app):
...
private ReactInstanceManager mReactInstanceManager;
...
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
mReactInstanceManager.onActivityResult(requestCode, resultCode, data);
}
in your Module:
public class MyModule extends ReactContextBaseJavaModule implements ActivityEventListener {
static final int REQUEST_VIDEO_CAPTURE = 1;
final ReactApplicationContext reactContext;
Promise promise;
public GeneralIntentModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
this.reactContext.addActivityEventListener(this);
}
@Override
public String getName() {
return "MyModule ";
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
this.promise.resolve(data.getDataString());
}
}
If any one using kotlin with react-native module with Promise, plesae refer below code,
import android.app.Activity
import android.content.Intent
import android.util.Log
import com.facebook.react.bridge.*
import com.onboardinglib.HostActivity
class ConsistyOnboarding (reactContext: ReactApplicationContext) :
ReactContextBaseJavaModule(reactContext) {
private val CODE = 999
private var promise: Promise? = null
private val reContext: ReactApplicationContext? = reactContext
fun dumpIntent(intent: Intent) {
LogPrint("Bundle data", "Dumping intent start")
val bundleData = intent.extras
if (bundleData != null) {
for (key in bundleData.keySet()) {
LogPrint(
"Bundle data-->",
key + " : " + if (bundleData[key] != null) bundleData[key] else "NULL"
)
}
}
}
override fun getName(): String {
return "ConsistyOnboarding"
}
private val mActivityEventListener: ActivityEventListener =
object : BaseActivityEventListener() {
override fun onActivityResult(
activity: Activity,
requestCode: Int,
resultCode: Int,
data: Intent
) {
LogPrint("mActivityEventListener", "Started")
if (data == null) {
resolve("01", "No action taken", "0")
return
}
dumpIntent(data)
if (resultCode == Activity.RESULT_OK) {
try {
val status = data.getBooleanExtra("status", false)
val response = data.getIntExtra("response", 0)
val message = data.getStringExtra("message")
resolve(status.toString(), response.toString(), message.toString())
return
} catch (e: Exception) {
e.printStackTrace()
resolve("01", "Exception occurred in on-boarding " + e.message, "0")
}
}
resolve("01", "No action taken", "0")
}
}
init {
reContext?.addActivityEventListener(mActivityEventListener)
}
@ReactMethod
fun Onboarding(
partnerId: String, partnerKey: String prm: Promise
) {
promise = prm
val currentActivity = currentActivity
val intent = Intent(currentActivity, HostActivity::class.java)
intent.putExtra("pId", partnerId)
intent.putExtra("ApiKey", partnerKey)
try {
currentActivity?.startActivityForResult(intent, CODE)
} catch (e: Exception) {
e.printStackTrace()
resolve("01", "No action taken", "0")
}
}
private fun resolve(
statusCode: String,
response: String,
message: String
) {
if (promise == null) {
return
}
val map = Arguments.createMap()
map.putString("statusCode", statusCode)
map.putString("response", response)
map.putString("message", message)
promise!!.resolve(map)
promise = null
}
private fun LogPrint(key: String?, value: String?) {
if (key == null || value == null) {
return
}
Log.i(key, value)
}
}
Main part is need to add event Listener,
init {
reContext?.addActivityEventListener(mActivityEventListener)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With