|
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 {}
|
}
|
|
/// <summary>
|
/// 必要的一些权限
|
/// </summary>
|
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);
|
}
|
}
|
}
|
|
/// <summary>
|
/// 隐藏底部导航栏——虚拟按键
|
/// </summary>
|
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;
|
}
|
|
/// <summary>
|
/// 监控
|
/// </summary>
|
/// <param name="address"></param>
|
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();
|
}
|
}
|
|
/// <summary>
|
/// show出视频画面
|
/// 不能用View.INVISIBLE来完全隐藏,否则MediaCodec.configure会报ava.lang.IllegalArgumentException: The surface has been released
|
/// </summary>
|
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 { }
|
}
|
|
/// <summary>
|
/// 关闭画面
|
/// </summary>
|
private void HideRemoteVideo()
|
{
|
try
|
{
|
if (mSurfaceRemote != null)
|
{
|
mRemoteFrameContainer.RemoveView(mSurfaceRemote);
|
mSurfaceRemote = null;
|
}
|
}
|
catch { }
|
}
|
|
/// <summary>
|
/// 弹出已挂断提示
|
/// </summary>
|
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");
|
}
|
}
|
|
/// <summary>
|
/// 开始拉流
|
/// 注意:由于android框架限制,要满足如下条件才能开流:activity要在前台,并且surfaceview可用
|
/// </summary>
|
/// <param name="reason"></param>
|
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 { }
|
}
|
}
|
|
/// <summary>
|
/// 通话状态回调方法
|
/// </summary>
|
/// <param name="msg"></param>
|
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();
|
}
|
}
|
}
|