Короткий шаг: у меня есть собственное приложение, которое по сути является просто приложением-оболочкой WebView. Я хочу, чтобы он мог получать текст из меню «Поделиться через» программы запуска Android. Полученный текст должен стать URI WebViews.
Я добавил фильтры намерений в свой андроид AndroidManifest.xml
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
Которые регистрируют приложение в собственном меню общего ресурса как способное обрабатывать намерения общего текста. Пока все хорошо!
В моем MainActivit.java мне удалось обработать намерение, пока просто поджаривая общий текст.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
when {
intent?.action == Intent.ACTION_SEND -> {
if ("text/plain" == intent.type) {
handleSendText(intent) // Handle text being sent
}
}
}
}
private fun handleSendText(intent: Intent) {
intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
Toast.makeText(this, it, Toast.LENGTH_SHORT).show() // this works
// Send event to react native app.js
}
}
Я следовал этому руководству, чтобы создать источник событий, который должен иметь возможность общаться с собственной частью приложения реагировать: https://levelup.gitconnected.com/react-native-events-in-gory-details-what-happens-on-the-way-to-listeners-2cee6c55940c
класс kotlin, который выглядит следующим образом:
class EventEmitter(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
val reactContext = reactContext
override fun getName(): String {
return "EventEmitter"
}
@ReactMethod
fun anExposedMethod() {
// this will be accessible from javascript as well
}
private fun sendEvent() {
val currentContext = reactApplicationContext
val eventName = "myAwesomeEvent"
val params = Arguments.createMap()
params.putString("type", "myEventType")
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit(eventName, params)
}
}
Это зарегистрировано в MainApplication.kt
class MainApplication : Application(), ShareApplication, ReactApplication {
private val mReactNativeHost = object : ReactNativeHost(this) {
override fun getUseDeveloperSupport(): Boolean {
return BuildConfig.DEBUG
}
override fun getPackages(): List<ReactPackage> {
return Arrays.asList<ReactPackage>(
MainReactPackage(),
EventEmitterPackage(),
RNCWebViewPackage()
)
}
override fun getJSMainModuleName(): String {
return "index"
}
}
override fun getReactNativeHost(): ReactNativeHost {
return mReactNativeHost
}
override fun onCreate() {
super.onCreate()
SoLoader.init(this, /* native exopackage */ false)
}
}
И отсюда я не уверен, как мне двигаться дальше. Что мне кажется логичным, так это вызов sendEvent () из handleSendText (intent: Intent), но у меня нет доступа к этой функции в классе MainActivity, и я не уверен, каков правильный подход к тому, как это сделать поэтому.
Еще больше меня смущает различие между MainApplication и MainActivity - почему эти две разные вещи?
Реакционная нативная часть
В app.js я импортировал eventEmitter
const EventEmitter = NativeModules.EventEmitter;
...
componentWillMount() {
DeviceEventEmitter.addListener('myAwesomeEvent', (event) => {
// this is were I want to receive the shared text at last
console.log(event);
this.state.uri = event;
});
}
Но я не смог проверить, работает ли это до сих пор, так как я запутался в том, как или откуда вызывать функцию sendEvent из класса EventEmitter.