pangweixin 4 tahun lalu
induk
melakukan
724eba0255

+ 2 - 0
VideoCall/build.gradle

@@ -24,4 +24,6 @@ dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
     implementation 'androidx.appcompat:appcompat:1.1.0'
     implementation 'com.tencent.liteav:LiteAVSDK_TRTC:latest.release'
+    // eventbus
+    api 'org.greenrobot:eventbus:3.2.0'
 }

+ 0 - 3
VideoCall/src/main/AndroidManifest.xml

@@ -5,9 +5,6 @@
         <activity
             android:name="com.tencent.trtc.videocall.VideoCallingActivity"
             android:screenOrientation="landscape" />
-        <activity
-            android:name="com.tencent.trtc.videocall.VideoCallingEnterActivity"
-            android:screenOrientation="landscape" />
     </application>
 
 </manifest>

+ 5 - 1
VideoCall/src/main/java/com/tencent/trtc/videocall/Constant.java

@@ -4,8 +4,12 @@ public class Constant {
 
     public static final String ROOM_ID = "room_id";
     public static final String USER_ID = "user_id";
+    public static final String STREAM_ID = "streamId";
+    public static final String USER_SIG = "userSig";
+    public static final String SDK_APP_ID = "sdkAppId";
+    public static final String PRIVATE_MAP_KEY = "privateMapKey";
     public static final String ROLE_TYPE = "role_type";
-    public static final String CUSTOM_VIDEO = "custom_video";
+    public static final String IS_VIDEO = "is_video";
 
     // 美颜风格.三种美颜风格:0 :光滑  1:自然  2:朦胧
     public static final int     BEAUTY_STYLE_SMOOTH              = 0;

+ 0 - 193
VideoCall/src/main/java/com/tencent/trtc/videocall/FloatingView.java

@@ -1,193 +0,0 @@
-package com.tencent.trtc.videocall;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.graphics.PixelFormat;
-import android.graphics.drawable.BitmapDrawable;
-import android.os.Build;
-import android.util.AttributeSet;
-import android.view.GestureDetector;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.FrameLayout;
-import android.widget.PopupWindow;
-
-/**
- * 悬浮球,点击可以弹出菜单
- */
-@TargetApi(Build.VERSION_CODES.LOLLIPOP)
-public class FloatingView extends FrameLayout implements GestureDetector.OnGestureListener {
-
-    private Context                     mContext;
-    private WindowManager               mWindowManager;
-    private GestureDetector             mGestureDetector;
-    private WindowManager.LayoutParams  mLayoutParams;
-    private float                       mLastX;
-    private float                       mLastY;
-    private PopupWindow                 mPopupWindow;
-    private long                        mTapOutsideTime;
-    private boolean                     mIsShowing = false;
-
-    public FloatingView(Context context) {
-        super(context);
-        this.mContext = context;
-        this.mGestureDetector = new GestureDetector(context, this);
-    }
-
-    public FloatingView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        this.mContext = context;
-        this.mGestureDetector = new GestureDetector(context, this);
-    }
-
-    public FloatingView(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        this.mContext = context;
-        this.mGestureDetector = new GestureDetector(context, this);
-    }
-
-    public FloatingView(Context context, int viewResId) {
-        super(context);
-        this.mContext = context;
-        View.inflate(context, viewResId, this);
-        this.mGestureDetector = new GestureDetector(context, this);
-    }
-
-    public void showView(View view) {
-        showView(view, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT);
-    }
-
-    public void showView(View view, int width, int height) {
-        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
-        int type = WindowManager.LayoutParams.TYPE_TOAST;
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-            type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-        } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
-            type = WindowManager.LayoutParams.TYPE_PHONE;
-        }
-        mLayoutParams = new WindowManager.LayoutParams(type);
-        mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-        mLayoutParams.flags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
-        mLayoutParams.width = width;
-        mLayoutParams.height = height;
-        mLayoutParams.format = PixelFormat.TRANSLUCENT;
-        mWindowManager.addView(view, mLayoutParams);
-    }
-
-    public void hideView() {
-        if (null != mWindowManager) {
-            mWindowManager.removeViewImmediate(this);
-        }
-        mWindowManager = null;
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        return mGestureDetector.onTouchEvent(event);
-    }
-
-    @Override
-    public boolean onDown(MotionEvent e) {
-        mLastX = e.getRawX();
-        mLastY = e.getRawY();
-        return false;
-    }
-
-    @Override
-    public void onShowPress(MotionEvent e) {
-    }
-
-    @Override
-    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
-        float nowX, nowY, tranX, tranY;
-        nowX = e2.getRawX();
-        nowY = e2.getRawY();
-        tranX = nowX - mLastX;
-        tranY = nowY - mLastY;
-        mLayoutParams.x += tranX;
-        mLayoutParams.y += tranY;
-        mWindowManager.updateViewLayout(this, mLayoutParams);
-        mLastX = nowX;
-        mLastY = nowY;
-        return false;
-    }
-
-    @Override
-    public void onLongPress(MotionEvent e) {
-    }
-
-    @Override
-    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
-        return false;
-    }
-
-    public void setPopupWindow(int id) {
-        mPopupWindow = new PopupWindow(this);
-        mPopupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
-        mPopupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
-        mPopupWindow.setTouchable(true);
-        mPopupWindow.setOutsideTouchable(true);
-        mPopupWindow.setFocusable(false);
-        mPopupWindow.setBackgroundDrawable(new BitmapDrawable());
-        mPopupWindow.setContentView(LayoutInflater.from(getContext()).inflate(id, null));
-        mPopupWindow.setTouchInterceptor(new OnTouchListener() {
-            @Override
-            public boolean onTouch(View v, MotionEvent event) {
-                if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
-                    mPopupWindow.dismiss();
-                    mTapOutsideTime = System.currentTimeMillis();
-                    return true;
-                }
-                return false;
-            }
-        });
-    }
-
-    public View getPopupView() {
-        return mPopupWindow.getContentView();
-    }
-
-    public void setOnPopupItemClickListener(OnClickListener listener) {
-        if (mPopupWindow == null)
-            return;
-
-        ViewGroup layout = (ViewGroup) mPopupWindow.getContentView();
-        for (int i = 0; i < layout.getChildCount(); i++) {
-            layout.getChildAt(i).setOnClickListener(listener);
-        }
-    }
-
-    public void show() {
-        if (!mIsShowing) {
-            showView(this);
-        }
-        mIsShowing = true;
-    }
-
-    public void dismiss() {
-        if (mIsShowing) {
-            hideView();
-        }
-        mIsShowing = false;
-        ViewGroup layout = (ViewGroup) mPopupWindow.getContentView();
-        for (int i = 0; i < layout.getChildCount(); i++) {
-            layout.getChildAt(i).setOnClickListener(null);
-        }
-    }
-
-    @Override
-    public boolean onSingleTapUp(MotionEvent e) {
-        if (null != mPopupWindow)
-            mPopupWindow.dismiss();
-        if (!(System.currentTimeMillis() - mTapOutsideTime < 80)) {
-            mPopupWindow.showAtLocation(this, Gravity.NO_GRAVITY, 100, 0);
-        }
-        return false;
-    }
-
-
-}

