using System; using System.Collections.Generic; using System.Threading; using Android; using Android.App; using Android.Content; using Android.Content.PM; using Android.Graphics; using Android.OS; using Android.Runtime; using Android.Support.V4.App; using Android.Support.V4.Content; using Android.Util; using Android.Views; using Android.Widget; using Com.ETouchSky; using Com.Tool; using GateWay.Droid.FengLinVideo.widget; using HDL_ON.Common; using HDL_ON.DAL.Server; using HDL_ON_Android.FengLinVideo.Form; namespace HDL_ON_Android { [Activity(Label = "VideoActivity", WindowSoftInputMode = SoftInput.AdjustResize, LaunchMode = LaunchMode.SingleInstance, ConfigurationChanges = (ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden | ConfigChanges.LayoutDirection | ConfigChanges.Locale | ConfigChanges.Orientation | ConfigChanges.ScreenSize), Theme = "@style/MyTheme1", ScreenOrientation = ScreenOrientation.Portrait)] public class VideoActivity : Activity, View.IOnClickListener, ISurfaceHolderCallback, VideoPhoneJni.ICallBack, TipDiaglog.OnConfirmClickListener { private static Activity activity; private VideoPhone mPhone; private ISurfaceHolder mRemoteSurfaceHolder; private FrameLayout mRemoteFrameContainer; private SurfaceView mSurfaceRemote; private ImageView ivBack; private TextView tvName; private MonitorFragment monitorFragment = null; private ReverseCallFragment reverseCallFragment = null; public static string ESVideoUUID = "JJY000019VPLLF";//室外机UUID,例:JJY000007FSEYX f5f6fa public static string DeviceName;//室外机的名称,例,室外机 public static bool IsCollect;//是否收藏 public static int Tpye = 0;//类型,0 监控,1反呼 public static string UUId; public static string CallId;//callId 呼叫记录id public static string CmtID;//cmtID 丰林社区号 public static string Roomno;//roomno 丰林房间号 public static string Unitno;//unitno 丰林楼栋号 string public static string HomeID;//HomeID 丰林住宅id protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); try { activity = this; ESVideoUUID = Intent.GetStringExtra("ESVideoUUID");//室外机UUID,例:JJY000007FSEYX DeviceName = Intent.GetStringExtra("DeviceName");//室外机的名称,例,室外机 UUId = Intent.GetStringExtra("uuid");// CallId = Intent.GetStringExtra("callId"); CmtID = Intent.GetStringExtra("cmtID"); Roomno = Intent.GetStringExtra("roomno"); Unitno = Intent.GetStringExtra("unitno"); HomeID = Intent.GetStringExtra("HomeID"); IsCollect = Intent.GetBooleanExtra("IsCollect", false);//是否收藏 Tpye = Intent.GetIntExtra("Type", 0);//类型,0 监控,1反呼 SetContentView(Resource.Layout.activity_video_phone); IniView(); IniData(); if (Tpye == 0) { Monitor(ESVideoUUID); //监控 monitorFragment = new MonitorFragment(mPhone); FragmentManager.BeginTransaction().Replace(Resource.Id.content, monitorFragment).Commit(); } else { string param = "address=" + ESVideoUUID + ",tag=mobile://123,"; reverseCallFragment = new ReverseCallFragment(mPhone, param); FragmentManager.BeginTransaction().Replace(Resource.Id.content, reverseCallFragment).Commit(); } } catch {} } /// /// 必要的一些权限 /// private void Permissions() { String[] mPermissionList = new String[] { Manifest.Permission.WriteExternalStorage, Manifest.Permission.ReadExternalStorage, Manifest.Permission.Camera, Manifest.Permission.RecordAudio }; foreach (String permissions in mPermissionList) { if (ContextCompat.CheckSelfPermission(this, permissions) != 0) { ActivityCompat.RequestPermissions(this, new string[] { permissions }, 1); } } } /// /// 隐藏底部导航栏——虚拟按键 /// private void HideVirtualButtons() { WindowManagerLayoutParams windowManager = Window.Attributes; var uiOptions = (int)Window.DecorView.SystemUiVisibility; var newUiOptions = (int)uiOptions; newUiOptions = (int)SystemUiFlags.HideNavigation | (int)SystemUiFlags.Immersive | (int)SystemUiFlags.ImmersiveSticky; windowManager.SystemUiVisibility = (StatusBarVisibility)newUiOptions; Window.Attributes = windowManager; } /// /// 监控 /// /// private void Monitor(string address) { //监视功能 从平台拉取监视列表,调用此接口可以一台一台监视 if (mPhone != null) { //此参数 可以向门口机设备传递数据, //注意:RequestAudio 请求对方音频,RequestVideo请求对方视频 SendAudio发送本地音频 SendVideo 发送本地视频 一般门口不接收到视频,所以最好设置0,减少流量消耗 string UserData = ""; string param = "SendAudio=0\r\n" + "SendVideo=0\r\n" + "RequestAudio=0\r\n" + "RequestVideo=0\r\n" + "UserData=" + UserData + "\r\n"; mPhone.Monitor(address, param); } } private void IniView() { mRemoteFrameContainer = (FrameLayout)FindViewById(Resource.Id.remoteFrame); ivBack = (ImageView)FindViewById(Resource.Id.videoBackImg); tvName = (TextView)FindViewById(Resource.Id.nameText); tvName.SetText(DeviceName, null); ivBack.SetOnClickListener(this); } private void IniData() { try { if (mPhone == null) { string _params = "port=8554\r\n" + "packcode=1021df37c2abe546a4541ca2c4a9c910\r\n"; //初始化对讲端口,默认就好,跟门口机设置要匹配,注意新接口需要增加packcode参数,需要把你们的包名发过来 mPhone = new VideoPhone(this, this, _params); if (mRemoteSurfaceHolder != null) { mPhone.SetRemoteSurfaceHolder(mRemoteSurfaceHolder, "mRemoteSurfaceHolder!=null"); //设置来电窗口 } ViewGroup v = (ViewGroup)FindViewById(Resource.Id.locaVideo); mPhone.SetLocalVideoContainer(v);//设置本地视频窗口,一定要调用,不然后会出现没声音 } else { mPhone.StopStream(); mPhone.Release(); mPhone = null; } } catch { } } protected override void OnResume() { base.OnResume(); HideVirtualButtons(); Permissions(); if (mPhone != null) { mPhone.OnActivityResume(); } } protected override void OnPause() { base.OnPause(); if (mPhone != null) { //mPhone.OnActivityPause(); } } protected override void OnDestroy() { base.OnDestroy(); if (mPhone != null) { mPhone.HangUp(); mPhone.Release(); mPhone = null; //mPhone.OnActivityDestroy(); } if (ReverseCallFragment.unlockThread != null) { try { // ReverseCallFragment.unlockThread.Interrupt(); } catch { } ReverseCallFragment.unlockThread = null; } if (MonitorFragment.thread != null) { try { // MonitorFragment.thread.Interrupt(); } catch { } MonitorFragment.thread = null; } } public override void OnBackPressed() { if (mPhone != null) mPhone.HangUp(); Finish(); } public void OnClick(View v) { if (v.Equals(ivBack)) { if (mPhone != null) mPhone.HangUp(); Finish(); } } /// /// show出视频画面 /// 不能用View.INVISIBLE来完全隐藏,否则MediaCodec.configure会报ava.lang.IllegalArgumentException: The surface has been released /// private void ShowRemoteVideo() { try { if (mSurfaceRemote != null) { return; } mSurfaceRemote = new SurfaceView(this, null); ISurfaceHolder holder = mSurfaceRemote.Holder; holder.AddCallback(this);//ISurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS holder.SetType(SurfaceType.PushBuffers); //发现第一次show时会闪屏一下,后面hide再show时不会闪屏 FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent); //v.setId(View.generateViewId()); mSurfaceRemote.LayoutParameters = lp; mRemoteFrameContainer.AddView(mSurfaceRemote); } catch { } } /// /// 关闭画面 /// private void HideRemoteVideo() { try { if (mSurfaceRemote != null) { mRemoteFrameContainer.RemoveView(mSurfaceRemote); mSurfaceRemote = null; } } catch { } } /// /// 弹出已挂断提示 /// private void ShowTipDialog(string title, string text, string btnText, bool isClose) { try { TipDiaglog diaglog = new TipDiaglog(this); diaglog.SetAutoClose(isClose); diaglog.SetTitleText(title);//"提示" diaglog.SetContentText(text);//"已挂断" diaglog.SetConfirmText(btnText);//"确认" diaglog.SetCanceledOnTouchOutside(false); diaglog.Show(); diaglog.Create(); diaglog.SetConfirmClickListener(this); } catch (Exception e) { string ss = e.Message; } } public void SurfaceChanged(ISurfaceHolder holder, [GeneratedEnum] Format format, int width, int height) { mRemoteSurfaceHolder = holder; if (mPhone != null) { mPhone.SetRemoteSurfaceHolder(holder, "surfaceChanged"); } } public void SurfaceCreated(ISurfaceHolder holder) { mRemoteSurfaceHolder = holder; if (mPhone != null) { mPhone.SetRemoteSurfaceHolder(holder, "surfaceCreated"); } } public void SurfaceDestroyed(ISurfaceHolder holder) { mRemoteSurfaceHolder = null; if (mPhone != null) { mPhone.SetRemoteSurfaceHolder(null, "surfaceDestroyed"); } } /// /// 开始拉流 /// 注意:由于android框架限制,要满足如下条件才能开流:activity要在前台,并且surfaceview可用 /// /// private void StartStream(String reason) { if (mPhone != null) { try { //开流之前可配置视频尺寸,码率,帧率 针对的是本地 //mPhone.SetVideoSize(640, 480);//1920x1080,1280x720,640x480 //mPhone.SetBps(1.5 * 1024 * 1024); //mPhone.SetFps(30); mPhone.StartStream(); } catch { } } } /// /// 通话状态回调方法 /// /// public void OnPhoneEvent(string msg) { try { if (monitorFragment != null) { monitorFragment.OnPhoneEvent(msg); } if (reverseCallFragment != null) { reverseCallFragment.OnPhoneEvent(msg); } TextProtocol tp = new TextProtocol(); tp.Parse(msg); string event1 = tp.GetString("event"); Log.Info("FengLinVideo", "OnPhoneEvent event=" + event1); switch (event1) { case "EVT_Ringing": mPhone.RequestCallerSendVideo(); ShowRemoteVideo(); break; case "EVT_Connected": if (!mPhone.IsStreamRunning) { //由于android框架限制,要满足如下条件才能开流: activity要在前台,并且surfaceview可用 StartStream("EVT_Connected"); } ShowRemoteVideo(); break; case "EVT_StartStream": StartStream("EVT_StreamStream"); break; case "EVT_StopStream": mPhone.StopStream(); break; case "EVT_MonitorConnected": if (!mPhone.IsStreamRunning) { StartStream("EVT_MonitorConnected"); } ShowRemoteVideo(); break; case "EVT_HangUp": HideRemoteVideo(); if (mPhone != null) { mPhone.StopStream(); } //Toast.MakeText(this, GetString(Resource.String.end_call), ToastLength.Short).Show(); this.Finish(); //ShowTipDialog(tip, hang_up, confirm, true); break; case "EVT_RECV_CUSTOM_DATA": string data = tp.GetString("data"); Toast.MakeText(this, GetString(Resource.String.video_success), ToastLength.Short).Show(); break; case "EVT_SnapAck": int error = tp.GetInt("error"); string filePath = tp.GetString("filePath"); if (error == 0) { Toast.MakeText(this, GetString(Resource.String.video_success), ToastLength.Short).Show(); } else { Toast.MakeText(this, GetString(Resource.String.video_fail), ToastLength.Short).Show(); } break; } } catch { } } public void OnRecvAudioFrame(byte[] p0) { //throw new NotImplementedException(); } public void OnRecvVideoFrame(byte[] p0) { //throw new NotImplementedException(); } public void onSureClick(TipDiaglog dialoog, View v, bool bol) { dialoog.Dismiss(); if (bol) this.Finish(); } } }