android: update SDK documentation

This commit is contained in:
Saúl Ibarra Corretgé 2019-03-06 15:33:43 +01:00
parent 20edb7c279
commit a7018970ca
6 changed files with 118 additions and 102 deletions

View File

@ -33,7 +33,7 @@ dependencies {
} }
``` ```
Also, enable 32bit mode for react-native, since react-native only supports 32bit apps. (If you have a 64bit device, it will not run unless this setting it set) Also, enable 32bit mode for react-native, since the react-native version we currently depend on only supports 32bit apps. (If you have a 64bit device, it will not run unless this setting it set).
```gradle ```gradle
android { android {
@ -167,14 +167,14 @@ View is strongly recommended.
package org.jitsi.example; package org.jitsi.example;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AppCompatActivity; import android.support.v4.app.FragmentActivity;
import org.jitsi.meet.sdk.JitsiMeetView; import org.jitsi.meet.sdk.JitsiMeetView;
import org.jitsi.meet.sdk.ReactActivityLifecycleCallbacks; import org.jitsi.meet.sdk.ReactActivityLifecycleCallbacks;
// Example // Example
// //
public class MainActivity extends AppCompatActivity { public class MainActivity extends FragmentActivity implements JitsiMeetActivityInterface {
private JitsiMeetView view; private JitsiMeetView view;
@Override @Override
@ -182,13 +182,13 @@ public class MainActivity extends AppCompatActivity {
int requestCode, int requestCode,
int resultCode, int resultCode,
Intent data) { Intent data) {
ReactActivityLifecycleCallbacks.onActivityResult( JitsiMeetActivityDelegate.onActivityResult(
this, requestCode, resultCode, data); this, requestCode, resultCode, data);
} }
@Override @Override
public void onBackPressed() { public void onBackPressed() {
ReactActivityLifecycleCallbacks.onBackPressed(); JitsiMeetActivityDelegate.onBackPressed();
} }
@Override @Override
@ -196,7 +196,10 @@ public class MainActivity extends AppCompatActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
view = new JitsiMeetView(this); view = new JitsiMeetView(this);
view.loadURL(null); JitsiMeetConferenceOptions options = new JitsiMeetConferenceOptions.Builder()
.setRoom("https://meet.jit.si/test123")
.build();
view.join(options);
setContentView(view); setContentView(view);
} }
@ -208,12 +211,12 @@ public class MainActivity extends AppCompatActivity {
view.dispose(); view.dispose();
view = null; view = null;
ReactActivityLifecycleCallbacks.onHostDestroy(this); JitsiMeetActivityDelegate.onHostDestroy(this);
} }
@Override @Override
public void onNewIntent(Intent intent) { public void onNewIntent(Intent intent) {
ReactActivityLifecycleCallbacks.onNewIntent(intent); JitsiMeetActivityDelegate.onNewIntent(intent);
} }
@Override @Override
@ -221,21 +224,21 @@ public class MainActivity extends AppCompatActivity {
final int requestCode, final int requestCode,
final String[] permissions, final String[] permissions,
final int[] grantResults) { final int[] grantResults) {
ReactActivityLifecycleCallbacks.onRequestPermissionsResult(requestCode, permissions, grantResults); JitsiMeetActivityDelegate.onRequestPermissionsResult(requestCode, permissions, grantResults);
} }
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
ReactActivityLifecycleCallbacks.onHostResume(this); JitsiMeetActivityDelegate.onHostResume(this);
} }
@Override @Override
protected void onStop() { protected void onStop() {
super.onStop(); super.onStop();
ReactActivityLifecycleCallbacks.onHostPause(this); JitsiMeetActivityDelegate.onHostPause(this);
} }
} }
``` ```
@ -262,103 +265,62 @@ implementation("com.github.bumptech.glide:annotations:${glideVersion}") {
### JitsiMeetActivity ### JitsiMeetActivity
This class encapsulates a high level API in the form of an Android `Activity` This class encapsulates a high level API in the form of an Android `FragmentActivity`
which displays a single `JitsiMeetView`. which displays a single `JitsiMeetView`. You can pass a URL as a `ACTION_VIEW`
on the Intent when starting it and it will join the conference, and will be
automatically terminated (finish() will be called on the activity) when the
conference ends or fails.
### JitsiMeetView ### JitsiMeetView
The `JitsiMeetView` class is the core of Jitsi Meet SDK. It's designed to The `JitsiMeetView` class is the core of Jitsi Meet SDK. It's designed to
display a Jitsi Meet conference (or a welcome page). display a Jitsi Meet conference (or a welcome page).
#### join(options)
Joins the conference specified by the given `JitsiMeetConferenceOptions`.
#### leave()
Leaves the currently active conference. If the welcome page is enabled it will
go back to it, otherwise a black window will be shown.
#### dispose() #### dispose()
Releases all resources associated with this view. This method MUST be called Releases all resources associated with this view. This method MUST be called
when the Activity holding this view is going to be destroyed, usually in the when the Activity holding this view is going to be destroyed, usually in the
`onDestroy()` method. `onDestroy()` method.
#### getDefaultURL()
Returns the default base URL used to join a conference when a partial URL (e.g.
a room name only) is specified to `loadURLString`/`loadURLObject`. If not set or
if set to `null`, the default built in JavaScript is used: https://meet.jit.si.
#### getListener() #### getListener()
Returns the `JitsiMeetViewListener` instance attached to the view. Returns the `JitsiMeetViewListener` instance attached to the view.
#### isPictureInPictureEnabled()
Returns `true` if Picture-in-Picture is enabled; `false`, otherwise. If not
explicitly set (by a preceding `setPictureInPictureEnabled` call), defaults to
`true` if the platform supports Picture-in-Picture natively; `false`, otherwise.
#### isWelcomePageEnabled()
Returns true if the Welcome page is enabled; otherwise, false. If false, a black
empty view will be rendered when not in a conference. Defaults to false.
#### loadURL(URL)
Loads a specific URL which may identify a conference to join. If the specified
URL is null and the Welcome page is enabled, the Welcome page is displayed
instead.
#### loadURLString(String)
Loads a specific URL which may identify a conference to join. If the specified
URL is null and the Welcome page is enabled, the Welcome page is displayed
instead.
#### loadURLObject(Bundle)
Loads a specific URL which may identify a conference to join. The URL is
specified in the form of a Bundle of properties which (1) internally are
sufficient to construct a URL (string) while (2) abstracting the specifics of
constructing the URL away from API clients/consumers. If the specified URL is
null and the Welcome page is enabled, the Welcome page is displayed instead.
Example:
```java
Bundle config = new Bundle();
config.putBoolean("startWithAudioMuted", true);
config.putBoolean("startWithVideoMuted", false);
Bundle urlObject = new Bundle();
urlObject.putBundle("config", config);
urlObject.putString("url", "https://meet.jit.si/Test123");
view.loadURLObject(urlObject);
```
#### setDefaultURL(URL)
Sets the default URL. See `getDefaultURL` for more information.
NOTE: Must be called before (if at all) `loadURL`/`loadURLString` for it to take
effect.
#### setListener(listener) #### setListener(listener)
Sets the given listener (class implementing the `JitsiMeetViewListener` Sets the given listener (class implementing the `JitsiMeetViewListener`
interface) on the view. interface) on the view.
#### setPictureInPictureEnabled(boolean) ### JitsiMeetConferenceOptions
Sets whether Picture-in-Picture is enabled. If not set, Jitsi Meet SDK This object encapsulates all the options that can be tweaked when joining
automatically enables/disables Picture-in-Picture based on native platform a conference.
support.
NOTE: Must be called (if at all) before `loadURL`/`loadURLString` for it to take Example:
effect.
#### setWelcomePageEnabled(boolean) ```java
JitsiMeetConferenceOptions options = new JitsiMeetConferenceOptions.Builder()
.setServerURL(new URL("https://meet.jit.si"))
.setRoom("test123")
.setAudioMuted(false)
.setVideoMuted(false)
.setAudioOnly(false)
.setWelcomePageEnabled(false)
.build();
```
Sets whether the Welcome page is enabled. See `isWelcomePageEnabled` for more See the `JitsiMeetConferenceOptions` implementation for all available options.
information.
NOTE: Must be called (if at all) before `loadURL`/`loadURLString` for it to take ### JitsiMeetActivityDelegate
effect.
### ReactActivityLifecycleCallbacks
This class handles the interaction between `JitsiMeetView` and its enclosing This class handles the interaction between `JitsiMeetView` and its enclosing
`Activity`. Generally this shouldn't be consumed by users, because they'd be `Activity`. Generally this shouldn't be consumed by users, because they'd be
@ -470,10 +432,6 @@ rules file: https://github.com/jitsi/jitsi-meet/blob/master/android/app/proguard
Picture-in-Picture style scenario, in a rectangle too small to accommodate its Picture-in-Picture style scenario, in a rectangle too small to accommodate its
"full" UI. "full" UI.
Jitsi Meet SDK automatically enables (unless explicitly disabled by a
`setPictureInPictureEnabled(false)` call) Android's native Picture-in-Picture
mode iff the platform is supported i.e. Android >= Oreo.
## Dropbox integration ## Dropbox integration
To setup the Dropbox integration, follow these steps: To setup the Dropbox integration, follow these steps:

View File

@ -55,8 +55,6 @@ public class MainActivity extends FragmentActivity implements JitsiMeetActivityI
private static final int OVERLAY_PERMISSION_REQUEST_CODE private static final int OVERLAY_PERMISSION_REQUEST_CODE
= (int) (Math.random() * Short.MAX_VALUE); = (int) (Math.random() * Short.MAX_VALUE);
private static final String TAG = "MainActivity";
private JitsiMeetFragment getFragment() { private JitsiMeetFragment getFragment() {
return (JitsiMeetFragment) getSupportFragmentManager().findFragmentById(R.id.jitsiFragment); return (JitsiMeetFragment) getSupportFragmentManager().findFragmentById(R.id.jitsiFragment);
} }
@ -186,8 +184,8 @@ public class MainActivity extends FragmentActivity implements JitsiMeetActivityI
if (canRequestOverlayPermission() && !Settings.canDrawOverlays(this)) { if (canRequestOverlayPermission() && !Settings.canDrawOverlays(this)) {
Intent intent Intent intent
= new Intent( = new Intent(
Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName())); Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, OVERLAY_PERMISSION_REQUEST_CODE); startActivityForResult(intent, OVERLAY_PERMISSION_REQUEST_CODE);
return; return;

View File

@ -21,12 +21,26 @@ import android.os.Bundle;
import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactInstanceManager;
public class JitsiMeet { public class JitsiMeet {
/**
* Default {@link JitsiMeetConferenceOptions} which will be used for all conferences. When
* joining a conference these options will be merged with the ones passed to
* {@link JitsiMeetView} join().
*/
private static JitsiMeetConferenceOptions defaultConferenceOptions; private static JitsiMeetConferenceOptions defaultConferenceOptions;
public static JitsiMeetConferenceOptions getDefaultConferenceOptions() { public static JitsiMeetConferenceOptions getDefaultConferenceOptions() {
return defaultConferenceOptions; return defaultConferenceOptions;
} }
public static void setDefaultConferenceOptions(JitsiMeetConferenceOptions options) {
defaultConferenceOptions = options;
}
/**
* Helper to get the default conference options as a {@link Bundle}.
*
* @return a {@link Bundle} with the default conference options.
*/
static Bundle getDefaultProps() { static Bundle getDefaultProps() {
if (defaultConferenceOptions != null) { if (defaultConferenceOptions != null) {
return defaultConferenceOptions.asProps(); return defaultConferenceOptions.asProps();
@ -35,10 +49,9 @@ public class JitsiMeet {
return new Bundle(); return new Bundle();
} }
public static void setDefaultConferenceOptions(JitsiMeetConferenceOptions options) { /**
defaultConferenceOptions = options; * Used in development mode. It displays the React Native development menu.
} */
public static void showDevOptions() { public static void showDevOptions() {
ReactInstanceManager reactInstanceManager ReactInstanceManager reactInstanceManager
= ReactInstanceManagerHolder.getReactInstanceManager(); = ReactInstanceManagerHolder.getReactInstanceManager();

View File

@ -21,17 +21,45 @@ import android.os.Bundle;
import java.net.URL; import java.net.URL;
/**
* This class represents the options when joining a Jitsi Meet conference. The user can create an
* instance by using {@link JitsiMeetConferenceOptions.Builder} and setting the desired options
* there.
*
* The resulting {@link JitsiMeetConferenceOptions} object is immutable and represents how the
* conference will be joined.
*/
public class JitsiMeetConferenceOptions { public class JitsiMeetConferenceOptions {
/**
* Server where the conference should take place.
*/
private URL serverURL; private URL serverURL;
/**
* Room name.
*/
private String room; private String room;
/**
* JWT token used for authentication.
*/
private String token; private String token;
/**
* Color scheme override, see: https://github.com/jitsi/jitsi-meet/blob/dbedee5e22e5dcf9c92db96ef5bb3c9982fc526d/react/features/base/color-scheme/defaultScheme.js
*/
private Bundle colorScheme; private Bundle colorScheme;
/**
* Set to {@code true} to join the conference with audio / video muted or to start in audio
* only mode respectively.
*/
private Boolean audioMuted; private Boolean audioMuted;
private Boolean audioOnly; private Boolean audioOnly;
private Boolean videoMuted; private Boolean videoMuted;
/**
* Set to {@code true} to enable the welcome page. Typically SDK users won't need this enabled
* since the host application decides which meeting to join.
*/
private Boolean welcomePageEnabled; private Boolean welcomePageEnabled;
public static class Builder { public static class Builder {

View File

@ -29,15 +29,15 @@ import android.view.ViewGroup;
import java.net.URL; import java.net.URL;
/** /**
* Base Activity for applications integrating Jitsi Meet at a higher level. It * Base {@link Fragment} for applications integrating Jitsi Meet at a higher level. It
* contains all the required wiring between the {@code JitsiMeetView} and * contains all the required wiring between the {@code JitsiMeetView} and
* the Activity lifecycle methods already implemented. * the Fragment lifecycle methods already implemented.
* *
* In this activity we use a single {@code JitsiMeetView} instance. This * In this fragment we use a single {@code JitsiMeetView} instance. This
* instance gives us access to a view which displays the welcome page and the * instance gives us access to a view which displays the welcome page and the
* conference itself. All lifetime methods associated with this Activity are * conference itself. All lifecycle methods associated with this Fragment are
* hooked to the React Native subsystem via proxy calls through the * hooked to the React Native subsystem via proxy calls through the
* {@code JitsiMeetView} static methods. * {@code JitsiMeetActivityDelegate} static methods.
*/ */
public class JitsiMeetFragment extends Fragment { public class JitsiMeetFragment extends Fragment {

View File

@ -51,6 +51,13 @@ public class JitsiMeetView extends BaseReactView<JitsiMeetViewListener> {
// fine to have this field volatile without additional synchronization. // fine to have this field volatile without additional synchronization.
private volatile String url; private volatile String url;
/**
* Helper method to recursively merge 2 {@link Bundle} objects representing React Native props.
*
* @param a - The first {@link Bundle}.
* @param b - The second {@link Bundle}.
* @return The merged {@link Bundle} object.
*/
private static Bundle mergeProps(@Nullable Bundle a, @Nullable Bundle b) { private static Bundle mergeProps(@Nullable Bundle a, @Nullable Bundle b) {
Bundle result = new Bundle(); Bundle result = new Bundle();
@ -125,27 +132,39 @@ public class JitsiMeetView extends BaseReactView<JitsiMeetViewListener> {
} }
} }
/**
* Joins the conference specified by the given {@link JitsiMeetConferenceOptions}.
* @param options - Description of what conference must be joined and what options will be used
* when doing so.
*/
public void join(@Nullable JitsiMeetConferenceOptions options) { public void join(@Nullable JitsiMeetConferenceOptions options) {
setProps(options != null ? options.asProps() : new Bundle()); setProps(options != null ? options.asProps() : new Bundle());
} }
/**
* Leaves the currently active conference.
*/
public void leave() { public void leave() {
setProps(new Bundle()); setProps(new Bundle());
} }
/**
* Helper method to set the React Native props.
* @param newProps - New props to be set on the React Native view.
*/
private void setProps(@NonNull Bundle newProps) { private void setProps(@NonNull Bundle newProps) {
// Merge the default options with the newly provided ones. // Merge the default options with the newly provided ones.
Bundle props = mergeProps(JitsiMeet.getDefaultProps(), newProps); Bundle props = mergeProps(JitsiMeet.getDefaultProps(), newProps);
// XXX The method loadURLObject: is supposed to be imperative i.e. // XXX The setProps() method is supposed to be imperative i.e.
// a second invocation with one and the same URL is expected to join // a second invocation with one and the same URL is expected to join
// the respective conference again if the first invocation was followed // the respective conference again if the first invocation was followed
// by leaving the conference. However, React and, respectively, // by leaving the conference. However, React and, respectively,
// appProperties/initialProperties are declarative expressions i.e. one // appProperties/initialProperties are declarative expressions i.e. one
// and the same URL will not trigger an automatic re-render in the // and the same URL will not trigger an automatic re-render in the
// JavaScript source code. The workaround implemented bellow introduces // JavaScript source code. The workaround implemented bellow introduces
// imperativeness in React Component props by defining a unique value // "imperativeness" in React Component props by defining a unique value
// per loadURLObject: invocation. // per setProps() invocation.
props.putLong("timestamp", System.currentTimeMillis()); props.putLong("timestamp", System.currentTimeMillis());
createReactRootView("App", props); createReactRootView("App", props);