+ 0 - 280
VideoCall/src/main/java/com/tencent/trtc/videocall/GenerateTestUserSig.java

@@ -1,280 +0,0 @@
-package com.tencent.trtc.videocall;
-
-
-import android.util.Base64;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.Charset;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-import java.util.zip.Deflater;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-
-/**
- * Module:   GenerateTestUserSig
- *
- * Function: 用于生成测试用的 UserSig,UserSig 是腾讯云为其云服务设计的一种安全保护签名。
- *           其计算方法是对 SDKAppID、UserID 和 EXPIRETIME 进行加密,加密算法为 HMAC-SHA256。
- *
- * Attention: 请不要将如下代码发布到您的线上正式版本的 App 中,原因如下:
- *
- *            本文件中的代码虽然能够正确计算出 UserSig,但仅适合快速调通 SDK 的基本功能,不适合线上产品,
- *            这是因为客户端代码中的 SECRETKEY 很容易被反编译逆向破解,尤其是 Web 端的代码被破解的难度几乎为零。
- *            一旦您的密钥泄露,攻击者就可以计算出正确的 UserSig 来盗用您的腾讯云流量。
- *
- *            正确的做法是将 UserSig 的计算代码和加密密钥放在您的业务服务器上,然后由 App 按需向您的服务器获取实时算出的 UserSig。
- *            由于破解服务器的成本要高于破解客户端 App,所以服务器计算的方案能够更好地保护您的加密密钥。
- *
- * Reference:https://cloud.tencent.com/document/product/647/17275#Server
- */
-
-/**
- * Module:   GenerateTestUserSig
- *
- * Description: generates UserSig for testing. UserSig is a security signature designed by Tencent Cloud for its cloud services.
- *           It is calculated based on `SDKAppID`, `UserID`, and `EXPIRETIME` using the HMAC-SHA256 encryption algorithm.
- *
- * Attention: do not use the code below in your commercial app. This is because:
- *
- *            The code may be able to calculate UserSig correctly, but it is only for quick testing of the SDK’s basic features, not for commercial apps.
- *            `SECRETKEY` in client code can be easily decompiled and reversed, especially on web.
- *             Once your key is disclosed, attackers will be able to steal your Tencent Cloud traffic.
- *
- *            The correct method is to deploy the `UserSig` calculation code and encryption key on your project server so that your app can request from your server a `UserSig` that is calculated whenever one is needed.
- *           Given that it is more difficult to hack a server than a client app, server-end calculation can better protect your key.
- *
- * Reference: https://cloud.tencent.com/document/product/647/17275#Server
- */
-public class GenerateTestUserSig {
-
-    /**
-     * 配置为CDN发布、混流的域名
-     *
-     */
-
-    /**
-     * Domain name for CDN publishing and stream mixing
-     */
-    public static final String  CDN_DOMAIN_NAME = "live.pwxmax.cn";
-
-    /**
-     * CDN发布功能 混流bizId
-     */
-
-    /**
-     * `bizId` for CDN publishing and stream mixing
-     */
-    public static final int BIZID = 135161;
-
-    /**
-     * CDN发布功能 混流appId
-     */
-
-    /**
-     * `appId` for CDN publishing and stream mixing
-     */
-    public static final int APPID = 1253658654;
-
-    /**
-     * 腾讯云 SDKAppId,需要替换为您自己账号下的 SDKAppId。
-     *
-     * 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ) 创建应用,即可看到 SDKAppId,
-     * 它是腾讯云用于区分客户的唯一标识。
-     */
-
-    /**
-     * Tencent Cloud `SDKAppID`. Set it to the `SDKAppID` of your account.
-     *
-     * You can view your `SDKAppID` after creating an application in the [TRTC console](https://console.cloud.tencent.com/rav).
-     * `SDKAppID` uniquely identifies a Tencent Cloud account.
-     */
-    public static final int SDKAPPID = 1400589545;
-
-    /**
-     * 签名过期时间,建议不要设置的过短
-     * <p>
-     * 时间单位:秒
-     * 默认时间:7 x 24 x 60 x 60 = 604800 = 7 天
-     */
-
-    /**
-     * Signature validity period, which should not be set too short
-     * <p>
-     * Unit: second
-     * Default value: 604800 (7 days)
-     */
-    private static final int EXPIRETIME = 604800;
-
-
-    /**
-     * 计算签名用的加密密钥,获取步骤如下:
-     *
-     * step1. 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ),如果还没有应用就创建一个,
-     * step2. 单击应用信息,并进一步找到“快速上手”部分。
-     * step3. 点击“复制密钥”按钮,复制密钥,请将其拷贝并复制到如下的变量中
-     *
-     * 注意:该方案仅适用于调试Demo,正式上线前请将 UserSig 计算代码和密钥迁移到您的后台服务器上,以避免加密密钥泄露导致的流量盗用。
-     * 文档:https://cloud.tencent.com/document/product/647/17275#Server
-     */
-
-    /**
-     * Follow the steps below to obtain the key required for UserSig calculation.
-     *
-     * Step 1. Log in to the [TRTC console](https://console.cloud.tencent.com/rav), and create an application if you don’t have one.
-     * Step 2. Find your application, click “Application Info”, and click the “Quick Start” tab.
-     * Step 3. Copy and paste the key to the code, as shown below.
-     *
-     * Note: this method is for testing only. Before commercial launch, please migrate the UserSig calculation code and key to your backend server to prevent key disclosure and traffic stealing.
-     * Reference: https://cloud.tencent.com/document/product/647/17275#Server
-     */
-    public static final String SECRETKEY = "310c3bedc8287ecef1740655bc1f2cbd5c78ea7a4588bdde61a085d09affd3f1";
-
-    /**
-     * 计算 UserSig 签名
-     *
-     * 函数内部使用 HMAC-SHA256 非对称加密算法,对 SDKAPPID、userId 和 EXPIRETIME 进行加密。
-     *
-     * @note: 请不要将如下代码发布到您的线上正式版本的 App 中,原因如下:
-     *
-     * 本文件中的代码虽然能够正确计算出 UserSig,但仅适合快速调通 SDK 的基本功能,不适合线上产品,
-     * 这是因为客户端代码中的 SECRETKEY 很容易被反编译逆向破解,尤其是 Web 端的代码被破解的难度几乎为零。
-     * 一旦您的密钥泄露,攻击者就可以计算出正确的 UserSig 来盗用您的腾讯云流量。
-     *
-     * 正确的做法是将 UserSig 的计算代码和加密密钥放在您的业务服务器上,然后由 App 按需向您的服务器获取实时算出的 UserSig。
-     * 由于破解服务器的成本要高于破解客户端 App,所以服务器计算的方案能够更好地保护您的加密密钥。
-     *
-     * 文档:https://cloud.tencent.com/document/product/647/17275#Server
-     */
-
-    /**
-     * Calculating UserSig
-     *
-     * The asymmetric encryption algorithm HMAC-SHA256 is used in the function to calculate UserSig based on `SDKAppID`, `UserID`, and `EXPIRETIME`.
-     *
-     * @note: do not use the code below in your commercial app. This is because:
-     *
-     * The code may be able to calculate UserSig correctly, but it is only for quick testing of the SDK’s basic features, not for commercial apps.
-     * `SECRETKEY` in client code can be easily decompiled and reversed, especially on web.
-     * Once your key is disclosed, attackers will be able to steal your Tencent Cloud traffic.
-     *
-     * The correct method is to deploy the `UserSig` calculation code on your project server so that your app can request from your server a `UserSig` that is calculated whenever one is needed.
-     * Given that it is more difficult to hack a server than a client app, server-end calculation can better protect your key.
-     *
-     * Reference: https://cloud.tencent.com/document/product/647/17275#Server
-     */
-    public static String genTestUserSig(String userId) {
-        return GenTLSSignature(SDKAPPID, userId, EXPIRETIME, null, SECRETKEY);
-    }
-
-    /**
-     * 生成 tls 票据
-     *
-     * @param sdkappid    应用的 appid
-     * @param userId      用户 id
-     * @param expire      有效期,单位是秒
-     * @param userbuf     默认填写null
-     * @param priKeyContent 生成 tls 票据使用的私钥内容
-     * @return 如果出错,会返回为空,或者有异常打印,成功返回有效的票据
-     */
-
-    /**
-     * Generating a TLS Ticket
-     *
-     * @param sdkappid    `appid` of your application
-     * @param userId      User ID
-     * @param expire      Validity period, in seconds
-     * @param userbuf     `null` by default
-     * @param priKeyContent Private key required for generating a TLS ticket
-     * @return If an error occurs, an empty string will be returned or exceptions printed. If the operation succeeds, a valid ticket will be returned.
-     */
-    private static String GenTLSSignature(long sdkappid, String userId, long expire, byte[] userbuf, String priKeyContent) {
-        long currTime = System.currentTimeMillis() / 1000;
-        JSONObject sigDoc = new JSONObject();
-        try {
-            sigDoc.put("TLS.ver", "2.0");
-            sigDoc.put("TLS.identifier", userId);
-            sigDoc.put("TLS.sdkappid", sdkappid);
-            sigDoc.put("TLS.expire", expire);
-            sigDoc.put("TLS.time", currTime);
-        } catch (JSONException e) {
-            e.printStackTrace();
-        }
-
-        String base64UserBuf = null;
-        if (null != userbuf) {
-            base64UserBuf = Base64.encodeToString(userbuf, Base64.NO_WRAP);
-            try {
-                sigDoc.put("TLS.userbuf", base64UserBuf);
-            } catch (JSONException e) {
-                e.printStackTrace();
-            }
-        }
-        String sig = hmacsha256(sdkappid, userId, currTime, expire, priKeyContent, base64UserBuf);
-        if (sig.length() == 0) {
-            return "";
-        }
-        try {
-            sigDoc.put("TLS.sig", sig);
-        } catch (JSONException e) {
-            e.printStackTrace();
-        }
-        Deflater compressor = new Deflater();
-        compressor.setInput(sigDoc.toString().getBytes(Charset.forName("UTF-8")));
-        compressor.finish();
-        byte[] compressedBytes = new byte[2048];
-        int compressedBytesLength = compressor.deflate(compressedBytes);
-        compressor.end();
-        return new String(base64EncodeUrl(Arrays.copyOfRange(compressedBytes, 0, compressedBytesLength)));
-    }
-
-
-    private static String hmacsha256(long sdkappid, String userId, long currTime, long expire, String priKeyContent, String base64Userbuf) {
-        String contentToBeSigned = "TLS.identifier:" + userId + "\n"
-                + "TLS.sdkappid:" + sdkappid + "\n"
-                + "TLS.time:" + currTime + "\n"
-                + "TLS.expire:" + expire + "\n";
-        if (null != base64Userbuf) {
-            contentToBeSigned += "TLS.userbuf:" + base64Userbuf + "\n";
-        }
-        try {
-            byte[] byteKey = priKeyContent.getBytes("UTF-8");
-            Mac hmac = Mac.getInstance("HmacSHA256");
-            SecretKeySpec keySpec = new SecretKeySpec(byteKey, "HmacSHA256");
-            hmac.init(keySpec);
-            byte[] byteSig = hmac.doFinal(contentToBeSigned.getBytes("UTF-8"));
-            return new String(Base64.encode(byteSig, Base64.NO_WRAP));
-        } catch (UnsupportedEncodingException e) {
-            return "";
-        } catch (NoSuchAlgorithmException e) {
-            return "";
-        } catch (InvalidKeyException e) {
-            return "";
-        }
-    }
-
-    private static byte[] base64EncodeUrl(byte[] input) {
-        byte[] base64 = new String(Base64.encode(input, Base64.NO_WRAP)).getBytes();
-        for (int i = 0; i < base64.length; ++i)
-            switch (base64[i]) {
-                case '+':
-                    base64[i] = '*';
-                    break;
-                case '/':
-                    base64[i] = '-';
-                    break;
-                case '=':
-                    base64[i] = '_';
-                    break;
-                default:
-                    break;
-            }
-        return base64;
-    }
-
-}

