我在android中使用opentok videocall库。我想要与WhatsApp相同的功能。在这个应用程序中,我的屏幕上有3个订阅者和1个发布者视图。当我们触摸任何订阅者视图时,它应该以全屏视图切换。我附加了一个屏幕,以便更好地理解。 当我们触摸订户2视图时,在此屏幕中,它应该与订户1交换其视图,当我们按任何其他订户视图时,它应该与大视图的主视图交换。
屏幕二
屏幕三
我的代码在这里,我可以相互切换订阅者,但无法在主屏幕中管理它们。
清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tokbox.android.tutorials.simple_multiparty">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
我的activity_main.xml文件在这里
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
android:layout_width="match_parent" android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<RelativeLayout
android:id="@+id/video_call_main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"
android:keepScreenOn="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
android:id="@+id/subscriberview0">
</RelativeLayout>
<RelativeLayout
android:layout_width="120dp"
android:layout_height="150dp"
android:layout_toLeftOf="@+id/subscriberview1"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:background="#154612"
android:id="@+id/subscriberview2">
</RelativeLayout>
<RelativeLayout
android:layout_width="120dp"
android:layout_height="150dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp"
android:layout_marginRight="5dp"
android:background="#af1234"
android:layout_toLeftOf="@+id/publisherview"
android:id="@+id/subscriberview1">
</RelativeLayout>
<RelativeLayout
android:background="#86dec6"
android:id="@+id/publisherview"
android:layout_height="150dp"
android:layout_width="100dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="10dp"
android:layout_marginRight="5dp">
</RelativeLayout>
</RelativeLayout>
我的MainActivity.java文件在这里
package com.tokbox.android.tutorials.simple_multiparty;
import android.Manifest;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Point;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.opentok.android.BaseVideoRenderer;
import com.opentok.android.OpentokError;
import com.opentok.android.Publisher;
import com.opentok.android.PublisherKit;
import com.opentok.android.Session;
import com.opentok.android.Stream;
import com.opentok.android.Subscriber;
import com.opentok.android.TextureViewRenderer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.AppSettingsDialog;
import pub.devrel.easypermissions.EasyPermissions;
public class MainActivity extends AppCompatActivity
implements EasyPermissions.PermissionCallbacks,
Publisher.PublisherListener,
Session.SessionListener {
public static final String API_KEY = "46139802";//"46089252";
public static final String TOKEN = "T1==cGFydG5lcl9pZD00NjEzOTgwMiZzaWc9NjZmOGRiY2Q3MDdiNWNiY2M0Yzc4Nzg4NWZlYTZlNzdiYzQyZDRkZDpzZXNzaW9uX2lkPTFfTVg0ME5qRXpPVGd3TW41LU1UVXlPVE13TXpJME9UazNNbjVDWTFaUVpteG1NMnh2UTFocWVWUlBVazloVGxKM1NYUi1mZyZjcmVhdGVfdGltZT0xNTI5MzAzMzQxJm5vbmNlPTAuNDEyNTM2NjMyNDUxODU2MjMmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTUyOTM4OTcwMSZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==";
public static final String SESSION_ID = "1_MX40NjEzOTgwMn5-MTUyOTMwMzI0OTk3Mn5CY1ZQZmxmM2xvQ1hqeVRPUk9hTlJ3SXR-fg";
private static final String TAG = "simple-multiparty " + MainActivity.class.getSimpleName();
private final int MAX_NUM_SUBSCRIBERS = 4;
private static final int RC_SETTINGS_SCREEN_PERM = 123;
private static final int RC_VIDEO_APP_PERM = 124;
private Session mSession;
private Publisher mPublisher;
private ArrayList<Subscriber> mSubscribers = new ArrayList<Subscriber>();
private HashMap<Stream, Subscriber> mSubscriberStreams = new HashMap<Stream, Subscriber>();
private RelativeLayout mPublisherViewContainer;
private RelativeLayout subscriberview0, subscriberview1, subscriberview2;
int widthView;
RelativeLayout.LayoutParams view0Params, view1Params, view2Params, viewParams;
View subscriberViewBig;
View subscriberViewSmall;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPublisherViewContainer = (RelativeLayout) findViewById(R.id.publisherview);
subscriberview0 = (RelativeLayout) findViewById(R.id.subscriberview0);
subscriberview1 = (RelativeLayout) findViewById(R.id.subscriberview1);
subscriberview2 = (RelativeLayout) findViewById(R.id.subscriberview2);
int totalMeasuredwidth = 0;
int Measuredheight = 0;
Point size = new Point();
WindowManager w = getWindowManager();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
w.getDefaultDisplay().getSize(size);
totalMeasuredwidth = size.x;
Measuredheight = size.y;
}else{
Display d = w.getDefaultDisplay();
totalMeasuredwidth = d.getWidth();
Measuredheight = d.getHeight();
}
int paddingInPx = (int) convertDpToPixel(5, MainActivity.this);
totalMeasuredwidth = totalMeasuredwidth - (4*paddingInPx);
widthView = totalMeasuredwidth / 3 ;
Log.d(TAG, "widthView : in pixel "+ widthView);
view0Params = new RelativeLayout.LayoutParams(widthView, (int) convertDpToPixel(150, MainActivity.this));
view1Params = new RelativeLayout.LayoutParams(widthView, (int) convertDpToPixel(150, MainActivity.this));
view2Params = new RelativeLayout.LayoutParams(widthView, (int) convertDpToPixel(150, MainActivity.this));
viewParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
requestPermissions();
subscriberview0.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mPublisherViewContainer.bringToFront();
subscriberview0.setLayoutParams(viewParams);
view1Params.rightMargin = (int) Utility.convertDpToPixel(5, MainActivity.this);
view1Params.bottomMargin = (int) Utility.convertDpToPixel(10, MainActivity.this);
view1Params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
view1Params.addRule(RelativeLayout.LEFT_OF, R.id.publisherview);
subscriberview1.setLayoutParams(view1Params);
subscriberview1.bringToFront();
view2Params.rightMargin = (int) Utility.convertDpToPixel(5, MainActivity.this);
view2Params.bottomMargin = (int) Utility.convertDpToPixel(10, MainActivity.this);
view2Params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
view2Params.addRule(RelativeLayout.LEFT_OF, R.id.subscriberview1);
subscriberview2.setLayoutParams(view2Params);
subscriberview2.bringToFront();
}
});
subscriberview1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mPublisherViewContainer.bringToFront();
view0Params.rightMargin = (int) Utility.convertDpToPixel(5, MainActivity.this);
view0Params.bottomMargin = (int) Utility.convertDpToPixel(10, MainActivity.this);
view0Params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
view0Params.addRule(RelativeLayout.LEFT_OF, R.id.publisherview);
subscriberview0.setLayoutParams(view0Params);
subscriberview0.bringToFront();
viewParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
subscriberview1.setLayoutParams(viewParams);
view2Params.rightMargin = (int) Utility.convertDpToPixel(5, MainActivity.this);
view2Params.bottomMargin = (int) Utility.convertDpToPixel(10, MainActivity.this);
view2Params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
view2Params.addRule(RelativeLayout.LEFT_OF, R.id.subscriberview0);
subscriberview2.setLayoutParams(view2Params);
subscriberview2.bringToFront();
}
});
subscriberview2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mPublisherViewContainer.bringToFront();
view0Params.rightMargin = (int) Utility.convertDpToPixel(3, MainActivity.this);
view0Params.bottomMargin = (int) Utility.convertDpToPixel(10, MainActivity.this);
view0Params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
view0Params.addRule(RelativeLayout.LEFT_OF, R.id.publisherview);
subscriberview0.setLayoutParams(view0Params);
subscriberview0.bringToFront();
view1Params.rightMargin = (int) Utility.convertDpToPixel(5, MainActivity.this);
view1Params.bottomMargin = (int) Utility.convertDpToPixel(10, MainActivity.this);
view1Params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
view1Params.addRule(RelativeLayout.LEFT_OF, R.id.subscriberview0);
subscriberview1.setLayoutParams(view1Params);
subscriberview1.bringToFront();
subscriberview2.setLayoutParams(viewParams);
}
});
}
private int getResIdForSubscriberIndex(int index) {
TypedArray arr = getResources().obtainTypedArray(R.array.subscriber_view_ids);
int subId = arr.getResourceId(index, 0);
arr.recycle();
return subId;
}
public static float convertDpToPixel(float dp, Context context){
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float px = dp * ((float)metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT);
return px;
}
@Override
protected void onStart() {
Log.d(TAG, "onStart");
super.onStart();
}
@Override
protected void onRestart() {
Log.d(TAG, "onRestart");
super.onRestart();
}
@Override
protected void onResume() {
Log.d(TAG, "onResume");
super.onResume();
if (mSession == null) {
return;
}
mSession.onResume();
}
@Override
protected void onPause() {
Log.d(TAG, "onPause");
super.onPause();
if (mSession == null) {
return;
}
mSession.onPause();
if (isFinishing()) {
disconnectSession();
}
}
@Override
protected void onStop() {
Log.d(TAG, "onPause");
super.onStop();
}
@Override
protected void onDestroy() {
Log.d(TAG, "onDestroy");
disconnectSession();
super.onDestroy();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
@Override
public void onPermissionsGranted(int requestCode, List<String> perms) {
Log.d(TAG, "onPermissionsGranted:" + requestCode + ":" + perms.size());
}
@Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
Log.d(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size());
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
new AppSettingsDialog.Builder(this)
.setTitle(getString(R.string.title_settings_dialog))
.setRationale(getString(R.string.rationale_ask_again))
.setPositiveButton(getString(R.string.setting))
.setNegativeButton(getString(R.string.cancel))
.setRequestCode(RC_SETTINGS_SCREEN_PERM)
.build()
.show();
}
}
@AfterPermissionGranted(RC_VIDEO_APP_PERM)
private void requestPermissions() {
String[] perms = {
Manifest.permission.INTERNET,
Manifest.permission.CAMERA,
Manifest.permission.RECORD_AUDIO
};
if (EasyPermissions.hasPermissions(this, perms)) {
//mSession = new Session.Builder(MainActivity.this, OpenTokConfig.API_KEY, OpenTokConfig.SESSION_ID).build();
mSession = new Session.Builder(MainActivity.this, API_KEY, SESSION_ID)
.sessionOptions(new Session.SessionOptions() {
@Override
public boolean useTextureViews() {
return true;
}
}).build();
mSession.setSessionListener(this);
mSession.connect(TOKEN);
} else {
EasyPermissions.requestPermissions(this, getString(R.string.rationale_video_app), RC_VIDEO_APP_PERM, perms);
}
}
@Override
public void onConnected(Session session) {
Log.d(TAG, "onConnected: Connected to session " + session.getSessionId());
mPublisher = new Publisher.Builder(MainActivity.this).name("publisher").build();
mPublisher.setPublisherListener(this);
mPublisher.setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, BaseVideoRenderer.STYLE_VIDEO_FILL);
mPublisherViewContainer.addView(mPublisher.getView());
mSession.publish(mPublisher);
}
@Override
public void onDisconnected(Session session) {
Log.d(TAG, "onDisconnected: disconnected from session " + session.getSessionId());
mSession = null;
}
@Override
public void onError(Session session, OpentokError opentokError) {
Log.d(TAG, "onError: Error (" + opentokError.getMessage() + ") in session " + session.getSessionId());
Toast.makeText(this, "Session error. See the logcat please.", Toast.LENGTH_LONG).show();
finish();
}
@Override
public void onStreamReceived(Session session, Stream stream) {
Log.d(TAG, "onStreamReceived: New stream " + stream.getStreamId() + " in session " + session.getSessionId());
if (mSubscribers.size() + 1 > MAX_NUM_SUBSCRIBERS) {
Toast.makeText(this, "New subscriber ignored. MAX_NUM_SUBSCRIBERS limit reached.", Toast.LENGTH_LONG).show();
return;
}
final Subscriber subscriber = new Subscriber.Builder(MainActivity.this, stream).build();
mSession.subscribe(subscriber);
mSubscribers.add(subscriber);
mSubscriberStreams.put(stream, subscriber);
subscriber.setSubscribeToAudio(false);
int position = mSubscribers.size() - 1;
int id = getResources().getIdentifier("subscriberview" + (new Integer(position)).toString(), "id", MainActivity.this.getPackageName());
RelativeLayout subscriberViewContainer = (RelativeLayout) findViewById(id);
//subscriber.setStyle(BaseVideoRenderer.STYLE_VIDEO_FILL, BaseVideoRenderer.STYLE_VIDEO_FILL);
subscriber.setStyle(TextureViewRenderer.STYLE_VIDEO_SCALE, TextureViewRenderer.STYLE_VIDEO_FIT);
subscriberViewContainer.addView(subscriber.getView());
if (mSubscribers.size() == 1) {
Log.d(TAG, "mSubscribers: view0 visible size : " + mSubscribers.size());
subscriberview1.setVisibility(View.GONE);
subscriberview2.setVisibility(View.GONE);
}
if (mSubscribers.size() == 2) {
Log.d(TAG, "mSubscribers: view1 visible size : " + mSubscribers.size());
subscriberview1.setVisibility(View.VISIBLE);
subscriberview2.setVisibility(View.GONE);
view1Params.rightMargin = (int) Utility.convertDpToPixel(5, MainActivity.this);
view1Params.bottomMargin = (int) Utility.convertDpToPixel(10, MainActivity.this);
view1Params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
view1Params.addRule(RelativeLayout.LEFT_OF, R.id.publisherview);
subscriberview1.setLayoutParams(view1Params);
//subscriberview1.setZ(1);
subscriberview1.bringToFront();
}
if (mSubscribers.size() == 3) {
Log.d(TAG, "mSubscribers: view2 visible size : " + mSubscribers.size());
subscriberview1.setVisibility(View.VISIBLE);
subscriberview2.setVisibility(View.VISIBLE);
view2Params.rightMargin = (int) Utility.convertDpToPixel(5, MainActivity.this);
view2Params.bottomMargin = (int) Utility.convertDpToPixel(10, MainActivity.this);
view2Params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
view2Params.addRule(RelativeLayout.LEFT_OF, R.id.subscriberview1);
subscriberview2.setLayoutParams(view2Params);
//subscriberview1.setZ(1);
subscriberview2.bringToFront();
}
}
@Override
public void onStreamDropped(Session session, Stream stream) {
Log.d(TAG, "onStreamDropped: Stream " + stream.getStreamId() + " dropped from session " + session.getSessionId());
Subscriber subscriber = mSubscriberStreams.get(stream);
if (subscriber == null) {
return;
}
int position = mSubscribers.indexOf(subscriber);
int id = getResources().getIdentifier("subscriberview" + (new Integer(position)).toString(), "id", MainActivity.this.getPackageName());
mSubscribers.remove(subscriber);
mSubscriberStreams.remove(stream);
RelativeLayout subscriberViewContainer = (RelativeLayout) findViewById(id);
subscriberViewContainer.removeView(subscriber.getView());
}
@Override
public void onStreamCreated(PublisherKit publisherKit, Stream stream) {
Log.d(TAG, "onStreamCreated: Own stream " + stream.getStreamId() + " created");
}
@Override
public void onStreamDestroyed(PublisherKit publisherKit, Stream stream) {
Log.d(TAG, "onStreamDestroyed: Own stream " + stream.getStreamId() + " destroyed");
}
@Override
public void onError(PublisherKit publisherKit, OpentokError opentokError) {
Log.d(TAG, "onError: Error (" + opentokError.getMessage() + ") in publisher");
Toast.makeText(this, "Session error. See the logcat please.", Toast.LENGTH_LONG).show();
finish();
}
private void disconnectSession() {
if (mSession == null) {
return;
}
if (mSubscribers.size() > 0) {
for (Subscriber subscriber : mSubscribers) {
if (subscriber != null) {
mSession.unsubscribe(subscriber);
subscriber.destroy();
}
}
}
if (mPublisher != null) {
mPublisherViewContainer.removeView(mPublisher.getView());
mSession.unpublish(mPublisher);
mPublisher.destroy();
mPublisher = null;
}
mSession.disconnect();
}
}
我的实用程序文件在这里
package com.tokbox.android.tutorials.simple_multiparty;
import android.content.Context;
import android.content.res.Resources;
import android.util.DisplayMetrics;
public class Utility {
public static float convertDpToPixel(float dp, Context context){
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float px = dp * ((float)metrics.densityDpi /
DisplayMetrics.DENSITY_DEFAULT);
return px;
}
}
答案 0 :(得分:1)
Tokbox QA这里的东西。
Opentok不会为您做到这一点,因为那是您的功能。您需要捕获屏幕按下,并自行调整发布者/订阅者的画布大小。我们不会处理您希望如何在屏幕上显示订阅者。