[RN] Consistency in Jitsi Meet SDK for Android
This commit is contained in:
parent
84463d8cf0
commit
90466183d6
|
@ -1,24 +1,38 @@
|
|||
# Jitsi Meet for Android
|
||||
# Jitsi Meet SDK for Android
|
||||
|
||||
This directory contains the source code for Jitsi Meet for Android (the
|
||||
application) and the Jitsi Meet SDK for Android.
|
||||
This directory contains the source code of the Jitsi Meet app and the Jitsi Meet
|
||||
SDK for Android.
|
||||
|
||||
## Jitsi Meet SDK
|
||||
|
||||
Jitsi Meet SDK is an Android library which embodies the Jitsi Meet experience,
|
||||
gift-wrapped so other applications can use it. Example use:
|
||||
Jitsi Meet SDK is an Android library which embodies the whole Jitsi Meet
|
||||
experience and makes it reusable by third-party apps.
|
||||
|
||||
To get started, extends your `android.app.Activity` from
|
||||
`org.jitsi.meet.sdk.JitsiMeetActivity`:
|
||||
|
||||
```java
|
||||
package org.jitsi.example;
|
||||
|
||||
import org.jitsi.meet.sdk.JitsiMeetActivity;
|
||||
|
||||
public class MainActivity extends JitsiMeetActivity {
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, you can use the `org.jitsi.meet.sdk.JitsiMeetView` class which
|
||||
extends `android.view.View`:
|
||||
|
||||
```java
|
||||
package org.jitsi.example;
|
||||
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
|
||||
import org.jitsi.meet.sdk.*;
|
||||
import org.jitsi.meet.sdk.JitsiMeetView;
|
||||
|
||||
|
||||
public class CustomActivity extends AppCompatActivity {
|
||||
private JitsiMeetView jitsiMeetView;
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private JitsiMeetView view;
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
|
@ -32,10 +46,17 @@ public class CustomActivity extends AppCompatActivity {
|
|||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
jitsiMeetView = new JitsiMeetView(this);
|
||||
jitsiMeetView.loadURL(null);
|
||||
view = new JitsiMeetView(this);
|
||||
view.loadURL(null);
|
||||
|
||||
setContentView(jitsiMeetView);
|
||||
setContentView(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
JitsiMeetView.onHostDestroy(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -43,45 +64,26 @@ public class CustomActivity extends AppCompatActivity {
|
|||
JitsiMeetView.onNewIntent(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
JitsiMeetView.onHostDestroy(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
JitsiMeetView.onHostPause(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
JitsiMeetView.onHostResume(this);
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, you can use the `JitsiMeetBaseActivity` class, which already has
|
||||
all activity lifecycle methods hooked up:
|
||||
### JitsiMeetActivity
|
||||
|
||||
```java
|
||||
package org.jitsi.example;
|
||||
|
||||
import org.jitsi.meet.sdk.*;
|
||||
|
||||
|
||||
public class MainActivity extends JitsiMeetBaseActivity {
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### JitsiMeetBaseActivity
|
||||
|
||||
This class encapsulates a high level API in the form of an Android activity
|
||||
which displays a single `JitsiMeetView` views.
|
||||
This class encapsulates a high level API in the form of an Android `Activity`
|
||||
which displays a single `JitsiMeetView`.
|
||||
|
||||
#### loadURL(url)
|
||||
|
||||
|
@ -91,7 +93,7 @@ See JitsiMeetView.loadURL.
|
|||
### JitsiMeetView
|
||||
|
||||
The `JitsiMeetView` class is the core of Jitsi Meet SDK. It's designed to
|
||||
display a Jitsi Meet conference view (or a welcome page).
|
||||
display a Jitsi Meet conference (or a welcome page).
|
||||
|
||||
#### getListener()
|
||||
|
||||
|
@ -99,8 +101,8 @@ Returns the `JitsiMeetView.Listener` instance attached to the view.
|
|||
|
||||
#### loadURL(url)
|
||||
|
||||
Loads the given URL and joins the conference which is being pointed to. If null,
|
||||
it will load the welcome page.
|
||||
Loads the given URL and joins the room. If `null` is specified, the welcome page
|
||||
is displayed instead.
|
||||
|
||||
#### setListener(listener)
|
||||
|
||||
|
@ -110,8 +112,8 @@ interface) on the view.
|
|||
#### onBackPressed()
|
||||
|
||||
Helper method which should be called from the activity's `onBackPressed` method.
|
||||
If this function returns `true` it means the action was handled and thus no
|
||||
extra processing is required, otherwise the application should call the parent's
|
||||
If this function returns `true`, it means the action was handled and thus no
|
||||
extra processing is required; otherwise the app should call the parent's
|
||||
`onBackPressed` method.
|
||||
|
||||
This is a static method.
|
||||
|
@ -136,16 +138,16 @@ This is a static method.
|
|||
|
||||
#### onNewIntent(intent)
|
||||
|
||||
Helper method for integrating the *deep linking* functionality. If your
|
||||
application's activity is launched in "singleTask" mode this method should
|
||||
be called from the activity's `onNewIntent` method.
|
||||
Helper method for integrating the *deep linking* functionality. If your app's
|
||||
activity is launched in "singleTask" mode this method should be called from the
|
||||
activity's `onNewIntent` method.
|
||||
|
||||
This is a static method.
|
||||
|
||||
#### Listener
|
||||
|
||||
JitsiMeetView.Listener provides an interface applications can implement in order
|
||||
to get notified about the state of the Jitsi Meet conference.
|
||||
JitsiMeetView.Listener provides an interface apps can implement in order to get
|
||||
notified about the state of the Jitsi Meet conference.
|
||||
|
||||
##### onConferenceFailed
|
||||
|
||||
|
@ -178,4 +180,3 @@ The `data` HashMap contains a "url" key with the conference URL.
|
|||
Called before a conference is left.
|
||||
|
||||
The `data` HashMap contains a "url" key with the conference URL.
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
apply plugin: 'com.android.application'
|
||||
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
|
|
|
@ -16,18 +16,19 @@
|
|||
|
||||
package org.jitsi.meet;
|
||||
|
||||
import org.jitsi.meet.sdk.JitsiMeetBaseActivity;
|
||||
|
||||
import org.jitsi.meet.sdk.JitsiMeetActivity;
|
||||
|
||||
/**
|
||||
* The one and only Activity that Jitsi Meet (the app) needs. The activity is launched in
|
||||
* "singleTask" mode, so it will be created upon application initialization and there will be
|
||||
* a single instance of it. Further attempts at launching the application once it was already
|
||||
* launched will result in <tt>onNewIntent</tt> being called.
|
||||
* The one and only {@link Activity} that the Jitsi Meet app needs. The
|
||||
* {@code Activity} is launched in {@code singleTask} mode, so it will be
|
||||
* created upon application initialization and there will be a single instance
|
||||
* of it. Further attempts at launching the application once it was already
|
||||
* launched will result in {@link Activity#onNewIntent(Intent)} being called.
|
||||
*
|
||||
* This Activity inherits from JitsiMeetBaseActivity without adding anything to it. It merely exists to
|
||||
* keep the React Native CLI working, since it always tries to launch an activity called
|
||||
* "MainActivity" when doing "react-native run-android".
|
||||
* This {@code Activity} extends {@link JitsiMeetActivity} without adding
|
||||
* anything to it. It exists to merely keep the React Native CLI working, since
|
||||
* the latter always tries to launch an {@code Activity} named
|
||||
* {@code MainActivity} when doing {@code react-native run-android}.
|
||||
*/
|
||||
public class MainActivity extends JitsiMeetBaseActivity {
|
||||
public class MainActivity extends JitsiMeetActivity {
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
// Top-level build file where you can add configuration options common to all
|
||||
// sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
|
@ -8,7 +9,7 @@ buildscript {
|
|||
classpath 'com.android.tools.build:gradle:2.2.3'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
// in the individual module build.gradle files.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +18,8 @@ allprojects {
|
|||
mavenLocal()
|
||||
jcenter()
|
||||
maven {
|
||||
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
||||
// All of React Native (JS, Obj-C sources, Android binaries) is
|
||||
// installed from npm.
|
||||
url "$rootDir/../node_modules/react-native/android"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ gradle.projectsEvaluated {
|
|||
def buildNameCapitalized = "${buildType.name.capitalize()}"
|
||||
def bundlePath = "${buildDir}/intermediates/bundles/${buildType.name}"
|
||||
|
||||
// Bundle fonts in react-native-vector-icons
|
||||
// Bundle fonts in react-native-vector-icons.
|
||||
//
|
||||
|
||||
def currentFontTask = tasks.create(name: "${buildType.name}CopyFonts", type: Copy) {
|
||||
|
@ -63,35 +63,43 @@ gradle.projectsEvaluated {
|
|||
runBefore("processUniversal${buildNameCapitalized}Resources", currentFontTask)
|
||||
runBefore("process${buildNameCapitalized}Resources", currentFontTask)
|
||||
|
||||
// Bundle JavaScript and React resources
|
||||
// Bundle JavaScript and React resources.
|
||||
// (adapted from react-native/react.gradle)
|
||||
//
|
||||
|
||||
// React js bundle directories
|
||||
// React JS bundle directories
|
||||
def jsBundleDir = file("${bundlePath}/assets")
|
||||
def resourcesDir = file("${bundlePath}/res/merged")
|
||||
def jsBundleFile = file("${jsBundleDir}/index.android.bundle")
|
||||
|
||||
// Bundle task name for variant
|
||||
// Bundle task name for variant.
|
||||
def bundleJsAndAssetsTaskName = "bundle${buildNameCapitalized}JsAndAssets"
|
||||
|
||||
def currentBundleTask = tasks.create(
|
||||
name: bundleJsAndAssetsTaskName,
|
||||
type: Exec) {
|
||||
|
||||
// Set up inputs and outputs so gradle can cache the result
|
||||
// Set up inputs and outputs so gradle can cache the result.
|
||||
def reactRoot = file("${projectDir}/../../")
|
||||
inputs.files fileTree(dir: reactRoot, excludes: ["android/**", "ios/**"])
|
||||
outputs.dir jsBundleDir
|
||||
outputs.dir resourcesDir
|
||||
|
||||
// Set up the call to the react-native cli
|
||||
// Set up the call to the react-native cli.
|
||||
workingDir reactRoot
|
||||
|
||||
// Create JS bundle
|
||||
def devEnabled = !buildNameCapitalized.toLowerCase().contains("release")
|
||||
commandLine("node", "node_modules/react-native/local-cli/cli.js", "bundle", "--platform", "android", "--dev", "${devEnabled}",
|
||||
"--reset-cache", "--entry-file", "index.android.js", "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir)
|
||||
commandLine(
|
||||
"node",
|
||||
"node_modules/react-native/local-cli/cli.js",
|
||||
"bundle",
|
||||
"--assets-dest", resourcesDir,
|
||||
"--bundle-output", jsBundleFile,
|
||||
"--dev", "${devEnabled}",
|
||||
"--entry-file", "index.android.js",
|
||||
"--platform", "android",
|
||||
"--reset-cache")
|
||||
|
||||
// TODO: disable task in Debug mode?
|
||||
}
|
||||
|
|
|
@ -26,53 +26,57 @@ import android.os.Bundle;
|
|||
|
||||
import java.net.URL;
|
||||
|
||||
|
||||
/**
|
||||
* Base Activity for applications integrating Jitsi Meet at a higher level. It contains all the
|
||||
* required wiring between the <tt>JKConferenceView</tt> and the Activity lifecycle methods already
|
||||
* implemented.
|
||||
* Base Activity for applications integrating Jitsi Meet at a higher level. It
|
||||
* contains all the required wiring between the <tt>JKConferenceView</tt> and
|
||||
* the Activity lifecycle methods already implemented.
|
||||
*
|
||||
* In this activity we use a single <tt>JKConferenceView</tt> instance. This instance gives us
|
||||
* access to a view which displays the welcome page and the conference itself. All lifetime methods
|
||||
* associated with this Activity are hooked to the React Native subsystem via proxy calls through
|
||||
* the <tt>JKConferenceView</tt> static methods.
|
||||
* In this activity we use a single <tt>JKConferenceView</tt> instance. This
|
||||
* instance gives us access to a view which displays the welcome page and the
|
||||
* conference itself. All lifetime methods associated with this Activity are
|
||||
* hooked to the React Native subsystem via proxy calls through the
|
||||
* <tt>JKConferenceView</tt> static methods.
|
||||
*/
|
||||
public class JitsiMeetBaseActivity extends AppCompatActivity {
|
||||
public class JitsiMeetActivity extends AppCompatActivity {
|
||||
/**
|
||||
* Instance of the {@JitsiMeetView} which this activity will display.
|
||||
*/
|
||||
private JitsiMeetView jitsiMeetView;
|
||||
|
||||
/**
|
||||
* Code for identifying the permission to draw on top of other apps. The number is chosen
|
||||
* arbitrarily and used to correlate the intent with its result.
|
||||
* Code for identifying the permission to draw on top of other apps. The
|
||||
* number is chosen arbitrarily and used to correlate the intent with its
|
||||
* result.
|
||||
*/
|
||||
public static final int OVERLAY_PERMISSION_REQ_CODE = 4242;
|
||||
|
||||
/**
|
||||
* Loads the given URL and displays the conference. If the specified URL is null, the welcome
|
||||
* page is displayed instead.
|
||||
* Instance of the {@JitsiMeetView} which this activity will display.
|
||||
*/
|
||||
private JitsiMeetView view;
|
||||
|
||||
/**
|
||||
* Loads the given URL and displays the conference. If the specified URL is
|
||||
* null, the welcome page is displayed instead.
|
||||
*
|
||||
* @param url - The conference URL.
|
||||
*/
|
||||
public void loadURL(@Nullable URL url) {
|
||||
jitsiMeetView.loadURL(url);
|
||||
view.loadURL(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
protected void onActivityResult(
|
||||
int requestCode,
|
||||
int resultCode,
|
||||
Intent data) {
|
||||
if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
if (!Settings.canDrawOverlays(this)) {
|
||||
// Permission not granted...
|
||||
// Permission not granted.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setContentView(jitsiMeetView);
|
||||
setContentView(view);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,24 +98,34 @@ public class JitsiMeetBaseActivity extends AppCompatActivity {
|
|||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
jitsiMeetView = new JitsiMeetView(this);
|
||||
jitsiMeetView.loadURL(null);
|
||||
|
||||
/**
|
||||
* In debug mode React needs permission to write over other apps in order to display the
|
||||
* warning and error overlays.
|
||||
*/
|
||||
if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
|
||||
!Settings.canDrawOverlays(this)) {
|
||||
view = new JitsiMeetView(this);
|
||||
view.loadURL(null);
|
||||
|
||||
// In debug mode React needs permission to write over other apps in
|
||||
// order to display the warning and error overlays.
|
||||
if (BuildConfig.DEBUG
|
||||
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||
&& !Settings.canDrawOverlays(this)) {
|
||||
Intent intent
|
||||
= new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
|
||||
Uri.parse("package:" + getPackageName()));
|
||||
= new Intent(
|
||||
Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
|
||||
Uri.parse("package:" + getPackageName()));
|
||||
|
||||
startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
|
||||
return;
|
||||
}
|
||||
|
||||
setContentView(jitsiMeetView);
|
||||
setContentView(view);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
JitsiMeetView.onHostDestroy(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,21 +136,13 @@ public class JitsiMeetBaseActivity extends AppCompatActivity {
|
|||
JitsiMeetView.onNewIntent(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
JitsiMeetView.onHostDestroy(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
JitsiMeetView.onHostPause(this);
|
||||
}
|
||||
|
||||
|
@ -146,7 +152,7 @@ public class JitsiMeetBaseActivity extends AppCompatActivity {
|
|||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
JitsiMeetView.onHostResume(this);
|
||||
}
|
||||
|
||||
}
|
|
@ -32,56 +32,58 @@ import com.facebook.react.common.LifecycleState;
|
|||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
public class JitsiMeetView extends FrameLayout {
|
||||
/**
|
||||
* Background color used by this view and the React Native root view.
|
||||
* Background color used by {@code JitsiMeetView} and the React Native root
|
||||
* view.
|
||||
*/
|
||||
private static final int BACKGROUND_COLOR = 0xFF111111;
|
||||
|
||||
/**
|
||||
* {@JitsiMeetView.Listener} instance for reporting events occurring in Jitsi Meet.
|
||||
* Reference to the single instance of this class we currently allow. It's
|
||||
* currently used for fetching the instance from the listener's callbacks.
|
||||
*
|
||||
* TODO: lift this limitation.
|
||||
*/
|
||||
private static JitsiMeetView instance;
|
||||
|
||||
/**
|
||||
* React Native bridge. The instance manager allows embedding applications
|
||||
* to create multiple root views off the same JavaScript bundle.
|
||||
*/
|
||||
private static ReactInstanceManager reactInstanceManager;
|
||||
|
||||
/**
|
||||
* {@JitsiMeetView.Listener} instance for reporting events occurring in
|
||||
* Jitsi Meet.
|
||||
*/
|
||||
private JitsiMeetView.Listener listener;
|
||||
|
||||
/**
|
||||
* Reference to the single instance of this class we currently allow. It's currently used for
|
||||
* fetching the instance from the listener's callbacks.
|
||||
*
|
||||
* TODO: lift this limitation.
|
||||
*/
|
||||
private static JitsiMeetView mInstance;
|
||||
|
||||
/**
|
||||
* React Native bridge. The instance manager allows embedding applications to create multiple
|
||||
* root views off the same JavaScript bundle.
|
||||
*/
|
||||
private static ReactInstanceManager mReactInstanceManager;
|
||||
|
||||
/**
|
||||
* React Native root view.
|
||||
*/
|
||||
private ReactRootView mReactRootView;
|
||||
private ReactRootView reactRootView;
|
||||
|
||||
public JitsiMeetView(@NonNull Context context) {
|
||||
super(context);
|
||||
|
||||
if (mInstance != null) {
|
||||
throw new RuntimeException("Only a single instance is currently allowed");
|
||||
if (instance != null) {
|
||||
throw new RuntimeException(
|
||||
"Only a single instance is currently allowed");
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Only allow a single instance for now. All React Native modules are
|
||||
* kinda singletons so global state would be broken since we have a single
|
||||
* bridge. Once we have that sorted out multiple instances of JitsiMeetView
|
||||
* will be allowed.
|
||||
* TODO: Only allow a single instance for now. All React Native modules
|
||||
* are kinda singletons so global state would be broken since we have a
|
||||
* single bridge. Once we have that sorted out multiple instances of
|
||||
* JitsiMeetView will be allowed.
|
||||
*/
|
||||
mInstance = this;
|
||||
instance = this;
|
||||
|
||||
setBackgroundColor(BACKGROUND_COLOR);
|
||||
|
||||
if (mReactInstanceManager == null) {
|
||||
initReactInstanceManager(((Activity)context).getApplication());
|
||||
if (reactInstanceManager == null) {
|
||||
initReactInstanceManager(((Activity) context).getApplication());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,7 +93,7 @@ public class JitsiMeetView extends FrameLayout {
|
|||
* @returns The {@JitsiMeetView} instance.
|
||||
*/
|
||||
public static JitsiMeetView getInstance() {
|
||||
return mInstance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,14 +106,15 @@ public class JitsiMeetView extends FrameLayout {
|
|||
}
|
||||
|
||||
/**
|
||||
* Internal method to initialize the React Native instance manager. We create a single instance
|
||||
* in order to load the JavaScript bundle a single time. All <tt>ReactRootView</tt> instances
|
||||
* will be tied to the one and only <tt>ReactInstanceManager</tt>.
|
||||
* Internal method to initialize the React Native instance manager. We
|
||||
* create a single instance in order to load the JavaScript bundle a single
|
||||
* time. All <tt>ReactRootView</tt> instances will be tied to the one and
|
||||
* only <tt>ReactInstanceManager</tt>.
|
||||
*
|
||||
* @param application - <tt>Application</tt> instance which is running.
|
||||
*/
|
||||
private static void initReactInstanceManager(Application application) {
|
||||
mReactInstanceManager = ReactInstanceManager.builder()
|
||||
reactInstanceManager = ReactInstanceManager.builder()
|
||||
.setApplication(application)
|
||||
.setBundleAssetName("index.android.bundle")
|
||||
.setJSMainModuleName("index.android")
|
||||
|
@ -130,8 +133,8 @@ public class JitsiMeetView extends FrameLayout {
|
|||
}
|
||||
|
||||
/**
|
||||
* Loads the given URL and displays the conference. If the specified URL is null, the welcome
|
||||
* page is displayed instead.
|
||||
* Loads the given URL and displays the conference. If the specified URL is
|
||||
* null, the welcome page is displayed instead.
|
||||
*
|
||||
* @param url - The conference URL.
|
||||
*/
|
||||
|
@ -142,17 +145,18 @@ public class JitsiMeetView extends FrameLayout {
|
|||
props.putString("url", url.toString());
|
||||
}
|
||||
|
||||
// TODO: ReactRootView#setAppProperties is only available on React Native 0.45, so destroy
|
||||
// the current root view and create a new one.
|
||||
if (mReactRootView != null) {
|
||||
removeView(mReactRootView);
|
||||
mReactRootView = null;
|
||||
// TODO: ReactRootView#setAppProperties is only available on React
|
||||
// Native 0.45, so destroy the current root view and create a new one.
|
||||
if (reactRootView != null) {
|
||||
removeView(reactRootView);
|
||||
reactRootView = null;
|
||||
}
|
||||
|
||||
mReactRootView = new ReactRootView(getContext());
|
||||
mReactRootView.startReactApplication(mReactInstanceManager, "App", props);
|
||||
mReactRootView.setBackgroundColor(BACKGROUND_COLOR);
|
||||
addView(mReactRootView);
|
||||
reactRootView = new ReactRootView(getContext());
|
||||
reactRootView
|
||||
.startReactApplication(reactInstanceManager, "App", props);
|
||||
reactRootView.setBackgroundColor(BACKGROUND_COLOR);
|
||||
addView(reactRootView);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -165,15 +169,17 @@ public class JitsiMeetView extends FrameLayout {
|
|||
}
|
||||
|
||||
/**
|
||||
* Activity lifecycle method which should be called from <tt>Activity.onBackPressed</tt> so
|
||||
* we can do the required internal processing.
|
||||
* Activity lifecycle method which should be called from
|
||||
* <tt>Activity.onBackPressed</tt> so we can do the required internal
|
||||
* processing.
|
||||
*
|
||||
* @return - true if the back-press was processed, false otherwise. In case false is returned
|
||||
* the application should call the parent's implementation.
|
||||
* @return - true if the back-press was processed, false otherwise. In case
|
||||
* false is returned the application should call the parent's
|
||||
* implementation.
|
||||
*/
|
||||
public static boolean onBackPressed() {
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onBackPressed();
|
||||
if (reactInstanceManager != null) {
|
||||
reactInstanceManager.onBackPressed();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -181,52 +187,54 @@ public class JitsiMeetView extends FrameLayout {
|
|||
}
|
||||
|
||||
/**
|
||||
* Activity lifecycle method which should be called from <tt>Activity.onDestroy</tt> so
|
||||
* we can do the required internal processing.
|
||||
* Activity lifecycle method which should be called from
|
||||
* <tt>Activity.onDestroy</tt> so we can do the required internal
|
||||
* processing.
|
||||
*
|
||||
* @param activity - <tt>Activity</tt> being destroyed.
|
||||
*/
|
||||
public static void onHostDestroy(Activity activity) {
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onHostDestroy(activity);
|
||||
if (reactInstanceManager != null) {
|
||||
reactInstanceManager.onHostDestroy(activity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Activity lifecycle method which should be called from <tt>Activity.onPause</tt> so
|
||||
* we can do the required internal processing.
|
||||
* Activity lifecycle method which should be called from
|
||||
* <tt>Activity.onPause</tt> so we can do the required internal processing.
|
||||
*
|
||||
* @param activity - <tt>Activity</tt> being paused.
|
||||
*/
|
||||
public static void onHostPause(Activity activity) {
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onHostPause(activity);
|
||||
if (reactInstanceManager != null) {
|
||||
reactInstanceManager.onHostPause(activity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Activity lifecycle method which should be called from <tt>Activity.onResume</tt> so
|
||||
* we can do the required internal processing.
|
||||
* Activity lifecycle method which should be called from
|
||||
* <tt>Activity.onResume</tt> so we can do the required internal processing.
|
||||
*
|
||||
* @param activity - <tt>Activity</tt> being resumed.
|
||||
*/
|
||||
public static void onHostResume(Activity activity) {
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onHostResume(activity, null);
|
||||
if (reactInstanceManager != null) {
|
||||
reactInstanceManager.onHostResume(activity, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Activity lifecycle method which should be called from <tt>Activity.onNewIntent</tt> so
|
||||
* we can do the required internal processing. Note that this is only needed if the activity's
|
||||
* "launchMode" was set to "singleTask". This is required for deep linking to work once the
|
||||
* application is already running.
|
||||
* Activity lifecycle method which should be called from
|
||||
* <tt>Activity.onNewIntent</tt> so we can do the required internal
|
||||
* processing. Note that this is only needed if the activity's "launchMode"
|
||||
* was set to "singleTask". This is required for deep linking to work once
|
||||
* the application is already running.
|
||||
*
|
||||
* @param intent - <tt>Intent</tt> instance which was received.
|
||||
*/
|
||||
public static void onNewIntent(Intent intent) {
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onNewIntent(intent);
|
||||
if (reactInstanceManager != null) {
|
||||
reactInstanceManager.onNewIntent(intent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,33 +243,38 @@ public class JitsiMeetView extends FrameLayout {
|
|||
*/
|
||||
public interface Listener {
|
||||
/**
|
||||
* Called when joining a conference fails or an ongoing conference is interrupted due to a
|
||||
* failure.
|
||||
* @param data - HashMap with an "error" key describing the problem, and a "url" key with
|
||||
* the conference URL.
|
||||
* Called when joining a conference fails or an ongoing conference is
|
||||
* interrupted due to a failure.
|
||||
*
|
||||
* @param data - HashMap with an "error" key describing the problem, and
|
||||
* a "url" key with the conference URL.
|
||||
*/
|
||||
void onConferenceFailed(HashMap<String, Object> data);
|
||||
|
||||
/**
|
||||
* Called when a conference was joined.
|
||||
*
|
||||
* @param data - HashMap with a "url" key with the conference URL.
|
||||
*/
|
||||
void onConferenceJoined(HashMap<String, Object> data);
|
||||
|
||||
/**
|
||||
* Called when the conference was left, typically after hanging up.
|
||||
*
|
||||
* @param data - HashMap with a "url" key with the conference URL.
|
||||
*/
|
||||
void onConferenceLeft(HashMap<String, Object> data);
|
||||
|
||||
/**
|
||||
* Called before the conference is joined.
|
||||
*
|
||||
* @param data - HashMap with a "url" key with the conference URL.
|
||||
*/
|
||||
void onConferenceWillJoin(HashMap<String, Object> data);
|
||||
|
||||
/**
|
||||
* Called before the conference is left.
|
||||
*
|
||||
* @param data - HashMap with a "url" key with the conference URL.
|
||||
*/
|
||||
void onConferenceWillLeave(HashMap<String, Object> data);
|
||||
|
|
|
@ -25,7 +25,6 @@ import org.jitsi.meet.sdk.JitsiMeetView;
|
|||
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
/**
|
||||
* Module implementing a simple API to enable a proximity sensor-controlled
|
||||
* wake lock. When the lock is held, if the proximity sensor detects a nearby
|
||||
|
@ -61,20 +60,22 @@ public class ExternalAPIModule extends ReactContextBaseJavaModule {
|
|||
|
||||
/**
|
||||
* Dispatches an event that occurred on JavaScript to the view's listener.
|
||||
*
|
||||
* @param name - Event name.
|
||||
* @param data - Ancillary data for the event.
|
||||
*/
|
||||
@ReactMethod
|
||||
public void sendEvent(final String name, ReadableMap data) {
|
||||
JitsiMeetView view = JitsiMeetView.getInstance();
|
||||
JitsiMeetView.Listener listener = view != null ? view.getListener() : null;
|
||||
JitsiMeetView.Listener listener
|
||||
= view != null ? view.getListener() : null;
|
||||
|
||||
if (listener == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Sigh, converting a ReadableMap to a HashMap is not supported until React Native
|
||||
// 0.46.
|
||||
// TODO: Sigh, converting a ReadableMap to a HashMap is not supported
|
||||
// until React Native 0.46.
|
||||
final HashMap<String, Object> dataMap = new HashMap<>();
|
||||
|
||||
try {
|
||||
|
|
|
@ -45,7 +45,7 @@ public class ExternalAPIPackage implements ReactPackage {
|
|||
*/
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(
|
||||
ReactApplicationContext reactContext) {
|
||||
ReactApplicationContext reactContext) {
|
||||
List<NativeModule> modules = new ArrayList<>();
|
||||
|
||||
modules.add(new ExternalAPIModule(reactContext));
|
||||
|
@ -58,7 +58,7 @@ public class ExternalAPIPackage implements ReactPackage {
|
|||
*/
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(
|
||||
ReactApplicationContext reactContext) {
|
||||
ReactApplicationContext reactContext) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,4 +108,3 @@ The `data` dictionary contains a "url" key with the conference URL.
|
|||
Called before a conference is left.
|
||||
|
||||
The `data` dictionary contains a "url" key with the conference URL.
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#import "JitsiMeetView.h"
|
||||
|
||||
|
||||
@interface ExternalAPI : NSObject<RCTBridgeModule>
|
||||
@end
|
||||
|
||||
|
@ -40,25 +39,20 @@ RCT_EXPORT_METHOD(sendEvent:(NSString*)name data:(NSDictionary *) data) {
|
|||
return;
|
||||
}
|
||||
|
||||
if ([name isEqualToString:@"CONFERENCE_FAILED"] &&
|
||||
[delegate respondsToSelector:@selector(conferenceFailed:)]) {
|
||||
|
||||
if ([name isEqualToString:@"CONFERENCE_FAILED"]
|
||||
&& [delegate respondsToSelector:@selector(conferenceFailed:)]) {
|
||||
[delegate conferenceFailed:data];
|
||||
} else if ([name isEqualToString:@"CONFERENCE_JOINED"] &&
|
||||
[delegate respondsToSelector:@selector(conferenceJoined:)]) {
|
||||
|
||||
} else if ([name isEqualToString:@"CONFERENCE_JOINED"]
|
||||
&& [delegate respondsToSelector:@selector(conferenceJoined:)]) {
|
||||
[delegate conferenceJoined:data];
|
||||
} else if ([name isEqualToString:@"CONFERENCE_LEFT"] &&
|
||||
[delegate respondsToSelector:@selector(conferenceLeft:)]) {
|
||||
|
||||
} else if ([name isEqualToString:@"CONFERENCE_LEFT"]
|
||||
&& [delegate respondsToSelector:@selector(conferenceLeft:)]) {
|
||||
[delegate conferenceLeft:data];
|
||||
} else if ([name isEqualToString:@"CONFERENCE_WILL_JOIN"] &&
|
||||
[delegate respondsToSelector:@selector(conferenceWillJoin:)]) {
|
||||
|
||||
} else if ([name isEqualToString:@"CONFERENCE_WILL_JOIN"]
|
||||
&& [delegate respondsToSelector:@selector(conferenceWillJoin:)]) {
|
||||
[delegate conferenceWillJoin:data];
|
||||
} else if ([name isEqualToString:@"CONFERENCE_WILL_LEAVE"] &&
|
||||
[delegate respondsToSelector:@selector(conferenceWillLeave:)]) {
|
||||
|
||||
} else if ([name isEqualToString:@"CONFERENCE_WILL_LEAVE"]
|
||||
&& [delegate respondsToSelector:@selector(conferenceWillLeave:)]) {
|
||||
[delegate conferenceWillLeave:data];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
sourceApplication:(NSString *)sourceApplication
|
||||
annotation:(id)annotation;
|
||||
|
||||
+ (instancetype) getInstance;
|
||||
+ (instancetype)getInstance;
|
||||
|
||||
- (void)loadURL:(nullable NSURL *)url;
|
||||
|
||||
|
|
Loading…
Reference in New Issue