+ 27 - 0
VideoCall/src/main/java/com/tencent/trtc/videocall/TrtcEvent.java

@@ -0,0 +1,27 @@
+package com.tencent.trtc.videocall;
+
+public class TrtcEvent {
+    int code;
+    String trtcType;
+
+    public TrtcEvent(int code, String trtcType) {
+        this.code = code;
+        this.trtcType = trtcType;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getTrtcType() {
+        return trtcType;
+    }
+
+    public void setTrtcType(String trtcType) {
+        this.trtcType = trtcType;
+    }
+}

+ 27 - 0
VideoCall/src/main/java/com/tencent/trtc/videocall/TrtcEventT.java

@@ -0,0 +1,27 @@
+package com.tencent.trtc.videocall;
+
+public class TrtcEventT {
+    int code;
+    String trtcType;
+
+    public TrtcEventT(int code, String trtcType) {
+        this.code = code;
+        this.trtcType = trtcType;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getTrtcType() {
+        return trtcType;
+    }
+
+    public void setTrtcType(String trtcType) {
+        this.trtcType = trtcType;
+    }
+}

+ 61 - 41
VideoCall/src/main/java/com/tencent/trtc/videocall/VideoCallingActivity.java

@@ -1,18 +1,11 @@
 package com.tencent.trtc.videocall;
 
-import static android.widget.RelativeLayout.ALIGN_PARENT_END;
 
 import android.content.Intent;
-import android.net.Uri;
-import android.os.Build;
 import android.os.Bundle;
-import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.ImageView;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 import android.widget.Toast;
@@ -24,38 +17,17 @@ import com.tencent.trtc.TRTCCloud;
 import com.tencent.trtc.TRTCCloudDef;
 import com.tencent.trtc.TRTCCloudListener;
 
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
+import org.json.JSONException;
+import org.json.JSONObject;
+
 import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * TRTC视频通话的主页面
- * <p>
- * 包含如下简单功能:
- * - 进入视频通话房间{@link VideoCallingActivity#enterRoom()}
- * - 退出视频通话房间{@link VideoCallingActivity#exitRoom()}
- * - 切换前置/后置摄像头{@link VideoCallingActivity#switchCamera()}
- * - 打开/关闭摄像头{@link VideoCallingActivity#muteVideo()}
- * - 打开/关闭麦克风{@link VideoCallingActivity#muteAudio()}
- * - 显示房间内其他用户的视频画面(当前示例最多可显示6个其他用户的视频画面){@link TRTCCloudImplListener#refreshRemoteVideoViews()}
- * <p>
- * - 详见接入文档{https://cloud.tencent.com/document/product/647/42045}
- */
-
-/**
- * Video Call
- * <p>
- * Features:
- * - Enter a video call room: {@link VideoCallingActivity#enterRoom()}
- * - Exit a video call room: {@link VideoCallingActivity#exitRoom()}
- * - Display the video of other users (max. 6) in the room: {@link TRTCCloudImplListener#refreshRemoteVideoViews()}
- * <p>
- * - For more information, please see the integration document {https://cloud.tencent.com/document/product/647/42045}.
- */
+
 public class VideoCallingActivity extends TRTCBaseActivity implements View.OnClickListener {
 
     private static final String TAG = "VideoCallingActivity";
-    private static final int OVERLAY_PERMISSION_REQ_CODE = 1234;
 
     private TXCloudVideoView mTXCVVLocalPreviewView;
     private TXCloudVideoView mTXCVVLocalTwoView;
@@ -63,7 +35,7 @@ public class VideoCallingActivity extends TRTCBaseActivity implements View.OnCli
     private RelativeLayout rl_maike;
     private RelativeLayout rl_guaduan;
     private RelativeLayout rl_qiehuan;
-
+private TextView tv_yuyin;
     private TRTCCloud mTRTCCloud;
     private TXDeviceManager mTXDeviceManager;
     private boolean mIsFrontCamera = true;
@@ -73,11 +45,17 @@ public class VideoCallingActivity extends TRTCBaseActivity implements View.OnCli
     private String mUserId;
     private boolean mAudioRouteFlag = true;
     private boolean mVideoViewFlag = true;
+    private String streamId;
+    private String userSig;
+    private String sdkAppId;
+    private String privateMapKey;
+    private String mIsVideo;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.videocall_activity_calling);
+        EventBus.getDefault().register(this);
         handleIntent();
 
         if (checkPermission()) {
@@ -92,9 +70,24 @@ public class VideoCallingActivity extends TRTCBaseActivity implements View.OnCli
             if (intent.getStringExtra(Constant.USER_ID) != null) {
                 mUserId = intent.getStringExtra(Constant.USER_ID);
             }
+            if (intent.getStringExtra(Constant.STREAM_ID) != null) {
+                streamId = intent.getStringExtra(Constant.STREAM_ID);
+            }
+            if (intent.getStringExtra(Constant.USER_SIG) != null) {
+                userSig = intent.getStringExtra(Constant.USER_SIG);
+            }
+            if (intent.getStringExtra(Constant.SDK_APP_ID) != null) {
+                sdkAppId = intent.getStringExtra(Constant.SDK_APP_ID);
+            }
+            if (intent.getStringExtra(Constant.PRIVATE_MAP_KEY) != null) {
+                privateMapKey = intent.getStringExtra(Constant.PRIVATE_MAP_KEY);
+            }
             if (intent.getStringExtra(Constant.ROOM_ID) != null) {
                 mRoomId = intent.getStringExtra(Constant.ROOM_ID);
             }
+            if (intent.getStringExtra(Constant.IS_VIDEO) != null) {
+                mIsVideo = intent.getStringExtra(Constant.IS_VIDEO);
+            }
         }
     }
 
@@ -105,6 +98,7 @@ public class VideoCallingActivity extends TRTCBaseActivity implements View.OnCli
         rl_maike = findViewById(R.id.rl_maike);
         rl_guaduan = findViewById(R.id.rl_guaduan);
         rl_qiehuan = findViewById(R.id.rl_qiehuan);
+        tv_yuyin = findViewById(R.id.tv_yuyin);
         rl_maike.setOnClickListener(this);
         rl_guaduan.setOnClickListener(this);
         rl_qiehuan.setOnClickListener(this);
@@ -116,14 +110,21 @@ public class VideoCallingActivity extends TRTCBaseActivity implements View.OnCli
         mTXDeviceManager = mTRTCCloud.getDeviceManager();
 
         TRTCCloudDef.TRTCParams trtcParams = new TRTCCloudDef.TRTCParams();
-        trtcParams.sdkAppId = GenerateTestUserSig.SDKAPPID;
+        trtcParams.sdkAppId = Integer.parseInt(sdkAppId);
         trtcParams.userId = mUserId;
-        trtcParams.roomId = Integer.parseInt(mRoomId);
-        trtcParams.userSig = GenerateTestUserSig.genTestUserSig(trtcParams.userId);
+        trtcParams.strRoomId = mRoomId;
+        trtcParams.userSig = userSig;
+        trtcParams.privateMapKey=privateMapKey;
 
-        mTRTCCloud.startLocalPreview(mIsFrontCamera, mTXCVVLocalPreviewView);
+        if (mIsVideo.equals("true")) {
+            mTRTCCloud.startLocalPreview(mIsFrontCamera, mTXCVVLocalPreviewView);
+            tv_yuyin.setVisibility(View.GONE);
+        }else{
+            tv_yuyin.setVisibility(View.VISIBLE);
+        }
         mTRTCCloud.startLocalAudio(TRTCCloudDef.TRTC_AUDIO_QUALITY_SPEECH);
         mTRTCCloud.enterRoom(trtcParams, TRTCCloudDef.TRTC_APP_SCENE_VIDEOCALL);
+
     }
 
     @Override
@@ -131,9 +132,17 @@ public class VideoCallingActivity extends TRTCBaseActivity implements View.OnCli
         super.onStop();
     }
 
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    public void stopTrtcasEvent(TrtcEventT trtcEvent) {
+        if (1 == trtcEvent.getCode() && "FUSHAN_TRTC_STOP".equals(trtcEvent.getTrtcType())) {
+            finish();
+        }
+    }
+
     @Override
     protected void onDestroy() {
         super.onDestroy();
+        EventBus.getDefault().unregister(this);
         exitRoom();
     }
 
@@ -169,6 +178,7 @@ public class VideoCallingActivity extends TRTCBaseActivity implements View.OnCli
         } else if (id == R.id.rl_maike) {
             muteAudio();
         } else if (id == R.id.rl_guaduan) {
+            EventBus.getDefault().post(new TrtcEvent(2, "FUSHAN_TRTC_STOP"));
             finish();
         }
     }
@@ -214,6 +224,14 @@ public class VideoCallingActivity extends TRTCBaseActivity implements View.OnCli
             mContext = new WeakReference<>(activity);
         }
 
+        @Override
+        public void onEnterRoom(long result) {
+            super.onEnterRoom(result);
+            if(result>0){
+//                mTRTCCloud.startPublishing(streamId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);
+            }
+        }
+
         @Override
         public void onUserVideoAvailable(String userId, boolean available) {
             Log.d(TAG, "onUserVideoAvailable userId " + userId + ", mUserCount " + mUserCount + ",available " + available);
@@ -231,7 +249,9 @@ public class VideoCallingActivity extends TRTCBaseActivity implements View.OnCli
         }
 
         private void refreshRemoteVideoViews() {
-            mTRTCCloud.startRemoteView(mRemoteUid, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_SMALL, mTXCVVLocalTwoView);
+            if (mIsVideo.equals("true")) {
+                mTRTCCloud.startRemoteView(mRemoteUid, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_SMALL, mTXCVVLocalTwoView);
+            }
         }
 
         @Override

+ 0 - 81
VideoCall/src/main/java/com/tencent/trtc/videocall/VideoCallingEnterActivity.java

@@ -1,81 +0,0 @@
-package com.tencent.trtc.videocall;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.text.TextUtils;
-import android.view.View;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.EditText;
-import android.widget.Toast;
-
-import androidx.appcompat.app.AppCompatActivity;
-
-
-/**
- * TRTC视频通话的入口页面(可以设置房间id和用户id)
- *
- * - 可跳转TRTC视频通话页面{@link VideoCallingActivity}
- */
-
-/**
- * Video Call Entrance View (set room ID and user ID)
- *
- * - Direct to the video call view: {@link VideoCallingActivity}
- */
-public class VideoCallingEnterActivity extends AppCompatActivity {
-
-    private EditText mEditInputUserId;
-    private EditText mEditInputRoomId;
-
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.videocall_activit_enter);
-        mEditInputUserId = findViewById(R.id.et_input_username);
-        mEditInputRoomId = findViewById(R.id.et_input_room_id);
-        findViewById(R.id.btn_enter_room).setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View view) {
-                startEnterRoom();
-            }
-        });
-        findViewById(R.id.rl_entrance_main).setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                hideInput();
-            }
-        });
-        findViewById(R.id.iv_back).setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                finish();
-            }
-        });
-        mEditInputRoomId.setText("1256732");
-        String time = String.valueOf(System.currentTimeMillis());
-        String userId = time.substring(time.length() - 8);
-        mEditInputUserId.setText(userId);
-    }
-
-    private void startEnterRoom() {
-        if (TextUtils.isEmpty(mEditInputUserId.getText().toString().trim())
-                || TextUtils.isEmpty(mEditInputRoomId.getText().toString().trim())) {
-            Toast.makeText(VideoCallingEnterActivity.this, getString(R.string.videocall_room_input_error_tip), Toast.LENGTH_LONG).show();
-            return;
-        }
-        Intent intent = new Intent(VideoCallingEnterActivity.this, VideoCallingActivity.class);
-        intent.putExtra(Constant.ROOM_ID, mEditInputRoomId.getText().toString().trim());
-        intent.putExtra(Constant.USER_ID, mEditInputUserId.getText().toString().trim());
-        startActivity(intent);
-    }
-
-    protected void hideInput() {
-        InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
-        View v = getWindow().peekDecorView();
-        if (null != v) {
-            imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
-        }
-    }
-
-}

