首页商品数据接入后台数据,田间检测视频接入本地视频

This commit is contained in:
tongchao 2025-06-10 15:35:06 +08:00
parent 7a946f304c
commit 9d34ea810a
26 changed files with 804 additions and 111 deletions

View File

@ -59,6 +59,8 @@ android {
buildTypes {
debug {
signingConfig signingConfigs.release
// buildConfigField "String", "DOMAIN", '"http://192.168.18.99:8080"'
buildConfigField "String", "DOMAIN", '"http://47.109.205.240:8080"'
jniDebuggable false
zipAlignEnabled false
}
@ -67,6 +69,7 @@ android {
signingConfig signingConfigs.release
minifyEnabled false
jniDebuggable false
buildConfigField "String", "DOMAIN", '"http://47.109.205.240:8080"'
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
@ -125,8 +128,16 @@ dependencies {
implementation 'com.github.zhpanvip:bannerviewpager:3.5.12'
implementation 'com.github.AAChartModel:AAChartCore:-SNAPSHOT'
// implementation 'com.github.AAChartModel:AAChartCore:7.3.0'
implementation 'com.github.li-xiaojun:XPopup:v2.2.23'
//使mediaplayer进行解码
implementation 'xyz.doikki.android.dkplayer:dkplayer-java:3.3.7'
//StandardVideoController的实现
implementation 'xyz.doikki.android.dkplayer:dkplayer-ui:3.3.7'
//使ijkplayer进行解码
implementation 'xyz.doikki.android.dkplayer:player-ijk:3.3.7'
}

View File

@ -0,0 +1,20 @@
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "com.tairui.industrial_operation",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 1,
"versionName": "1.0",
"outputFile": "IndustrialOperation_app_v1.0_20250610153115.apk"
}
],
"elementType": "File"
}

View File

