乐橙平台大华监控Android端实时预览播放
一、初始化
首先我们需要到乐橙开放平台下载android对应的开发包,将sdk中提供的jar和so文件添加到项目中;
二、获取监控列表
监控列表我们是通过从自家后台服务器中获取的,这个自己根据需要调整;
package com.aldx.hccraftsman.activity; import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; import com.afollestad.materialdialogs.MaterialDialog;
import com.aldx.hccraftsman.NewHcgjApplication;
import com.aldx.hccraftsman.R;
import com.aldx.hccraftsman.adapter.DahuaCameraListAdapter;
import com.aldx.hccraftsman.loadinglayout.LoadingLayout;
import com.aldx.hccraftsman.model.DahuaCamera;
import com.aldx.hccraftsman.model.DahuaCameraListModel;
import com.aldx.hccraftsman.model.DahuaDevice;
import com.aldx.hccraftsman.model.DahuaDeviceListModel;
import com.aldx.hccraftsman.okhttp.LoadingDialogCallback;
import com.aldx.hccraftsman.utils.Api;
import com.aldx.hccraftsman.utils.Constants;
import com.aldx.hccraftsman.utils.FastJsonUtils;
import com.aldx.hccraftsman.utils.OtherUtils;
import com.jcodecraeer.xrecyclerview.XRecyclerView;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.model.Response; import java.util.ArrayList;
import java.util.List; import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick; /**
* author: chenzheng
* created on: 2019/8/8 15:31
* description: 大华监控列表
*/
public class DahuaCameraListActivity extends BaseActivity { @BindView(R.id.back_iv)
ImageView backIv;
@BindView(R.id.layout_back)
LinearLayout layoutBack;
@BindView(R.id.title_tv)
TextView titleTv;
@BindView(R.id.right_tv)
TextView rightTv;
@BindView(R.id.layout_right)
LinearLayout layoutRight;
@BindView(R.id.dhcamera_recyclerview)
XRecyclerView dhcameraRecyclerview;
@BindView(R.id.loading_layout)
LoadingLayout loadingLayout; private DahuaCameraListAdapter dahuaCameraListAdapter;
public List<DahuaCamera> list = new ArrayList<>();
private String projectId; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dahua_camera_list);
ButterKnife.bind(this); initView();
requestDeviceList();
} private void initView() {
titleTv.setText("监控列表"); dahuaCameraListAdapter = new DahuaCameraListAdapter(this);
dhcameraRecyclerview.setAdapter(dahuaCameraListAdapter);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
Drawable dividerDrawable = ContextCompat.getDrawable(this, R.drawable.divider_sample); dhcameraRecyclerview.addItemDecoration(dhcameraRecyclerview.new DividerItemDecoration(dividerDrawable));
dhcameraRecyclerview.setLayoutManager(layoutManager);
OtherUtils.setXRecyclerViewAttr(dhcameraRecyclerview);
dhcameraRecyclerview.setLoadingMoreEnabled(false);
dhcameraRecyclerview.setLoadingListener(new XRecyclerView.LoadingListener() {
@Override
public void onRefresh() {
requestDeviceList();
} @Override
public void onLoadMore() {
}
});
dahuaCameraListAdapter.setOnItemClickListener(new DahuaCameraListAdapter.OnRecyclerViewItemClickListener() {
@Override
public void onItemClick(View view, DahuaCamera data) {
if (data != null) {
Intent intent = new Intent(DahuaCameraListActivity.this, DahuaCameraFullPlayActivity.class);
intent.putExtra("DAHUA_CAMERA_INFO", data);
startActivity(intent);
}
}
});
loadingLayout.setEmptyClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dhcameraRecyclerview.refresh();
}
});
loadingLayout.showLoading();
} private void requestDeviceList(){
OkGo.<String>get(Api.GET_DAHUA_DEVICE_LIST)
.tag(this)
.params("projectId", "05771166ea834823b077d2166f7afe65")
.params("pageNum", Constants.FIRSTPAGE)
.params("pageSize", Constants.PAGESIZE)
.execute(new LoadingDialogCallback(this, Constants.NET_REQUEST_TXT) { @Override
public void onSuccess(Response<String> response) {
DahuaDeviceListModel dahuaDeviceListModel = null;
try {
dahuaDeviceListModel = FastJsonUtils.parseObject(response.body(), DahuaDeviceListModel.class);
} catch (Exception e) {
e.printStackTrace();
}
if (dahuaDeviceListModel != null) {
if (dahuaDeviceListModel.code == Api.SUCCESS_CODE) {
if (dahuaDeviceListModel.data != null && dahuaDeviceListModel.data.list != null
&& dahuaDeviceListModel.data.list.size() > 0) {
loadingLayout.showContent();
DahuaDevice dahuaDevice = dahuaDeviceListModel.data.list.get(0);
requestCameraList(dahuaDevice.deviceId);
} else {
tipDialog();
}
} else {
tipDialog();
}
}
} @Override
public void onError(Response<String> response) {
super.onError(response);
NewHcgjApplication.showResultToast(DahuaCameraListActivity.this, response);
} });
} private void requestCameraList(String deviceId){
OkGo.<String>get(Api.GET_DAHUA_CAMERA_LIST)
.tag(this)
.params("deviceId", deviceId)
.execute(new LoadingDialogCallback(this, Constants.NET_REQUEST_TXT) { @Override
public void onSuccess(Response<String> response) {
dhcameraRecyclerview.refreshComplete();
DahuaCameraListModel dahuaCameraListModel = null;
try {
dahuaCameraListModel = FastJsonUtils.parseObject(response.body(), DahuaCameraListModel.class);
} catch (Exception e) {
e.printStackTrace();
}
if (dahuaCameraListModel != null) {
if (dahuaCameraListModel.code == Api.SUCCESS_CODE) {
if (dahuaCameraListModel.data != null && dahuaCameraListModel.data.size() > 0) {
list.addAll(dahuaCameraListModel.data);
dahuaCameraListAdapter.setItems(list);
} else {
tipDialog();
}
} else {
tipDialog();
}
}
} @Override
public void onError(Response<String> response) {
super.onError(response);
dhcameraRecyclerview.refreshComplete();
NewHcgjApplication.showResultToast(DahuaCameraListActivity.this, response);
} });
} private void tipDialog() {
new MaterialDialog.Builder(DahuaCameraListActivity.this)
.title("温馨提示")
.content("您没有可以预览的监控,请联系管理员添加!")
.positiveText("我知道了")
.cancelable(false)
.show();
} @OnClick({R.id.layout_back, R.id.layout_right})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.layout_back:
finish();
break;
case R.id.layout_right:
break;
}
} public static void startActivity(Context context) {
Intent intent = new Intent(context, DahuaCameraListActivity.class);
context.startActivity(intent);
}
}
三、实时预览
添加预览工具类:
package com.aldx.hccraftsman.utils; import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.view.ViewGroup; import com.aldx.hccraftsman.model.LeChangeRecordInfo;
import com.lechange.opensdk.api.LCOpenSDK_Api;
import com.lechange.opensdk.api.bean.QueryLocalRecordNum;
import com.lechange.opensdk.api.bean.QueryLocalRecords;
import com.lechange.opensdk.api.client.BaseRequest;
import com.lechange.opensdk.api.client.BaseResponse;
import com.lechange.opensdk.listener.LCOpenSDK_EventListener;
import com.lechange.opensdk.media.LCOpenSDK_PlayWindow; import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List; import cn.qqtheme.framework.util.LogUtils; /**
* author: chenzheng
* created on: 2019/8/9 9:26
* description:
*/
public class PlayerLeChange { private static final String TAG = "LeChange";
private Handler handler;
public LCOpenSDK_PlayWindow lcOpenSDK_playWindow; //播放窗口 public PlayerLeChange(Context context, ViewGroup viewGroup, Handler handler) {
LCOpenSDK_Api.setHost("openapi.lechange.cn:443"); //设置乐橙服务地址
lcOpenSDK_playWindow = new LCOpenSDK_PlayWindow();
lcOpenSDK_playWindow.initPlayWindow(context, viewGroup, 0); //初始化播放功能,父窗口绑定到LCOpenSDK_playWindow的实例上
this.handler = handler;
} /**
* 实时预览
* @param token
* @param deviceId
* @param channelNo
* @param quality
*/
public void live(String token, String deviceId, String encryptKey, int channelNo, int quality) {
lcOpenSDK_playWindow.playRtspReal(token, deviceId, encryptKey, channelNo, quality);
/**
* 为播放窗口设置监听
*/
lcOpenSDK_playWindow.setWindowListener(new LCOpenSDK_EventListener() {
@Override
public void onPlayerResult(int index, String code, int resultSource) {
super.onPlayerResult(index, code, resultSource);
if (resultSource == 0 && "4".equals(code)) {
messageFeedback(1);
} else {
messageFeedback(2);
}
}
});
} /**
* 远程回放
* @param token
* @param deviceId
* @param encryptKey
* @param channelNo
* @param beginTime
* @param endTime
*/
public void playback(String token, String deviceId, String encryptKey, int channelNo, long beginTime, long endTime) {
lcOpenSDK_playWindow.playRtspPlaybackByUtcTime(token, deviceId, encryptKey, channelNo, beginTime, endTime);
lcOpenSDK_playWindow.setWindowListener(new LCOpenSDK_EventListener() {
@Override
public void onPlayerResult(int index, String code, int resultSource) {
super.onPlayerResult(index, code, resultSource);
if (resultSource == 0 && "4".equals(code)) {
messageFeedback(1);
} else {
messageFeedback(2);
}
}
});
} /**
* 停止实时预览
*/
public void stopLive() {
lcOpenSDK_playWindow.stopRtspReal();
} /**
* 停止远程回放
*/
public void stopPlayback() {
lcOpenSDK_playWindow.stopRtspPlayback();
} /**
* 查询录像段文件数量
* @param token
* @param deviceId
* @param channelNo
* @param beginTime
* @param endTime
*/
public int queryRecordNum(String token, String deviceId, int channelNo, String beginTime, String endTime) {
QueryLocalRecordNum req = new QueryLocalRecordNum();
req.data.token = token;
req.data.deviceId = deviceId;
req.data.channelId = channelNo + "";
req.data.beginTime = beginTime;
req.data.endTime = endTime; RetObject retObject = request(req, 60 * 1000);
QueryLocalRecordNum.Response resp = (QueryLocalRecordNum.Response) retObject.resp;
if (retObject.mErrorCode != 0) { //查询录像失败
return -1;
} else {
if (resp.data == null) { //录像数据为空
return 0;
} else {
return resp.data.recordNum;
}
}
} /**
* 获取录像段文件
* @param token
* @param deviceId
* @param channelNo
* @param beginTime
* @param endTime
* @param queryRange
* @return
*/
public List<LeChangeRecordInfo> getRecordFile(String token, String deviceId, int channelNo, String beginTime, String endTime, String queryRange) {
List<LeChangeRecordInfo> recordInfoList = new ArrayList<LeChangeRecordInfo>(); QueryLocalRecords req = new QueryLocalRecords();
req.data.token = token;
req.data.deviceId = deviceId;
req.data.channelId = channelNo + "";
req.data.beginTime = beginTime;
req.data.endTime = endTime;
req.data.queryRange = queryRange; RetObject retObject = request(req);
QueryLocalRecords.Response resp = (QueryLocalRecords.Response) retObject.resp; if (retObject.mErrorCode == 0 && resp.data != null && resp.data.records != null) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (QueryLocalRecords.ResponseData.RecordsElement element:resp.data.records) {
LeChangeRecordInfo recordInfo = new LeChangeRecordInfo();
try {
recordInfo.setStartTime(sdf.parse(element.beginTime).getTime());
recordInfo.setEndTime(sdf.parse(element.endTime).getTime());
recordInfoList.add(recordInfo);
} catch (ParseException e) {
e.printStackTrace();
}
}
} return recordInfoList;
} public static class RetObject {
public int mErrorCode = 0; //错误码表示符 -1:返回体为null,0:成功,1:http错误,2:业务错误
public String mMsg;
public Object resp;
} /**
* 发送网络请求,并对请求结果的错误码进行处理
* @param req
* @return
*/
private RetObject request(BaseRequest req) {
return request(req, 5 * 1000);
} /**
* 发送网络请求,并对请求结果的错误码进行处理
* @param req
* @param timeout
* @return
*/
private RetObject request(BaseRequest req, int timeout) {
RetObject retObject = new RetObject();
BaseResponse t = null;
try {
t = LCOpenSDK_Api.request(req, timeout); //openAPI请求方法
if (t.getCode() == 200) { //请求成功
if (!t.getApiRetCode().equals("0")) { //业务错误
retObject.mErrorCode = 2;
retObject.mMsg = "业务错误码:" + t.getApiRetCode() + ",错误消息:"
+ t.getApiRetMsg();
LogUtil.e(TAG, "retObject.mMsg:" + retObject.mMsg);
}
} else {
retObject.mErrorCode = 1; //http错误
retObject.mMsg = "HTTP错误码:" + t.getCode() + ",错误消息:" + t.getDesc();
LogUtil.e(TAG, "retObject.mMsg:" + retObject.mMsg);
}
} catch (Exception e) {
e.printStackTrace();
retObject.mErrorCode = -1000;
retObject.mMsg = "内部错误码 : -1000, 错误消息 :" + e.getMessage();
LogUtil.e(TAG, "retObject.mMsg:" + retObject.mMsg);
}
retObject.resp = t;
return retObject;
} private void messageFeedback(int bfCode) {
LogUtil.e("bfCode="+bfCode);
Message message = Message.obtain();
message.obj = bfCode;
handler.sendMessage(message);
}
}
package com.aldx.hccraftsman.model; import java.util.UUID; /**
* author: chenzheng
* created on: 2019/8/9 9:27
* description:
*/
public class LeChangeRecordInfo { public enum RecordType
{
DeviceLocal, // 设备本地录像
PrivateCloud, // 私有云
PublicCloud, // 公有云
} public enum RecordEventType
{
All, // 所有录像
Manual, // 手动录像
Event, // 事件录像
} private String id = UUID.randomUUID().toString();
private RecordType type; // 录像类型
private float fileLength; // 文件长度
private float downLength = -1; // 已下载长度
private long startTime; // 开始时间
private long endTime; // 结束时间
private String deviceId; //设备ID
private String deviceKey;
private String backgroudImgUrl; // 录像文件Url
private String chnlUuid; // 通道的uuid
private RecordEventType eventType; // 事件类型
private long recordID; //录像ID
private String recordPath; //录像ID(设备录像) public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getDeviceKey() {
return deviceKey;
}
public void setDeviceKey(String deviceKey) {
this.deviceKey = deviceKey;
} public RecordType getType() {
return type;
}
public void setType(RecordType type) {
this.type = type;
}
public long getStartTime() {
return startTime;
}
public float getFileLength() {
return fileLength;
}
public void setFileLength(float fileLength) {
this.fileLength = fileLength;
}
public float getDownLength() {
return downLength;
}
public void setDownLength(float downLength) {
this.downLength = downLength;
}
public void setStartTime(long startTime) {
this.startTime = startTime;
}
public long getEndTime() {
return endTime;
}
public void setEndTime(long endTime) {
this.endTime = endTime;
}
public String getBackgroudImgUrl() {
return backgroudImgUrl;
}
public void setBackgroudImgUrl(String backgroudImgUrl) {
this.backgroudImgUrl = backgroudImgUrl;
}
public String getChnlUuid() {
return chnlUuid;
}
public void setChnlUuid(String chnlUuid) {
this.chnlUuid = chnlUuid;
}
public RecordEventType getEventType() {
return eventType;
}
public void setEventType(RecordEventType eventType) {
this.eventType = eventType;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void setRecordID(long id) {
this.recordID = id;
}
public long getRecordID() {
return this.recordID;
} public boolean isDownload() {
return downLength >= 0;
}
public String getRecordPath() {
return recordPath;
}
public void setRecordPath(String recordPath) {
this.recordPath = recordPath;
}
}
编写预览页面:
package com.aldx.hccraftsman.activity; import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; import com.afollestad.materialdialogs.MaterialDialog;
import com.aldx.hccraftsman.NewHcgjApplication;
import com.aldx.hccraftsman.R;
import com.aldx.hccraftsman.model.DahuaCamera;
import com.aldx.hccraftsman.model.EZTokenModel;
import com.aldx.hccraftsman.okhttp.LoadingDialogCallback;
import com.aldx.hccraftsman.utils.Api;
import com.aldx.hccraftsman.utils.Constants;
import com.aldx.hccraftsman.utils.FastJsonUtils;
import com.aldx.hccraftsman.utils.LogUtil;
import com.aldx.hccraftsman.utils.PlayerLeChange;
import com.aldx.hccraftsman.utils.ToastUtil;
import com.aldx.hccraftsman.utils.Utils;
import com.kongqw.rockerlibrary.view.RockerView;
import com.lechange.opensdk.listener.LCOpenSDK_EventListener;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.model.Response;
import com.pnikosis.materialishprogress.ProgressWheel; import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick; /**
* author: chenzheng
* created on: 2019/8/8 11:43
* description: 大华摄像头全屏播放
*/
public class DahuaCameraFullPlayActivity extends BaseActivity { @BindView(R.id.progress_wheel)
ProgressWheel progressWheel;
@BindView(R.id.back_iv)
ImageView backIv;
@BindView(R.id.go_zoombig_btn)
TextView goZoombigBtn;
@BindView(R.id.go_zoomsmall_btn)
TextView goZoomsmallBtn;
@BindView(R.id.rocker_iv)
ImageView rockerIv;
@BindView(R.id.monitor_name_tv)
TextView monitorNameTv;
@BindView(R.id.layout_bottom_menu)
LinearLayout layoutBottomMenu;
@BindView(R.id.tools_control_iv)
ImageView toolsControlIv;
@BindView(R.id.tool_control_layout)
LinearLayout toolControlLayout;
@BindView(R.id.rockerView)
RockerView rockerView;
@BindView(R.id.rocker_close_iv)
ImageView rockerCloseIv;
@BindView(R.id.layout_rocker)
LinearLayout layoutRocker; private ViewGroup liveWindowContent;
private View load_layout;
private DahuaCamera dahuaCamera;
private String dahuaToken;
private PlayerLeChange playerLeChange; private Handler mHander = new Handler() {
public void handleMessage(Message msg) {
int status = (int) msg.obj;
switch (status){
case 1://播放成功
load_layout.setVisibility(View.GONE);
break;
case 2://播放失败
tipDialog("当前摄像头无法播放!");
load_layout.setVisibility(View.GONE);
break;
}
return;
} }; @Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dahua_camera_full_play);
ButterKnife.bind(this);
dahuaCamera = getIntent().getParcelableExtra("DAHUA_CAMERA_INFO");
if (dahuaCamera != null && "offline".equals(dahuaCamera.status)) {
tipDialog("当前摄像头不在线,请检查设备网络!");
return;
}
initView();
requestDahuaToken();
} private void initView() {
load_layout = this.findViewById(R.id.load_layout);
liveWindowContent = this.findViewById(R.id.live_window_content);
} /**
* 描述:开始播放
*/
public void play() {
playerLeChange = new PlayerLeChange(this, liveWindowContent, mHander);
playerLeChange.live(dahuaToken, dahuaCamera.deviceId, dahuaCamera.deviceId, Utils.toInt(dahuaCamera.channelId), 0);
} @Override
protected void onDestroy() {
super.onDestroy();
if(playerLeChange!=null) {
playerLeChange.stopLive();
}
} private void tipDialog(String messageStr) {
new MaterialDialog.Builder(this)
.title("温馨提示")
.content(messageStr)
.positiveText("我知道了")
.cancelable(false)
.show();
} @OnClick({R.id.back_iv, R.id.go_zoombig_btn, R.id.go_zoomsmall_btn, R.id.rocker_iv})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.back_iv:
finish();
break;
case R.id.go_zoombig_btn:
break;
case R.id.go_zoomsmall_btn:
break;
case R.id.rocker_iv:
break;
}
} private void requestDahuaToken() {
OkGo.<String>get(Api.GET_DAHUA_ACCESS_TOKEN)
.tag(this)
.execute(new LoadingDialogCallback(this, Constants.NET_REQUEST_TXT) { @Override
public void onSuccess(Response<String> response) {
EZTokenModel ezTokenModel = null;
try {
ezTokenModel = FastJsonUtils.parseObject(response.body(), EZTokenModel.class);
} catch (Exception e) {
e.printStackTrace();
}
if (ezTokenModel != null) {
if (ezTokenModel.code == Api.SUCCESS_CODE) {
if (!TextUtils.isEmpty(ezTokenModel.data)) {
dahuaToken = ezTokenModel.data;
play();
}
} else {
if (!TextUtils.isEmpty(ezTokenModel.msg)) {
ToastUtil.show(DahuaCameraFullPlayActivity.this, ezTokenModel.msg);
}
}
}
} @Override
public void onError(Response<String> response) {
super.onError(response);
NewHcgjApplication.showResultToast(DahuaCameraFullPlayActivity.this, response);
} });
} class MyBaseWindowListener extends LCOpenSDK_EventListener { }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"> <FrameLayout
android:id="@+id/live_window_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black" /> <include
android:id="@+id/load_layout"
layout="@layout/view_loading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center" /> <ImageView
android:id="@+id/back_iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="30dp"
android:src="@drawable/back_btn_round_background" /> <LinearLayout
android:id="@+id/layout_bottom_menu"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_gravity="bottom"
android:layout_marginRight="48dp"
android:background="#80000000"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="5dp"
android:visibility="gone"> <TextView
android:id="@+id/go_zoombig_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:background="@drawable/bg_round_corner_solid_white"
android:padding="5dp"
android:text="放大"
android:textColor="@color/textview_color_gray3"
android:textSize="@dimen/s_size"
android:visibility="gone" /> <TextView
android:id="@+id/go_zoomsmall_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:background="@drawable/bg_round_corner_solid_white"
android:padding="5dp"
android:text="缩小"
android:textColor="@color/textview_color_gray3"
android:textSize="@dimen/s_size"
android:visibility="gone" /> <ImageView
android:id="@+id/rocker_iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:src="@drawable/rocker_icon_white"
android:visibility="gone" /> <TextView
android:id="@+id/monitor_name_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:textColor="@color/white"
android:textSize="@dimen/m_size" /> </LinearLayout> <LinearLayout
android:id="@+id/tool_control_layout"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="right|bottom"
android:background="#80000000"
android:gravity="center"
android:orientation="horizontal"> <ImageView
android:id="@+id/tools_control_iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/hk_tools_open" /> </LinearLayout> <LinearLayout
android:id="@+id/layout_rocker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:layout_marginBottom="40dp"
android:orientation="horizontal"
android:visibility="gone"> <com.kongqw.rockerlibrary.view.RockerView xmlns:kongqw="http://schemas.android.com/apk/res-auto"
android:id="@+id/rockerView"
android:layout_width="120dp"
android:layout_height="120dp"
kongqw:areaBackground="@drawable/default_area_bg"
kongqw:rockerBackground="@drawable/default_rocker_bg"
kongqw:rockerRadius="20dp" /> <ImageView
android:id="@+id/rocker_close_iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:src="@drawable/hk_rock_close" /> </LinearLayout> </FrameLayout> </LinearLayout>
四、最终效果图
乐橙平台大华监控Android端实时预览播放的更多相关文章
- Android中实时预览UI和编写UI的各种技巧
一.啰嗦 之前有读者反馈说,你搞这个所谓的最佳实践,每篇文章最后就给了一个库,感觉不是很高大上.其实,我在写这个系列之初就有想过这个问题.我的目的是:给出最实用的库来帮助我们开发,并且尽可能地说明这个 ...
- Sublime、Webstorm等在APICloud平台上全面支持WiFi真机同步和实时预览功能
APICloud工具插件包括APICloud Studio.Sublime Text和Webstorm全面为开发者提供iOS和Android平台真机同步调试功能,不仅可以通过USB方式进行APP真机同 ...
- Android 10开发者预览版功能介绍
Android P的开发者预览版最亮眼的功能莫过于支持“刘海屏”等屏幕显示.同样在适配可折叠设备方面,Android Q的第一个开发者预览版也很“接地气”,谷歌早在去年11月就发布了对可折叠设备的支持 ...
- Android远程桌面助手(B1185)for Android P开发者预览版
Android P的开发者预览版已出,其中App compatibility changes部分特别强调“The platform restricts the use of some non-SDK ...
- 用pdf.js实现在移动端在线预览pdf文件
用pdf.js实现在移动端在线预览pdf文件1.下载pdf.js 官网地址:https://mozilla.github.io/pdf.js/ 2.配置 下载下来的文件包,就是一个demo ...
- js实现移动端图片预览:手势缩放, 手势拖动,双击放大...
.katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...
- 2016移动端Android新技术综合预览--好文不多,这一篇就足够
Csdn /Tamic 原文地址: http://blog.csdn.net/sk719887916/article/details/53525067 本文章6月份已完成(http://www.jia ...
- 关于降低android手机摄像头预览分辨率
假设现在有这样一个需求需要一直开着手机摄像头 但是不做任何拍照动作 但是每个手机的相机分辨率都不同 而默认预览的时候参数是最大分辨率 这样有时候就回导致电量损耗的加快 所以我们可以采取降低相机分辨率的 ...
- Android手势识别 Camera 预览界面上显示文字 布局注意事项(merge布局)
通常在Surfaceview作为预览视频帧的载体,有时需在上面显示提示文字.曾经我弄的都好好的.今天忽然发现叠加的TextView不管咋弄都出不来文字了,跟Surfaceview一起放在FrameLa ...
随机推荐
- 如何让VS像CB一样使用
之前用VS,先是完成了GLUT库下的opengl使用: 然后得知GLUT有些过时,又按照教程接触了GLFW库下,反正对我来说是有些复杂. 今天正式试一试用VS来写ACM的题目,发现不能定义string ...
- HDU - 3644:A Chocolate Manufacturer's Problem(模拟退火, 求多边形内最大圆半径)
pro:给定一个N边形,然后给半径为R的圆,问是否可以放进去. 问题转化为多边形的最大内接圆半径.(N<50): sol:乍一看,不就是二分+半平面交验证是否有核的板子题吗. 然而事情并没有那 ...
- 3、Python的IDE之Jupyter的使用
一.Jupyter介绍 Jupyter Notebook 的本质是一个 Web 应用程序,便于创建和共享文学化程序文档,支持实时代码,数学方程,可视化和 markdown.用途包括:数据清理和转换,数 ...
- linux命令 node常用
//查看进程netstat -nlp //查找某一进程 netstat -nlp | grep node //后台挂起 nohup npm start &
- UVa10828 Back to Kernighan-Ritchie——概率转移&&高斯消元法
题意 给出一个程序控制流图,从每个结点出发到每个后继接结点的概率均相等.当执行完一个没有后继的结点后,整个程序终止.程序总是从编号为1的结点开始.你的任务是对于若干个查询结点,求出每个结点的期望执行次 ...
- .net 代码调用cmd执行.exe程序,获取控制台输出信息
使用.net core 对老项目升级, .net core 使用TripleDES.Create() 加密众iv字节限制 与 framework中的不同, 新项目还需要兼容老项目版本,还不想通过web ...
- LeetCode 723. Candy Crush
原题链接在这里:https://leetcode.com/problems/candy-crush/ 题目: This question is about implementing a basic e ...
- WinDbg常用命令系列---线程栈中局部上下文切换.frame
.frame (Set Local Context) .frame命令指定使用哪个本地上下文(作用域)解释本地变量或显示当前本地上下文. .frame [/c] [/r] [FrameNumber] ...
- 开源项目 03 DocX
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- Spark-Streaming hdfs count 案例
Streaming hdfs count 需要先启动 hadoop 集群. # 启动 hadoop 集群 start-dfs.sh start-yarn.sh # 查看是否启动成功 # 命令 jps ...