+ 11 - 1
VideoCall/src/main/res/layout/videocall_activity_calling.xml

@@ -4,10 +4,20 @@
     android:layout_height="match_parent"
     android:background="@color/rl_main_bg">
 
+    <TextView
+        android:id="@+id/tv_yuyin"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:gravity="center"
+        android:text="正在进行语音通话"
+        android:textColor="#ffffff"
+        android:visibility="gone"
+        android:textSize="30sp" />
+
     <com.tencent.rtmp.ui.TXCloudVideoView
         android:id="@+id/trtc_view_2"
         android:layout_width="match_parent"
-        android:layout_height="match_parent" >
+        android:layout_height="match_parent">
 
         <com.tencent.rtmp.ui.TXCloudVideoView
             android:id="@+id/txcvv_main"

+ 1 - 2
app/build.gradle

@@ -40,8 +40,7 @@ dependencies {
     implementation 'com.just.agentweb:agentweb:4.1.4'
     implementation 'com.yanzhenjie.apache:httpcore:4.4.14.1'
 
-    // eventbus
-    implementation 'org.greenrobot:eventbus:3.2.0'
+
     // 权限请求框架:https://github.com/getActivity/XXPermissions
     implementation 'com.github.getActivity:XXPermissions:12.0'
     implementation 'io.reactivex.rxjava2:rxjava:2.2.19'

+ 14 - 2
app/src/main/AndroidManifest.xml

@@ -13,7 +13,11 @@
     <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />
-
+    <uses-permission android:name="android.permission.NFC" />
+    <uses-permission android:name="android.permission.NFC_TRANSACTION_EVENT" />
+    <uses-feature
+        android:name="android.hardware.nfc"
+        android:required="true" />
     <uses-feature android:name="android.hardware.camera" />
     <uses-feature android:name="android.hardware.camera.autofocus" />
 
@@ -29,7 +33,15 @@
         android:theme="@style/Theme.HomeCareSAS">
         <activity
             android:name=".weiview.WebViewActivity"
-            android:screenOrientation="landscape" />
+            android:configChanges="keyboardHidden|orientation|screenSize"
+            android:launchMode="singleTask"
+            android:screenOrientation="landscape">
+            <intent-filter>
+                <action android:name="android.nfc.action.NDEF_DISCOVERED" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="*/*" />
+            </intent-filter>
+        </activity>
         <activity
             android:name=".activity.MainActivity"
             android:exported="true"

+ 1 - 5
app/src/main/java/com/qingdaofushan/home/activity/MainActivity.java

@@ -37,7 +37,6 @@ import com.qingdaofushan.home.utils.SharedPreferenceUtil;
 import com.qingdaofushan.home.utils.ToastUtil;
 import com.qingdaofushan.home.view.VersionCheckingUtil;
 import com.qingdaofushan.home.weiview.WebViewActivity;
-import com.tencent.trtc.videocall.VideoCallingEnterActivity;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -45,8 +44,6 @@ import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
 
-import io.reactivex.Observable;
-
 public class MainActivity extends AppCompatActivity {
 
     private String mRootUrl;
@@ -54,7 +51,6 @@ public class MainActivity extends AppCompatActivity {
     private EditText editText;
     private TextView start;
 
-
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -277,7 +273,7 @@ public class MainActivity extends AppCompatActivity {
         if (requestCode == XXPermissions.REQUEST_CODE) {
             if (XXPermissions.isGranted(this, Permission.WRITE_EXTERNAL_STORAGE)
                     && XXPermissions.isGranted(this, Permission.READ_EXTERNAL_STORAGE)
-                    && XXPermissions.isGranted(this, Permission.CAMERA)) {
+                    && XXPermissions.isGranted(this, Permission.CAMERA) ) {
 
             } else {
                 ToastUtil.showToast("权限未正常获取");

+ 264 - 0
app/src/main/java/com/qingdaofushan/home/activity/NfcActivity.java

@@ -0,0 +1,264 @@
+package com.qingdaofushan.home.activity;
+
+import android.Manifest;
+import android.app.AlertDialog;
+import android.app.PendingIntent;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.nfc.NdefMessage;
+import android.nfc.NdefRecord;
+import android.nfc.NfcAdapter;
+import android.nfc.Tag;
+import android.nfc.tech.Ndef;
+import android.os.Bundle;
+import android.widget.Toast;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+
+import com.qingdaofushan.home.R;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+
+/**
+ * Created by leo on 2017/6/9.
+ * 封装了NFC的Activity
+ * 注册时请加入以下配置<br>
+ * android:configChanges="orientation|keyboardHidden|screenSize"<br>
+ * android:launchMode="singleTask"<br>
+ * &lt;intent-filter&gt;<br>
+ * &lt;action android:name="android.nfc.action.NDEF_DISCOVERED" /&gt;<br>
+ * &lt;category android:name="android.intent.category.DEFAULT"/&gt;<br>
+ * &lt;data android:mimeType="* /*"/&gt;<br>
+ * &lt;/intent-filter&gt;
+ */
+
+public abstract class NfcActivity extends AppCompatActivity {
+    private NfcAdapter mNfcAdapter;
+    private PendingIntent mPendingIntent;
+    private Tag tag;
+
+    private static final int REQUEST_CODE_NFC_PERMISSION = 0x12345678;
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        checkPermission();
+        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
+        //初始化PendingIntent
+        mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()), 0);
+    }
+    private void checkPermission() {
+        if (ContextCompat.checkSelfPermission(this, Manifest.permission.NFC) != PackageManager.PERMISSION_GRANTED) {
+            if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.NFC)) {
+                ActivityCompat.requestPermissions(NfcActivity.this, new String[]{Manifest.permission.NFC}, REQUEST_CODE_NFC_PERMISSION);
+            } else {
+                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.NFC}, REQUEST_CODE_NFC_PERMISSION);
+            }
+
+        }
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        processTag(intent);
+    }
+
+    private void processTag(Intent intent) {
+        checkPermission();
+        tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
+//        nfcId.setText("tagId:" + bytesToHexString(tag.getId()));
+//        readNfcContent();
+        onNfcTouch();
+    }
+
+    /**
+     * 当接受到可处理的NCF时回调该方法
+     */
+    protected abstract void onNfcTouch();
+
+    /**
+     * 读取nfc内容
+     */
+    protected final String readNfcContent() throws Exception {
+        checkPermission();
+        String resultMsg = "";
+        Ndef ndef = Ndef.get(tag);
+        if (ndef != null) {
+            try {
+
+                ndef.connect();
+
+                NdefMessage ndefMessage = ndef.getNdefMessage();
+                byte[] msg = ndefMessage.toByteArray();
+                byte[] realMsg = new byte[msg.length - 3];
+                for (int i = 3; i < msg.length; i++) {
+                    realMsg[i - 3] = msg[i];
+                }
+                if (realMsg.length != 0) {
+                    resultMsg = new String(realMsg, Charset.forName("UTF-8"));
+                } else {
+                    resultMsg = "";
+                }
+
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new RuntimeException("read nfc content failed");
+            } finally {
+                try {
+                    ndef.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return resultMsg;
+    }
+
+    /**
+     * 向NFC中写入内容
+     *
+     * @param msg 需要写入的信息
+     * @return 是否写入成功
+     * @throws Exception 写入异常
+     */
+    protected final boolean writeNfc(String msg) throws Exception {
+        checkPermission();
+        boolean flag = false;
+        try {
+            if (tag != null) {
+                //新建NdefRecord数组,本例中数组只有一个元素
+                NdefRecord[] records = {createRecord(msg)};
+                //新建一个NdefMessage实例
+                NdefMessage message = new NdefMessage(records);
+                // 解析TAG获取到NDEF实例
+                Ndef ndef = Ndef.get(tag);
+                // 打开连接
+                ndef.connect();
+                // 写入NDEF信息
+                ndef.writeNdefMessage(message);
+                // 关闭连接
+                ndef.close();
+                flag = true;
+            } else {
+                flag = false;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("write NFC ERROR");
+        }
+        return flag;
+    }
+
+    /**
+     * 清空NFC卡片中的内容
+     *
+     * @return 是否清空成功
+     * @throws Exception 清空时出现的异常
+     */
+    protected final boolean deleteNfc() throws Exception {
+        checkPermission();
+        boolean flag = false;
+        try {
+            if (tag != null) {
+                //新建NdefRecord数组,本例中数组只有一个元素
+                NdefRecord[] records = {new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null)};
+                //新建一个NdefMessage实例
+                NdefMessage message = new NdefMessage(records);
+                // 解析TAG获取到NDEF实例
+                Ndef ndef = Ndef.get(tag);
+                // 打开连接
+                ndef.connect();
+                // 写入NDEF信息
+                ndef.writeNdefMessage(message);
+                // 关闭连接
+                ndef.close();
+                flag = true;
+            } else {
+                flag = false;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
+        return flag;
+    }
+
+    /**
+     * 用于创建NFC信息
+     *
+     * @param msg 需要包装的信息
+     * @return 包装后的NdefRecord
+     * @throws UnsupportedEncodingException
+     */
+    private NdefRecord createRecord(String msg) throws UnsupportedEncodingException {
+        //组装字符串,准备好你要写入的信息
+        //将字符串转换成字节数组
+        byte[] textBytes = msg.getBytes("UTF8");
+        //将字节数组封装到一个NdefRecord实例中去
+        NdefRecord textRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
+                null, null, textBytes);
+        return textRecord;
+    }
+
+    //使当前窗口置顶,权限高于三重过滤
+    @Override
+    protected void onResume() {
+        super.onResume();
+        if (mNfcAdapter != null) {
+            //设置当前activity为栈顶
+            mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, null, null);
+        }
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        //恢复栈
+        if (mNfcAdapter != null) {
+            mNfcAdapter.disableForegroundDispatch(this);
+        }
+    }
+
+    // 字符序列转换为16进制字符串
+    private String bytesToHexString(byte[] src) {
+        return bytesToHexString(src, true);
+    }
+
+    private String bytesToHexString(byte[] src, boolean isPrefix) {
+        StringBuilder stringBuilder = new StringBuilder();
+        if (isPrefix == true) {
+            stringBuilder.append("0x");
+        }
+        if (src == null || src.length <= 0) {
+            return null;
+        }
+        char[] buffer = new char[2];
+        for (int i = 0; i < src.length; i++) {
+            buffer[0] = Character.toUpperCase(Character.forDigit(
+                    (src[i] >>> 4) & 0x0F, 16));
+            buffer[1] = Character.toUpperCase(Character.forDigit(src[i] & 0x0F,
+                    16));
+//            System.out.println(buffer);
+            stringBuilder.append(buffer);
+        }
+        return stringBuilder.toString();
+    }
+
+    /**
+     * 获取NFC标签ID
+     *
+     * @return 标签的ID,可能返回空
+     */
+    protected final String getTagId() {
+        if (null == tag) {
+            return "";
+        }
+        return bytesToHexString(tag.getId());
+    }
+
+}

+ 17 - 13
app/src/main/java/com/qingdaofushan/home/activity/SimplePlayer.java

@@ -1,5 +1,6 @@
 package com.qingdaofushan.home.activity;
 
+import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
 import android.widget.ImageView;
@@ -11,9 +12,6 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager;
 import com.shuyu.gsyvideoplayer.utils.OrientationUtils;
 import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer;
 
-/**
- * 横屏不旋转的 Demo
- */
 public class SimplePlayer extends AppCompatActivity {
 
     StandardGSYVideoPlayer videoPlayer;
@@ -24,14 +22,20 @@ public class SimplePlayer extends AppCompatActivity {
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_simple_play);
-        init();
+        Intent intent=getIntent();
+        if(intent!=null){
+            String url = intent.getStringExtra("url");
+            String title = intent.getStringExtra("title");
+            init(url,title);
+        }
     }
 
-    private void init() {
+    private void init(String url,String title) {
         videoPlayer =  (StandardGSYVideoPlayer)findViewById(R.id.video_player);
 
-        String source1 = "http://9890.vod.myqcloud.com/9890_4e292f9a3dd011e6b4078980237cc3d3.f20.mp4";
-        videoPlayer.setUp(source1, true, "测试视频");
+//        String source1 = "http://9890.vod.myqcloud.com/9890_4e292f9a3dd011e6b4078980237cc3d3.f20.mp4";
+//        videoPlayer.setUp(source1, true, "测试视频");
+        videoPlayer.setUp(url, true, title);
 
         //增加封面
 //        ImageView imageView = new ImageView(this);
@@ -46,12 +50,12 @@ public class SimplePlayer extends AppCompatActivity {
         //设置旋转
         orientationUtils = new OrientationUtils(this, videoPlayer);
         //设置全屏按键功能,这是使用的是选择屏幕,而不是全屏
-        videoPlayer.getFullscreenButton().setOnClickListener(v -> {
-            // ------- !!!如果不需要旋转屏幕,可以不调用!!!-------
-            // 不需要屏幕旋转,还需要设置 setNeedOrientationUtils(false)
-            //orientationUtils.resolveByClick();
-            finish();
-        });
+//        videoPlayer.getFullscreenButton().setOnClickListener(v -> {
+//             ------- !!!如果不需要旋转屏幕,可以不调用!!!-------
+//             不需要屏幕旋转,还需要设置 setNeedOrientationUtils(false)
+//            orientationUtils.resolveByClick();
+//            finish();
+//        });
         //是否可以滑动调整
         videoPlayer.setIsTouchWiget(true);
         //设置返回按键功能

+ 56 - 5
app/src/main/java/com/qingdaofushan/home/weiview/AndroidInterface.java

@@ -11,6 +11,9 @@ import com.qingdaofushan.home.event.EventData;
 import com.qingdaofushan.home.utils.SharedPreferenceUtil;
 import com.qingdaofushan.home.utils.ToastUtil;
 import com.qingdaofushan.home.zxing.activity.CaptureActivity;
+import com.tencent.trtc.videocall.Constant;
+import com.tencent.trtc.videocall.TrtcEventT;
+import com.tencent.trtc.videocall.VideoCallingActivity;
 
 import org.greenrobot.eventbus.EventBus;
 import org.json.JSONException;
@@ -33,8 +36,8 @@ public class AndroidInterface {
             @Override
             public void run() {
                 try {
-                    JSONObject jsonObject=new JSONObject(json);
-                    SharedPreferenceUtil.put(activity,jsonObject.getString("key"),jsonObject.getString("value"));
+                    JSONObject jsonObject = new JSONObject(json);
+                    SharedPreferenceUtil.put(activity, jsonObject.getString("key"), jsonObject.getString("value"));
 //                    mAgentWeb.getJsAccessEntrace().quickCallJs("SetData","200");
                 } catch (JSONException e) {
                     ToastUtil.showToast("存储参数报错");
@@ -49,15 +52,16 @@ public class AndroidInterface {
             @Override
             public void run() {
                 try {
-                    JSONObject jsonObject=new JSONObject(json);
-                   String key= jsonObject.getString("key");
-                    mAgentWeb.getJsAccessEntrace().quickCallJs("GetData", (String)SharedPreferenceUtil.get(activity,key,""));
+                    JSONObject jsonObject = new JSONObject(json);
+                    String key = jsonObject.getString("key");
+                    mAgentWeb.getJsAccessEntrace().quickCallJs("GetData", (String) SharedPreferenceUtil.get(activity, key, ""));
                 } catch (JSONException e) {
                     ToastUtil.showToast("读取参数报错");
                 }
             }
         });
     }
+
     @JavascriptInterface
     public void QRCode(String a) {
         deliver.post(new Runnable() {
@@ -99,4 +103,51 @@ public class AndroidInterface {
             }
         });
     }
+
+    @JavascriptInterface
+    public void TRtc(String json) {
+        deliver.post(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    JSONObject jsonObject = new JSONObject(json);
+                    String userId = jsonObject.getString("userId");
+                    String roomId = jsonObject.getString("roomId");
+                    String streamId = jsonObject.getString("streamId");
+                    String userSig = jsonObject.getString("userSig");
+                    String sdkAppId = jsonObject.getString("sdkAppId");
+                    String privateMapKey = jsonObject.getString("privateMapKey");
+                    String isVideo = jsonObject.getString("isVideo");
+
+                    Intent intent = new Intent(activity, VideoCallingActivity.class);
+                    intent.putExtra(Constant.ROOM_ID, roomId);
+                    intent.putExtra(Constant.USER_ID, userId);
+                    intent.putExtra(Constant.STREAM_ID, streamId);
+                    intent.putExtra(Constant.USER_SIG, userSig);
+                    intent.putExtra(Constant.SDK_APP_ID, sdkAppId);
+                    intent.putExtra(Constant.PRIVATE_MAP_KEY, privateMapKey);
+                    intent.putExtra(Constant.IS_VIDEO, isVideo);
+                    activity.startActivity(intent);
+                } catch (JSONException e) {
+                    ToastUtil.showToast("参数错误");
+                }
+            }
+        });
+    }
+
+    @JavascriptInterface
+    public void TRtcTtype(String json) {
+        deliver.post(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    JSONObject jsonObject = new JSONObject(json);
+                    String type = jsonObject.getString("type");
+                    EventBus.getDefault().post(new TrtcEventT(1, type));
+                } catch (JSONException e) {
+                    ToastUtil.showToast("参数错误");
+                }
+            }
+        });
+    }
 }