@ -9,31 +9,33 @@
"normal": [
{
"name": "监控001",
"status": 0
"status": 0,
"videoSource": "jiankong1"
},
{
"name": "监控002",
"status": 0
"status": 0,
"videoSource": "jiankong2"
},
{
"name": "监控003",
"status": 0
"status": 0,
"videoSource": "jiankong3"
},
{
"name": "监控004",
"status": 0
"status": 0,
"videoSource": "jiankong4"
},
{
"name": "监控005",
"status": 0
"status": 0,
"videoSource": "jiankong5"
},
{
"name": "监控012",
"status": 0
},
{
"name": "监控013",
"status": 0
"status": 0,
"videoSource": "jiankong6"
}
],
"exceptions": [
@ -118,23 +120,28 @@
"normal": [
{
"name": "监控001",
"status": 0
"status": 0,
"videoSource": "jiankong1"
},
{
"name": "监控002",
"status": 0
"status": 0,
"videoSource": "jiankong2"
},
{
"name": "监控003",
"status": 0
"status": 0,
"videoSource": "jiankong3"
},
{
"name": "监控004",
"status": 0
"status": 0,
"videoSource": "jiankong4"
},
{
"name": "监控005",
"status": 0
"status": 0,
"videoSource": "jiankong5"
}
],
"exceptions": [

View File

@ -16,6 +16,9 @@ import android.text.TextUtils;
import okhttp3.OkHttpClient;
import rxhttp.RxHttp;
import rxhttp.wrapper.ssl.HttpsUtils;
import xyz.doikki.videoplayer.ijk.IjkPlayerFactory;
import xyz.doikki.videoplayer.player.VideoViewConfig;
import xyz.doikki.videoplayer.player.VideoViewManager;
public class IOApplication extends Application {
@ -39,6 +42,14 @@ public class IOApplication extends Application {
initHawk();
intiDialog();
initHttp();
initVideoPlayer();
}
private void initVideoPlayer() {
VideoViewManager.setConfig(VideoViewConfig.newBuilder()
//使用使用IjkPlayer解码
.setPlayerFactory(IjkPlayerFactory.create())
.build());
}
private void initHawk() {
@ -50,7 +61,7 @@ public class IOApplication extends Application {
DialogX.init(this);
DialogX.globalStyle = new MaterialYouStyle();
//设置亮色/暗色在启动下一个对话框时生效
DialogX.globalTheme = DialogX.THEME.AUTO;
DialogX.globalTheme = DialogX.THEME.LIGHT;
}
private void initHttp() {

View File

@ -1,19 +1,27 @@
package com.tairui.industrial_operation.entity;
import com.tairui.industrial_operation.BuildConfig;
public class Api {
// public static String BASE_HOST = "http://192.168.18.188:8080";
public static String BASE_HOST = "http://47.109.205.240:8080";
public static String BASE_HOST = BuildConfig.DOMAIN;
/**
* 请求成功
*/
public static final int CODE_SUCCESS_REQUEST = 200;
/**
* 登录状态异常
*/
public static final int CODE_AUTH_ERROR = 401;
/**
* token前面需要加入的字段
*/
public static final String BEARER = "Bearer ";
/**
* 分页值
*/
public static final int SIZE_PAGE = 10;
/**
* 请求接口的时候的 授权token
*/
@ -22,4 +30,6 @@ public class Api {
public static final String REGISTER = BASE_HOST + "/auth/registerApp";
public static final String LOGIN = BASE_HOST + "/auth/login";
public static final String HOME_GOODS_LIST = BASE_HOST + "/goods/goodInfoManage/transactionGoodInfo";
}

View File

@ -1,13 +1,22 @@
package com.tairui.industrial_operation.http;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.orhanobut.hawk.Hawk;
import com.tairui.industrial_operation.IOApplication;
import com.tairui.industrial_operation.config.AppConfig;
import com.tairui.industrial_operation.http.exception.AuthException;
import com.tairui.industrial_operation.ui.account.LoginActivity;
import android.content.Intent;
import android.text.TextUtils;
import rxhttp.wrapper.exception.HttpStatusCodeException;
import rxhttp.wrapper.exception.ParseException;
/**
* Http请求错误信息
*/
public class ErrorInfo {
private int errorCode; //仅指服务器返回的错误码
private String errorMsg; //错误文案网络错误请求失败错误服务器返回的错误等文案
private Throwable throwable; //异常信息
@ -15,7 +24,17 @@ public class ErrorInfo {
public ErrorInfo(Throwable throwable) {
this.throwable = throwable;
String errorMsg = ExceptionHelper.handleNetworkException(throwable); //网络异常
if (throwable instanceof ParseException) { // ParseException异常表明请求成功但是数据不正确
if (throwable instanceof AuthException) { //没有身份信息需要重新登录
this.errorMsg = throwable.getMessage();
AppConfig.getInstance().setToken("");
Hawk.put("token", "");
// 创建跳转到登录页面的 Intent
Intent intent = new Intent(IOApplication.getContext(), LoginActivity.class);
// 设置标志位清除所有旧的 Activity 并创建新任务
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
// 启动登录 Activity
IOApplication.getContext().startActivity(intent);
} else if (throwable instanceof ParseException) { // ParseException异常表明请求成功但是数据不正确
String errorCode = throwable.getLocalizedMessage();
this.errorCode = Integer.valueOf(errorCode);
errorMsg = throwable.getMessage();
@ -23,7 +42,20 @@ public class ErrorInfo {
errorMsg = errorCode;//errorMsg为空显示errorCode
}
}
this.errorMsg = errorMsg;
if (errorMsg == null) {
if (throwable instanceof HttpStatusCodeException) {
HttpStatusCodeException exception = (HttpStatusCodeException) throwable;
if (exception.getStatusCode().equals("500")) {
this.errorMsg = "服务器接口发生错误";
} else {
JsonObject result = (JsonObject) new JsonParser().parse(exception.getResult());
String message = result.get("msg").getAsString();
this.errorMsg = message;
}
}
} else {
this.errorMsg = errorMsg;
}
}
public int getErrorCode() {
@ -37,5 +69,4 @@ public class ErrorInfo {
public Throwable getThrowable() {
return throwable;
}
}

View File

@ -4,6 +4,7 @@ import java.io.IOException;
import java.lang.reflect.Type;
import com.tairui.industrial_operation.entity.Api;
import com.tairui.industrial_operation.http.exception.AuthException;
import android.annotation.SuppressLint;
import android.text.TextUtils;
@ -62,6 +63,8 @@ public class ResponseParser<T> extends AbstractParser<T> {
}
if (data.getCode() == Api.CODE_SUCCESS_REQUEST) {
return t;
} else if (data.getCode() == Api.CODE_AUTH_ERROR) {
throw new AuthException("-1", data.getMsg(), response);
} else {
throw new ParseException("-1", data.getMsg(), response);
}

View File

@ -0,0 +1,77 @@
package com.tairui.industrial_operation.http.exception;
import java.io.IOException;
import io.reactivex.annotations.NonNull;
import io.reactivex.annotations.Nullable;
import okhttp3.Headers;
import okhttp3.Request;
import okhttp3.Response;
/**
* 没有身份信息需要重新登录
*/
public class AuthException extends IOException {
private String errorCode;
private String requestMethod; //请求方法Get/Post等
private Headers responseHeaders; //响应头
private String requestResult; //请求结果
@Deprecated
public AuthException(String message, Response response) {
this("-1", message, response, null);
}
@Deprecated
public AuthException(String message, Response response, String result) {
this("-1", message, response, result);
}
public AuthException(@NonNull String code, String message, Response response) {
this(code, message, response, null);
}
public AuthException(@NonNull String code, String message, Response response, String result) {
super(message);
errorCode = code;
requestResult = result;
Request request = response.request();
requestMethod = request.method();
responseHeaders = response.headers();
}
public String getRequestResult() {
return requestResult;
}
public String getErrorCode() {
return errorCode;
}
public String getRequestMethod() {
return requestMethod;
}
public Headers getResponseHeaders() {
return responseHeaders;
}
@Nullable
@Override
public String getLocalizedMessage() {
return errorCode;
}
@Override
public String toString() {
return getClass().getName() + ":" +
" Method=" + requestMethod +
" Code=" + errorCode +
"\n\n" + responseHeaders +
"\nmessage = " + getMessage();
}
}

View File

@ -3,6 +3,7 @@ package com.tairui.industrial_operation.ui.account;
import com.google.gson.JsonObject;
import com.orhanobut.hawk.Hawk;
import com.rxjava.rxlife.RxLife;
import com.tairui.industrial_operation.BuildConfig;
import com.tairui.industrial_operation.base.BaseActivity;
import com.tairui.industrial_operation.databinding.ActivityLoginBinding;
import com.tairui.industrial_operation.entity.Api;
@ -26,6 +27,10 @@ public class LoginActivity extends BaseActivity<ActivityLoginBinding> {
@Override
protected void onFindView(Bundle savedInstanceState) {
if (BuildConfig.DEBUG) {
setText(binding.inputUserName, "admin");
setText(binding.inputUserPass, "admin123");
}
}
@Override

View File

@ -3,15 +3,21 @@ package com.tairui.industrial_operation.ui.home;
import java.util.ArrayList;
import java.util.List;
import com.rxjava.rxlife.RxLife;
import com.tairui.industrial_operation.R;
import com.tairui.industrial_operation.base.BaseFragment;
import com.tairui.industrial_operation.base.entity.BaseHolderEntity;
import com.tairui.industrial_operation.databinding.FragmentHomeBinding;
import com.tairui.industrial_operation.entity.Api;
import com.tairui.industrial_operation.http.OnError;
import com.tairui.industrial_operation.ui.home.adapter.HomeAdapter;
import com.tairui.industrial_operation.ui.home.entity.HomeGoodsEntity;
import com.tairui.industrial_operation.util.ArrayUtil;
import com.tairui.industrial_operation.widget.RefreshRecyclerView;
import android.view.View;
import androidx.recyclerview.widget.LinearLayoutManager;
import rxhttp.RxHttp;
public class HomeFragment extends BaseFragment<FragmentHomeBinding> {
@ -60,10 +66,43 @@ public class HomeFragment extends BaseFragment<FragmentHomeBinding> {
@Override
protected void onApplyData() {
// binding.refreshRecycler.showLoading();
// currentPageIndex = 1;
// requestData(false);
binding.refreshRecycler.showLoading();
currentPageIndex = 1;
requestData(false);
}
private void requestData(boolean loadmore) {
RxHttp.get(Api.HOME_GOODS_LIST).add("type", 1).add("current", currentPageIndex).add("size", Api.SIZE_PAGE)
.asResponse(HomeGoodsEntity.class).as(RxLife.asOnMain(this)).subscribe(data -> {
if (loadmore) {
binding.refreshRecycler.finishLoadMore();
}
if (!ArrayUtil.isEmpty(data.getRecords())) {
if (loadmore) {
adapter.addGoodsData(data.getRecords());
} else {
initData(data.getRecords());
}
currentPageIndex += 1;
if (ArrayUtil.size(data.getRecords()) < Api.SIZE_PAGE) {
binding.refreshRecycler.setNoMoreData(true);
} else {
binding.refreshRecycler.setNoMoreData(false);
}
binding.refreshRecycler.showContent();
} else {
binding.refreshRecycler.showError();
binding.refreshRecycler.setNoMoreData(true);
}
}, (OnError) error -> {
binding.refreshRecycler.showError();
binding.refreshRecycler.setNoMoreData(true);
showError(error.getErrorMsg());
});
}
private void initData(List<HomeGoodsEntity.RecordsEntity> goodsList) {
List<BaseHolderEntity> list = new ArrayList<>();
BaseHolderEntity bannerItem = new BaseHolderEntity();
bannerItem.setType(HomeAdapter.TYPE_BANNER);
@ -111,57 +150,10 @@ public class HomeFragment extends BaseFragment<FragmentHomeBinding> {
BaseHolderEntity goodsItem = new BaseHolderEntity();
goodsItem.setType(HomeAdapter.TYPE_GOODS);
List<String> goodsList = new ArrayList<>();
for (int i = 0; i < 20; i++) {
goodsList.add(String.valueOf(i));
}
goodsItem.setData(goodsList);
list.add(goodsItem);
adapter.setNewData(list);
binding.refreshRecycler.setNoMoreData(true);
binding.refreshRecycler.showContent();
}
private void requestData(boolean loadmore) {
// RxHttpNoBodyParam http = RxHttp.get(Api.LAND_RESOURCE_LIST);
// if (!TextUtils.isEmpty(regionCode)) {
// http.add("regionCode", regionCode);
// }
// if (!TextUtils.isEmpty(searchWord)) {
// http.add("landName", searchWord);
// }
// http.add("landType", landTypeId)
// .add("current", currentPageIndex)
// .add("size", Api.SIZE_PAGE)
// .asResponse(LandResourceEntity.class)
// .as(RxLife.asOnMain(this))
// .subscribe(data -> {
// if (loadmore) {
// binding.refreshRecycler.finishLoadMore();
// }
// if (!ArrayUtil.isEmpty(data.getRecords())) {
// if (loadmore) {
// adapter.addData(data.getRecords());
// } else {
// adapter.setNewData(data.getRecords());
// }
// currentPageIndex += 1;
// if (ArrayUtil.size(data.getRecords()) < Api.SIZE_PAGE) {
// binding.refreshRecycler.setNoMoreData(true);
// } else {
// binding.refreshRecycler.setNoMoreData(false);
// }
// binding.refreshRecycler.showContent();
// } else {
// binding.refreshRecycler.showError();
// binding.refreshRecycler.setNoMoreData(true);
// }
// }, (OnError) error -> {
// binding.refreshRecycler.showError();
// binding.refreshRecycler.setNoMoreData(true);
// PopTip.show(error.getErrorMsg()).iconError();
// });
}
}

View File

@ -7,6 +7,7 @@ import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.tairui.industrial_operation.R;
import com.tairui.industrial_operation.base.entity.BaseHolderEntity;
import com.tairui.industrial_operation.ui.home.entity.HomeGoodsEntity;
import com.tairui.industrial_operation.ui.smart_farm.SmartFarmActivity;
import com.tairui.industrial_operation.util.DensityUtils;
import com.tairui.industrial_operation.util.IntentUtil;
@ -32,6 +33,8 @@ public class HomeAdapter extends BaseMultiItemQuickAdapter<BaseHolderEntity, Bas
public static final int TYPE_GUIDE = 4;
public static final int TYPE_GOODS = 5;
private HomeGoodsAdapter goodsAdapter;
public HomeAdapter(List<BaseHolderEntity> list) {
super(list);
addItemType(TYPE_BANNER, R.layout.item_home_banner);
@ -41,6 +44,19 @@ public class HomeAdapter extends BaseMultiItemQuickAdapter<BaseHolderEntity, Bas
addItemType(TYPE_GOODS, R.layout.item_home_goods);
}
public void addGoodsData(List<HomeGoodsEntity.RecordsEntity> goods) {
// for (BaseHolderEntity item : getData()) {
// if (item.getType() == TYPE_GOODS) {
// List<HomeGoodsEntity.RecordsEntity> data = (List<HomeGoodsEntity.RecordsEntity>) item.getData();
// data.addAll(goods);
// item.setData(data);
// }
// }
if (goodsAdapter != null) {
goodsAdapter.addData(goods);
}
}
@Override
protected void convert(@NonNull BaseViewHolder holder, BaseHolderEntity entity) {
switch (holder.getItemViewType()) {
@ -83,8 +99,8 @@ public class HomeAdapter extends BaseMultiItemQuickAdapter<BaseHolderEntity, Bas
RecyclerView goodsRecycler = holder.getView(R.id.recycle_view);
goodsRecycler.setLayoutManager(new GridLayoutManager(mContext, 2));
goodsRecycler.addItemDecoration(new GridSpacingItemDecoration(2, DensityUtils.dp2px(mContext, 12), true));
HomeGoodsAdapter goodsAdapter = new HomeGoodsAdapter();
goodsAdapter.setNewData((List<String>) entity.getData());
goodsAdapter = new HomeGoodsAdapter();
goodsAdapter.setNewData((List<HomeGoodsEntity.RecordsEntity>) entity.getData());
goodsRecycler.setAdapter(goodsAdapter);
break;
default:

View File

@ -3,34 +3,37 @@ package com.tairui.industrial_operation.ui.home.adapter;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.tairui.industrial_operation.R;
import com.tairui.industrial_operation.widget.RoundBackgroundSpan;
import com.tairui.industrial_operation.ui.home.entity.HomeGoodsEntity;
import com.tairui.industrial_operation.util.glide.GlideLoader;
import android.graphics.Color;
import android.text.Spannable;
import android.text.SpannableString;
import android.widget.TextView;
import android.widget.ImageView;
import androidx.annotation.NonNull;
public class HomeGoodsAdapter extends BaseQuickAdapter<String, BaseViewHolder> {
public class HomeGoodsAdapter extends BaseQuickAdapter<HomeGoodsEntity.RecordsEntity, BaseViewHolder> {
public HomeGoodsAdapter() {
super(R.layout.item_goods);
}
@Override
protected void convert(@NonNull BaseViewHolder holder, String entity) {
TextView titleTv = holder.getView(R.id.title);
SpannableString spannableString = new SpannableString("溯源耿马普罗斯西红柿沙瓤番茄甄选番茄苗");
// 创建带圆角和padding的背景Span (参数: 背景色, 文字颜色, 圆角半径, padding)
RoundBackgroundSpan span = new RoundBackgroundSpan(
Color.parseColor("#D3F2E6"), // 浅绿背景
Color.parseColor("#25BF82"), // 深绿文字
8, // 圆角半径
10 // padding大小
);
// 应用Span到"溯源"两个字
spannableString.setSpan(span, 0, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
titleTv.setText(spannableString);
protected void convert(@NonNull BaseViewHolder holder, HomeGoodsEntity.RecordsEntity entity) {
// TextView titleTv = holder.getView(R.id.title);
// SpannableString spannableString = new SpannableString(entity.getGoodName());
// // 创建带圆角和padding的背景Span (参数: 背景色, 文字颜色, 圆角半径, padding)
// RoundBackgroundSpan span = new RoundBackgroundSpan(
// Color.parseColor("#D3F2E6"), // 浅绿背景
// Color.parseColor("#25BF82"), // 深绿文字
// 8, // 圆角半径
// 10 // padding大小
// );
//
// // 应用Span到"溯源"两个字
// spannableString.setSpan(span, 0, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// titleTv.setText(spannableString);
holder.setText(R.id.title, entity.getGoodName());
ImageView imgView = holder.getView(R.id.img);
GlideLoader.loadOriginal(imgView, entity.getGoodUrl());
holder.setText(R.id.price, String.valueOf(entity.getGoodPrice()));
holder.setText(R.id.countType, String.valueOf(entity.getGoodCateGory()));
}
}

View File

@ -0,0 +1,362 @@
package com.tairui.industrial_operation.ui.home.entity;
import java.util.List;
import com.google.gson.annotations.SerializedName;
public class HomeGoodsEntity {
@SerializedName("total")
private Integer total;
@SerializedName("size")
private Integer size;
@SerializedName("current")
private Integer current;
@SerializedName("optimizeCountSql")
private Boolean optimizeCountSql;
@SerializedName("searchCount")
private Boolean searchCount;
@SerializedName("maxLimit")
private Object maxLimit;
@SerializedName("countId")
private Object countId;
@SerializedName("pages")
private Integer pages;
@SerializedName("records")
private List<RecordsEntity> records;
@SerializedName("orders")
private List<?> orders;
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
public Integer getSize() {
return size;
}
public void setSize(Integer size) {
this.size = size;
}
public Integer getCurrent() {
return current;
}
public void setCurrent(Integer current) {
this.current = current;
}
public Boolean isOptimizeCountSql() {
return optimizeCountSql;
}
public void setOptimizeCountSql(Boolean optimizeCountSql) {
this.optimizeCountSql = optimizeCountSql;
}
public Boolean isSearchCount() {
return searchCount;
}
public void setSearchCount(Boolean searchCount) {
this.searchCount = searchCount;
}
public Object getMaxLimit() {
return maxLimit;
}
public void setMaxLimit(Object maxLimit) {
this.maxLimit = maxLimit;
}
public Object getCountId() {
return countId;
}
public void setCountId(Object countId) {
this.countId = countId;
}
public Integer getPages() {
return pages;
}
public void setPages(Integer pages) {
this.pages = pages;
}
public List<RecordsEntity> getRecords() {
return records;
}
public void setRecords(List<RecordsEntity> records) {
this.records = records;
}
public List<?> getOrders() {
return orders;
}
public void setOrders(List<?> orders) {
this.orders = orders;
}
public static class RecordsEntity {
@SerializedName("id")
private String id;
@SerializedName("goodName")
private String goodName;
@SerializedName("goodCateGory")
private String goodCateGory;
@SerializedName("goodUrl")
private String goodUrl;
@SerializedName("goodPrice")
private Double goodPrice;
@SerializedName("parentId")
private Object parentId;
@SerializedName("unit")
private Object unit;
@SerializedName("attribute")
private Object attribute;
@SerializedName("detailUrl")
private Object detailUrl;
@SerializedName("brandId")
private Object brandId;
@SerializedName("traceCode")
private Object traceCode;
@SerializedName("netWeight")
private Object netWeight;
@SerializedName("safeguard")
private Object safeguard;
@SerializedName("discountSettings")
private Object discountSettings;
@SerializedName("discountRebate")
private Object discountRebate;
@SerializedName("categoryId1")
private Object categoryId1;
@SerializedName("categoryId2")
private Object categoryId2;
@SerializedName("categoryId3")
private Object categoryId3;
@SerializedName("videoUrl")
private Object videoUrl;
@SerializedName("describeContent")
private String describeContent;
@SerializedName("salesVolume")
private Object salesVolume;
@SerializedName("areaAddress")
private Object areaAddress;
@SerializedName("detailAddress")
private Object detailAddress;
@SerializedName("unitWeight")
private Object unitWeight;
@SerializedName("unitVolume")
private Object unitVolume;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getGoodName() {
return goodName;
}
public void setGoodName(String goodName) {
this.goodName = goodName;
}
public String getGoodCateGory() {
return goodCateGory;
}
public void setGoodCateGory(String goodCateGory) {
this.goodCateGory = goodCateGory;
}
public String getGoodUrl() {
return goodUrl;
}
public void setGoodUrl(String goodUrl) {
this.goodUrl = goodUrl;
}
public Double getGoodPrice() {
return goodPrice;
}
public void setGoodPrice(Double goodPrice) {
this.goodPrice = goodPrice;
}
public Object getParentId() {
return parentId;
}
public void setParentId(Object parentId) {
this.parentId = parentId;
}
public Object getUnit() {
return unit;
}
public void setUnit(Object unit) {
this.unit = unit;
}
public Object getAttribute() {
return attribute;
}
public void setAttribute(Object attribute) {
this.attribute = attribute;
}
public Object getDetailUrl() {
return detailUrl;
}
public void setDetailUrl(Object detailUrl) {
this.detailUrl = detailUrl;
}
public Object getBrandId() {
return brandId;
}
public void setBrandId(Object brandId) {
this.brandId = brandId;
}
public Object getTraceCode() {
return traceCode;
}
public void setTraceCode(Object traceCode) {
this.traceCode = traceCode;
}
public Object getNetWeight() {
return netWeight;
}
public void setNetWeight(Object netWeight) {
this.netWeight = netWeight;
}
public Object getSafeguard() {
return safeguard;
}
public void setSafeguard(Object safeguard) {
this.safeguard = safeguard;
}
public Object getDiscountSettings() {
return discountSettings;
}
public void setDiscountSettings(Object discountSettings) {
this.discountSettings = discountSettings;
}
public Object getDiscountRebate() {
return discountRebate;
}
public void setDiscountRebate(Object discountRebate) {
this.discountRebate = discountRebate;
}
public Object getCategoryId1() {
return categoryId1;
}
public void setCategoryId1(Object categoryId1) {
this.categoryId1 = categoryId1;
}
public Object getCategoryId2() {
return categoryId2;
}
public void setCategoryId2(Object categoryId2) {
this.categoryId2 = categoryId2;
}
public Object getCategoryId3() {
return categoryId3;
}
public void setCategoryId3(Object categoryId3) {
this.categoryId3 = categoryId3;
}
public Object getVideoUrl() {
return videoUrl;
}
public void setVideoUrl(Object videoUrl) {
this.videoUrl = videoUrl;
}
public String getDescribeContent() {
return describeContent;
}
public void setDescribeContent(String describeContent) {
this.describeContent = describeContent;
}
public Object getSalesVolume() {
return salesVolume;
}
public void setSalesVolume(Object salesVolume) {
this.salesVolume = salesVolume;
}
public Object getAreaAddress() {
return areaAddress;
}
public void setAreaAddress(Object areaAddress) {
this.areaAddress = areaAddress;
}
public Object getDetailAddress() {
return detailAddress;
}
public void setDetailAddress(Object detailAddress) {
this.detailAddress = detailAddress;
}
public Object getUnitWeight() {
return unitWeight;
}
public void setUnitWeight(Object unitWeight) {
this.unitWeight = unitWeight;
}
public Object getUnitVolume() {
return unitVolume;
}
public void setUnitVolume(Object unitVolume) {
this.unitVolume = unitVolume;
}
}
}

View File

@ -20,12 +20,15 @@ import com.tairui.industrial_operation.util.DensityUtils;
import com.tairui.industrial_operation.util.IntentUtil;
import com.tairui.industrial_operation.util.JsonUtils;
import com.tairui.industrial_operation.util.SingleClickListener;
import com.tairui.industrial_operation.util.VideoUtil;
import com.tairui.industrial_operation.widget.TikTokController;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import xyz.doikki.videoplayer.ijk.IjkPlayerFactory;
public class FieldMonitoringActivity extends BaseActivity<ActivityFieldMonitoringBinding> {
@ -54,6 +57,10 @@ public class FieldMonitoringActivity extends BaseActivity<ActivityFieldMonitorin
binding.stationRecycler.setHasFixedSize(true);
groupAdapter = new GroupAdapter();
binding.stationRecycler.setAdapter(groupAdapter);
TikTokController controller = new TikTokController(this);
binding.player.setVideoController(controller);
binding.player.setLooping(true);
}
private void showTeamMenu() {
@ -68,8 +75,10 @@ public class FieldMonitoringActivity extends BaseActivity<ActivityFieldMonitorin
selectGroup = selectTeam.getGroups().get(0);
if (selectGroup.getType().equals("monitor")) {
selectMonitor = selectGroup.getMonitors().getNormal().get(0);
playVideo();
selectStation = null;
} else {
stopVideo();
selectStation = selectGroup.getStations().get(0);
selectMonitor = null;
}
@ -86,10 +95,11 @@ public class FieldMonitoringActivity extends BaseActivity<ActivityFieldMonitorin
}
PopMenu.show(binding.layoutMonitor, menus)
.setBackgroundColorRes(R.color.white)
.setWidth(DensityUtils.dp2px(mContext,100))
.setWidth(DensityUtils.dp2px(mContext, 100))
.setOnMenuItemClickListener((dialog, text, index) -> {
selectMonitor = selectGroup.getMonitors().getNormal().get(index);
setText(binding.tvMonitorName, selectMonitor.getName());
playVideo();
return false;
}).setItemDivider(new ItemDivider(15, 15, 1));
}
@ -137,8 +147,10 @@ public class FieldMonitoringActivity extends BaseActivity<ActivityFieldMonitorin
groupAdapter.setSelect(i);
if (selectGroup.getType().equals("monitor")) {
selectMonitor = selectGroup.getMonitors().getNormal().get(0);
playVideo();
selectStation = null;
} else {
stopVideo();
selectStation = selectGroup.getStations().get(0);
selectMonitor = null;
}
@ -194,12 +206,63 @@ public class FieldMonitoringActivity extends BaseActivity<ActivityFieldMonitorin
setText(binding.tvMonitorName, selectMonitor.getName());
setGone(binding.layoutMonitorStatus, true);
setGone(binding.layoutStationInfo, false);
setGone(binding.imgMonitor, true);
setGone(binding.player, true);
playVideo();
} else {
setText(binding.tvMonitorName, selectStation.getName());
setGone(binding.layoutStationInfo, true);
stopVideo();
setGone(binding.layoutMonitorStatus, false);
setGone(binding.imgMonitor, false);
setGone(binding.player, false);
}
}
private void stopVideo() {
binding.player.release();
}
private void playVideo() {
binding.player.release();
Object playerFactory = VideoUtil.getCurrentPlayerFactoryInVideoView(binding.player);
if (playerFactory instanceof IjkPlayerFactory) {
String url = "android.resource://" + getPackageName() + "/" + getIdentifier(selectMonitor.getVideoSource());
binding.player.setUrl(url);
binding.player.start();
}
}
private int getIdentifier(String resourceName) {
// 从字符串获取资源 ID
int resourceId = getResources().getIdentifier(
resourceName, // 资源名称不带扩展名
"raw", // 资源类型对应 res/raw 目录
getPackageName() // 当前应用的包名
);
return resourceId;
}
@Override
protected void onPause() {
super.onPause();
binding.player.pause();
}
@Override
protected void onResume() {
super.onResume();
binding.player.resume();
}
@Override
protected void onDestroy() {
super.onDestroy();
binding.player.release();
}
@Override
public void onBackPressed() {
if (!binding.player.onBackPressed()) {
super.onBackPressed();
}
}

View File

@ -117,6 +117,16 @@ public class FileMonitoringEntity {
private String name;
@SerializedName("status")
private Integer status;
@SerializedName("videoSource")
private String videoSource;
public String getVideoSource() {
return videoSource;
}
public void setVideoSource(String videoSource) {
this.videoSource = videoSource;
}
public String getName() {
return name;

View File

@ -0,0 +1,35 @@
package com.tairui.industrial_operation.util;
import java.lang.reflect.Field;
import xyz.doikki.videoplayer.controller.ControlWrapper;
import xyz.doikki.videoplayer.player.VideoView;
public class VideoUtil {
public static Object getCurrentPlayerFactoryInVideoView(ControlWrapper controlWrapper) {
Object playerFactory = null;
try {
Field mPlayerControlField = controlWrapper.getClass().getDeclaredField("mPlayerControl");
mPlayerControlField.setAccessible(true);
Object playerControl = mPlayerControlField.get(controlWrapper);
if (playerControl instanceof VideoView) {
playerFactory = getCurrentPlayerFactoryInVideoView((VideoView) playerControl);
}
} catch (Exception e) {
e.printStackTrace();
}
return playerFactory;
}
public static Object getCurrentPlayerFactoryInVideoView(VideoView videoView) {
Object playerFactory = null;
try {
Field mPlayerFactoryField = videoView.getClass().getSuperclass().getDeclaredField("mPlayerFactory");
mPlayerFactoryField.setAccessible(true);
playerFactory = mPlayerFactoryField.get(videoView);
} catch (Exception e) {
e.printStackTrace();
}
return playerFactory;
}
}

View File

@ -0,0 +1,38 @@
package com.tairui.industrial_operation.widget;
import android.content.Context;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import xyz.doikki.videoplayer.controller.BaseVideoController;
public class TikTokController extends BaseVideoController {
public TikTokController(@NonNull Context context) {
super(context);
}
public TikTokController(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public TikTokController(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
// {
// //显示调试信息
// addControlComponent(new DebugInfoView(getContext()));
// }
@Override
protected int getLayoutId() {
return 0;
}
@Override
public boolean showNetWarning() {
//不显示移动网络播放警告
return false;
}
}

View File

@ -313,12 +313,11 @@
android:src="@mipmap/ic_station_status_normal" />
</LinearLayout>
<ImageView
android:id="@+id/imgMonitor"
<xyz.doikki.videoplayer.player.VideoView
android:id="@+id/player"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="12dp"
android:src="@mipmap/pic_monitor"
android:visibility="gone"
app:layout_constraintDimensionRatio="344:188"
app:layout_constraintTop_toBottomOf="@id/layoutMonitor" />
@ -511,23 +510,23 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_gravity="left|center_vertical"
android:layout_marginTop="12dp"
android:text="生长趋势图"
android:textColor="@color/color_txt_label"
android:textSize="14sp" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_marginTop="12dp"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:layout_marginTop="12dp">
<ImageView
app:layout_constraintTop_toTopOf="parent"
android:src="@mipmap/pic_monitor_chart"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="334:156"/>
android:src="@mipmap/pic_monitor_chart"
app:layout_constraintDimensionRatio="334:156"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -25,7 +25,6 @@
android:id="@+id/inputUserName"
android:layout_width="match_parent"
android:layout_height="56dp"
android:text="admin"
android:layout_marginLeft="24dp"
android:layout_marginTop="64dp"
android:layout_marginRight="24dp"
@ -41,7 +40,6 @@
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_marginLeft="24dp"
android:text="admin123"
android:layout_marginTop="24dp"
android:layout_marginRight="24dp"
android:background="@drawable/bg_container_white_raduis_30"

View File

@ -3,8 +3,10 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_container_white_raduis_10"
android:gravity="center_horizontal"
android:orientation="vertical">
android:orientation="vertical"
android:padding="12dp">
<ImageView
android:id="@+id/img"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.