+ 71 - 10
app/src/main/java/com/qingdaofushan/home/weiview/WebViewActivity.java

@@ -16,8 +16,8 @@ import android.os.Bundle;
 import android.os.Environment;
 import android.provider.MediaStore;
 import android.util.Base64;
-import android.util.Log;
 import android.view.KeyEvent;
+import android.view.View;
 import android.webkit.ValueCallback;
 import android.webkit.WebSettings;
 import android.webkit.WebView;
@@ -37,16 +37,17 @@ import com.just.agentweb.PermissionInterceptor;
 import com.just.agentweb.WebChromeClient;
 import com.just.agentweb.WebViewClient;
 //import com.king.zxing.CameraScan;
-import com.qingdaofushan.home.activity.CamActivity;
+import com.qingdaofushan.home.activity.NfcActivity;
 import com.qingdaofushan.home.event.EventData;
 import com.qingdaofushan.home.R;
+import com.tencent.trtc.videocall.TrtcEvent;
 import com.qingdaofushan.home.utils.ToastUtil;
-import com.qingdaofushan.home.utils.Uri2PathUtil;
-import com.qingdaofushan.home.zxing.view.Constant;
 
 import org.greenrobot.eventbus.EventBus;
 import org.greenrobot.eventbus.Subscribe;
 import org.greenrobot.eventbus.ThreadMode;
+import org.json.JSONException;
+import org.json.JSONObject;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -63,7 +64,7 @@ import java.util.Locale;
  * @Date 2020.6.11
  * @Discription 对接H5通用的 Activity
  */
-public class WebViewActivity extends AppCompatActivity {
+public class WebViewActivity extends NfcActivity {
 
     LinearLayout linearLayout;
     protected AgentWeb mAgentWeb;
@@ -100,6 +101,45 @@ public class WebViewActivity extends AppCompatActivity {
         initView();
     }
 
+    @Override
+    protected void onNfcTouch() {
+        ToastUtil.showToast("NFC TagId:" + getTagId());
+        readNfc();
+    }
+
+    public void readNfc() {
+        String s = null;
+        try {
+            //read nfc content from tag;
+            s = this.readNfcContent();
+        } catch (Exception e) {
+            ToastUtil.showToast("NFC读取失败");
+        }
+    }
+
+    public void writeNfcContent() {
+        SimpleDateFormat dateFormat = null;
+        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
+            dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
+        }
+        String content = dateFormat.format(System.currentTimeMillis());
+        try {
+            //write something to tag;
+            this.writeNfc(content);
+        } catch (Exception e) {
+            ToastUtil.showToast("NFC读取失败");
+        }
+    }
+
+    public void clearNfc() {
+        try {
+            //clear nfcContent
+            this.deleteNfc();
+        } catch (Exception e) {
+            ToastUtil.showToast("NFC读取失败");
+        }
+    }
+
     private void initView() {
         url = getIntent().getStringExtra("url");
 //        url="http://192.168.1.11:8080";
@@ -213,12 +253,12 @@ public class WebViewActivity extends AppCompatActivity {
 
     @Override
     protected void onPause() {
-        mAgentWeb.getWebLifeCycle().onPause();
+//        mAgentWeb.getWebLifeCycle().onPause();
         super.onPause();
 
     }
 
-//    @Override
+    //    @Override
 //    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
 //        super.onActivityResult(requestCode, resultCode, data);
 //        /**
@@ -324,6 +364,19 @@ public class WebViewActivity extends AppCompatActivity {
         }
     }
 
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    public void stopTrtcEvent(TrtcEvent trtcEvent) {
+        if (trtcEvent.getCode() == 2) {
+            JSONObject j = new JSONObject();
+            try {
+                j.put("type", trtcEvent.getTrtcType());
+                mAgentWeb.getJsAccessEntrace().quickCallJs("TRtc", j.toString());
+            } catch (JSONException e) {
+
+            }
+        }
+    }
+
     /**
      * 检查权限并拍照。
      * 调用相机前先检查权限。
@@ -352,6 +405,7 @@ public class WebViewActivity extends AppCompatActivity {
      */
     @Override
     public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
         if (requestCode == PERMISSION_CAMERA_REQUEST_CODE) {
             if (grantResults.length > 0
                     && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
@@ -443,8 +497,11 @@ public class WebViewActivity extends AppCompatActivity {
      * @throws IOException
      */
     private File createImageFile() throws IOException {
-        String imageName = new SimpleDateFormat("yyyyMMdd_HHmmss",
-                Locale.getDefault()).format(new Date()) + ".jpg";
+        String imageName = null;
+        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
+            imageName = new SimpleDateFormat("yyyyMMdd_HHmmss",
+                    Locale.getDefault()).format(new Date()) + ".jpg";
+        }
 //        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
 //        File storageDir = Environment.getExternalStoragePublicDirectory(
 //                Environment.DIRECTORY_PICTURES);
@@ -494,7 +551,7 @@ public class WebViewActivity extends AppCompatActivity {
 
     @Override
     protected void onResume() {
-        mAgentWeb.getWebLifeCycle().onResume();
+//        mAgentWeb.getWebLifeCycle().onResume();
         super.onResume();
     }
 
@@ -505,4 +562,8 @@ public class WebViewActivity extends AppCompatActivity {
         EventBus.getDefault().unregister(this);
     }
 
+    @Override
+    public void onPointerCaptureChanged(boolean hasCapture) {
+
+    }
 }

+ 1 - 1
app/src/main/res/layout/activity_web.xml

@@ -4,10 +4,10 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
+
     <LinearLayout
         android:id="@+id/ll_webview"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="horizontal"/>
-
 </RelativeLayout>