diff --git a/app/build.gradle b/app/build.gradle index aebe63d..c1e0b30 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -39,6 +39,13 @@ android { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } + + packagingOptions { + pickFirst 'lib/x86/libc++_shared.so' + pickFirst 'lib/arm64-v8a/libc++_shared.so' + pickFirst 'lib/armeabi-v7a/libc++_shared.so' + pickFirst 'lib/x86_64/libc++_shared.so' + } } dependencies { @@ -91,4 +98,12 @@ dependencies { implementation 'com.google.android.material:material:1.3.0' //https://github.com/donkingliang/LabelsView implementation 'com.github.donkingliang:LabelsView:1.6.5' +// https://github.com/JavaNoober/BackgroundLibrary + //布局直接用shape selector等属性 + implementation 'com.github.JavaNoober.BackgroundLibrary:libraryx:1.7.2' + + //融云IM 5.2.1.55 + api project(path: ':imlib') + api project(path: ':calllib') + compile 'com.github.lmiot:LoadDialog:V2.1' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8370bb3..fa3aa98 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,13 @@ + + + + + + + @@ -83,6 +90,12 @@ + + >>() { @Override @@ -145,7 +145,7 @@ public class DoctorActivity extends BaseActivity { list.remove(list.size() - 1); } list.addAll(doctorInfo); - if (doctorInfo.size() == endNum) { + if (doctorInfo.size() == row) { GetNearDoctorApi.DoctorInfo.MemberBean memberBean = new GetNearDoctorApi.DoctorInfo.MemberBean(); memberBean.setLast(true); list.add(memberBean); diff --git a/app/src/main/java/com/unionmed/unionmedtv/activity/DoctorDetailActivity.java b/app/src/main/java/com/unionmed/unionmedtv/activity/DoctorDetailActivity.java index 82a7ca0..3fdd871 100644 --- a/app/src/main/java/com/unionmed/unionmedtv/activity/DoctorDetailActivity.java +++ b/app/src/main/java/com/unionmed/unionmedtv/activity/DoctorDetailActivity.java @@ -1,56 +1,64 @@ package com.unionmed.unionmedtv.activity; +import android.Manifest; import android.content.Context; import android.content.Intent; +import android.hardware.camera2.CameraAccessException; +import android.hardware.camera2.CameraManager; import android.os.Bundle; import android.text.TextUtils; +import android.util.Log; +import android.view.SurfaceView; import android.view.View; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; +import android.widget.Toast; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.core.widget.NestedScrollView; -import androidx.leanback.widget.ArrayObjectAdapter; -import androidx.leanback.widget.FocusHighlight; -import androidx.leanback.widget.FocusHighlightHelper; -import androidx.leanback.widget.ItemBridgeAdapter; -import androidx.leanback.widget.Presenter; -import androidx.leanback.widget.VerticalGridView; -import androidx.recyclerview.widget.GridLayoutManager; -import androidx.recyclerview.widget.RecyclerView; +import com.blankj.utilcode.util.LogUtils; import com.blankj.utilcode.util.ToastUtils; import com.bumptech.glide.Glide; import com.bumptech.glide.request.RequestOptions; import com.hjq.http.EasyHttp; import com.hjq.http.listener.OnHttpListener; +import com.hjq.permissions.OnPermissionCallback; +import com.hjq.permissions.Permission; +import com.hjq.permissions.XXPermissions; import com.unionmed.unionmedtv.R; -import com.unionmed.unionmedtv.adapter.HospitalDetailAdapter; +import com.unionmed.unionmedtv.api.ApplyVideoApi; import com.unionmed.unionmedtv.api.GetDoctorInfoApi; -import com.unionmed.unionmedtv.api.GetNearDoctorApi; import com.unionmed.unionmedtv.base.BaseActivity; import com.unionmed.unionmedtv.network.ApiResponse; import com.unionmed.unionmedtv.network.HttpData; -import com.unionmed.unionmedtv.presenter.TypeDoctorPresenter; import com.unionmed.unionmedtv.utils.CacheUtil; -import com.unionmed.unionmedtv.utils.FontDisplayUtil; -import com.unionmed.unionmedtv.utils.LinearSpacingItemDecoration; -import com.unionmed.unionmedtv.utils.OnChildClickListener; -import com.unionmed.unionmedtv.widgets.focus.MyItemBridgeAdapter; + import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; -import me.jessyan.autosize.utils.LogUtils; +import io.rong.calllib.IRongCallListener; +import io.rong.calllib.RongCallClient; +import io.rong.calllib.RongCallCommon; +import io.rong.calllib.RongCallSession; +import io.rong.imlib.model.Conversation; -public class DoctorDetailActivity extends BaseActivity { +public class DoctorDetailActivity extends BaseActivity implements View.OnClickListener { private String userAccount = ""; private ImageView iv_image; private TextView tv_name; - private TextView tv_dept; + private TextView + + tv_dept; private TextView tv_affiliation_hospital; private TextView tv_doctor_brief; private TextView tv_grade; + private LinearLayout lin_video; + private String imAccount;//im账号 public static void StartActivity(Context context, String userAccount) { Intent intent = new Intent(context, DoctorDetailActivity.class); @@ -74,6 +82,8 @@ public class DoctorDetailActivity extends BaseActivity { tv_affiliation_hospital = findViewById(R.id.tv_affiliation_hospital); tv_doctor_brief = findViewById(R.id.tv_doctor_brief); tv_grade = findViewById(R.id.tv_grade); + lin_video = findViewById(R.id.lin_video); + lin_video.setOnClickListener(this); } public void loadData() { @@ -90,36 +100,37 @@ public class DoctorDetailActivity extends BaseActivity { .load(infoBean.getPhoto()) .apply(new RequestOptions() .placeholder(R.color.white_e1e1e1) - ) + ) .into(iv_image); + imAccount = infoBean.getIm_useraccount(); //名字 tv_name.setText(infoBean.getName()); if (!infoBean.getChoscodeInfo().isEmpty()) { // 部门职称 GetDoctorInfoApi.ChoscodeInfoBean choscodeInfoBean = infoBean.getChoscodeInfo().get(0); - if (!choscodeInfoBean.getDepartment().isEmpty() - && !choscodeInfoBean.getZc().isEmpty()) {//部门职称都不为null + if (!TextUtils.isEmpty(choscodeInfoBean.getDepartment()) + && !TextUtils.isEmpty(choscodeInfoBean.getZc())) {//部门职称都不为null tv_dept.setText(choscodeInfoBean.getDepartment() + " | " + choscodeInfoBean.getZc()); - } else if (choscodeInfoBean.getDepartment().isEmpty() - && choscodeInfoBean.getZc().isEmpty()) {//部门职称都为null + } else if (TextUtils.isEmpty(choscodeInfoBean.getDepartment()) + && TextUtils.isEmpty(choscodeInfoBean.getZc())) {//部门职称都为null tv_dept.setText("- -"); - } else if (!choscodeInfoBean.getDepartment().isEmpty() - && choscodeInfoBean.getZc().isEmpty()) {//部门不为null,职称为null + } else if (!TextUtils.isEmpty(choscodeInfoBean.getDepartment()) + && TextUtils.isEmpty(choscodeInfoBean.getZc())) {//部门不为null,职称为null tv_dept.setText(choscodeInfoBean.getDepartment()); - } else if (choscodeInfoBean.getDepartment().isEmpty() - && !choscodeInfoBean.getZc().isEmpty()) {//部门为null,职称不为null + } else if (TextUtils.isEmpty(choscodeInfoBean.getDepartment()) + && !TextUtils.isEmpty(choscodeInfoBean.getZc())) {//部门为null,职称不为null tv_dept.setText(choscodeInfoBean.getZc()); } //所属医院 tv_affiliation_hospital.setText("所属医院: " + choscodeInfoBean.getChosname()); tv_doctor_brief.setText("医生简介: " + choscodeInfoBean.getJj()); //医院等级 - if(!TextUtils.isEmpty(choscodeInfoBean.getLevelname())){ + if (!TextUtils.isEmpty(choscodeInfoBean.getLevelname())) { tv_grade.setVisibility(View.VISIBLE); tv_grade.setText(choscodeInfoBean.getLevelname()); - }else { + } else { tv_grade.setVisibility(View.GONE); } } else { @@ -138,4 +149,98 @@ public class DoctorDetailActivity extends BaseActivity { } }); } + + @Override + public void onClick(View view) { + if (view.getId() == R.id.lin_video) { + // 被叫用户 Id + String targetId = imAccount; + if(targetId.equals(CacheUtil.getImUserAccount())){ + ToastUtils.showShort("不能向自己发起视频"); + return; + } + + if (TextUtils.isEmpty(targetId)) { + ToastUtils.showShort("会话Id为空"); + } else { + XXPermissions.with(this) + // 申请单个权限 + .permission(Manifest.permission.CAMERA, Permission.RECORD_AUDIO) + // 设置权限请求拦截器(局部设置) + //.interceptor(new PermissionInterceptor()) + // 设置不触发错误检测机制(局部设置) + //.unchecked() + .request(new OnPermissionCallback() { + + @Override + public void onGranted(@NonNull List permissions, boolean all) { + if (!all) { +// toast("获取部分权限成功,但部分权限未正常授予"); + return; + } + if (checkCamera()) { + List pKeys = new ArrayList<>(); + pKeys.add(targetId); + EasyHttp.post(DoctorDetailActivity.this) + .api(new ApplyVideoApi(pKeys, "10001")) + .request(new OnHttpListener>>() { + @Override + public void onSucceed(ApiResponse> result) { + if (null != result.getData() && result.getData().isInnerRequestSucceed() && + null != result.getData().getData()) { + + VideoCallActivity.startActivity(DoctorDetailActivity.this, targetId, + result.getData().getData().getGroupID(), VideoCallActivity.CALL); + } else { + ToastUtils.showLong("发起视频失败"); + LogUtils.e("applyVideo失败", "数据解析失败"); + } + } + + @Override + public void onFail(Exception e) { + ToastUtils.showLong("发起视频失败"); + LogUtils.e("applyVideo失败", "失败:" + e); + } + + }); + + } + + } + + @Override + public void onDenied(@NonNull List permissions, boolean never) { + if (never) { + // 如果是被永久拒绝就跳转到应用权限系统设置页面 + XXPermissions.startPermissionActivity(DoctorDetailActivity.this, permissions); + } else { + Toast.makeText(DoctorDetailActivity.this, "权限获取失败", Toast.LENGTH_LONG).show(); + } + } + }); + } + + } + } + + public boolean checkCamera() { + CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); + try { + String[] cameraIds = cameraManager.getCameraIdList(); + if (cameraIds.length > 0) { + // 设备上存在摄像头 + return true; + } else { + // 设备上不存在摄像头 + ToastUtils.showLong("当前设备上不存在摄像头"); + return false; + } + } catch (CameraAccessException e) { + // 检测摄像头失败 + e.printStackTrace(); + ToastUtils.showLong("获取摄像头失败"); + return false; + } + } } diff --git a/app/src/main/java/com/unionmed/unionmedtv/activity/HomeActivity.java b/app/src/main/java/com/unionmed/unionmedtv/activity/HomeActivity.java index d1de2a5..9f0c502 100644 --- a/app/src/main/java/com/unionmed/unionmedtv/activity/HomeActivity.java +++ b/app/src/main/java/com/unionmed/unionmedtv/activity/HomeActivity.java @@ -3,6 +3,7 @@ package com.unionmed.unionmedtv.activity; import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.widget.ImageView; @@ -30,6 +31,8 @@ import com.unionmed.unionmedtv.widgets.ScaleConstraintLayout; import java.util.ArrayList; +import io.rong.imlib.RongIMClient; + public class HomeActivity extends BaseActivity implements View.OnFocusChangeListener, View.OnClickListener { private ViewPager2 mViewPager; private ArrayList fragments = new ArrayList<>(); @@ -39,6 +42,7 @@ public class HomeActivity extends BaseActivity implements View.OnFocusChangeList private ImageView iv_avatar; private TextView tv_name; private TextView tv_city; + private ImageView iv_msg; public static void StartActivity(Context context) { Intent intent = new Intent(context, HomeActivity.class); @@ -50,6 +54,7 @@ public class HomeActivity extends BaseActivity implements View.OnFocusChangeList super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); initView(); + imConnect(); } public void initView() { @@ -63,6 +68,8 @@ public class HomeActivity extends BaseActivity implements View.OnFocusChangeList cl_login.setOnClickListener(this); tv_city = findViewById(R.id.tv_city); tv_city.setOnClickListener(this); + iv_msg = findViewById(R.id.iv_msg); + iv_msg.setOnClickListener(this); tv_city.setText(CacheUtil.getIpAddress() == null ? "选择城市" : CacheUtil.getIpAddress().getMemo()); iv_avatar = findViewById(R.id.iv_avatar); Glide.with(this) @@ -99,6 +106,28 @@ public class HomeActivity extends BaseActivity implements View.OnFocusChangeList }); } + public void imConnect() { + String imToken = CacheUtil.getImTokenRong(); + RongIMClient.connect(imToken, new RongIMClient.ConnectCallback() { + + @Override + public void onSuccess(String t) { + Log.i("TAG", "onSuccess: 融云登录成功"); + } + + @Override + public void onError(RongIMClient.ConnectionErrorCode e) { + Log.i("TAG", "onSuccess: 融云登录失败======" + e); + } + + @Override + public void onDatabaseOpened(RongIMClient.DatabaseOpenStatus code) { + + } + }); + + } + @Override public void onFocusChange(View view, boolean b) { if (view.getId() == R.id.tv_my_doctor) { @@ -134,6 +163,8 @@ public class HomeActivity extends BaseActivity implements View.OnFocusChangeList })).show(); } else if (view.getId() == R.id.tv_city) { AddressSelectActivity.StartActivity(HomeActivity.this); + } else if (view.getId() == R.id.iv_msg) { + MsgActivity.StartActivity(HomeActivity.this); } } diff --git a/app/src/main/java/com/unionmed/unionmedtv/activity/MsgActivity.java b/app/src/main/java/com/unionmed/unionmedtv/activity/MsgActivity.java new file mode 100644 index 0000000..e89a9c0 --- /dev/null +++ b/app/src/main/java/com/unionmed/unionmedtv/activity/MsgActivity.java @@ -0,0 +1,101 @@ +package com.unionmed.unionmedtv.activity; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; +import androidx.fragment.app.FragmentTransaction; +import androidx.lifecycle.Observer; +import androidx.recyclerview.widget.RecyclerView; +import androidx.viewpager.widget.ViewPager; +import androidx.viewpager2.adapter.FragmentStateAdapter; +import androidx.viewpager2.widget.ViewPager2; + +import com.unionmed.unionmedtv.R; +import com.unionmed.unionmedtv.adapter.MsgListAdapter; +import com.unionmed.unionmedtv.adapter.SmartFragmentStatePagerAdapter; +import com.unionmed.unionmedtv.base.BaseActivity; +import com.unionmed.unionmedtv.fragment.MsgFragment; +import com.unionmed.unionmedtv.livedatas.LiveDataBus; +import com.unionmed.unionmedtv.utils.Constants; +import com.unionmed.unionmedtv.utils.MsgItemLinearLayoutManager; +import com.unionmed.unionmedtv.utils.MyLinearLayoutManager; +import com.unionmed.unionmedtv.utils.OnChildClickListener; +import com.unionmed.unionmedtv.widgets.TabViewPager; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +public class MsgActivity extends BaseActivity { + private RecyclerView recyclerView; + private MsgListAdapter msgListAdapter; + private List list = new ArrayList<>(); + private FrameLayout frameLayout; + private TextView tv_title; + private int lastSelectedPosition = 0; + + public static void StartActivity(Context context) { + Intent intent = new Intent(context, MsgActivity.class); + context.startActivity(intent); + } + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_msg); + initView(); + } + + public void initView() { + recyclerView = findViewById(R.id.recyclerView); + tv_title = findViewById(R.id.tv_title); + MyLinearLayoutManager myLinearLayoutManager = new MyLinearLayoutManager(MsgActivity.this); + recyclerView.setLayoutManager(myLinearLayoutManager); + list.add("通知"); + list.add("赵医生"); + list.add("陈医生"); + list.add("福建医科大学附属医院1"); + list.add("福建医科大学附属医院2"); + list.add("福建医科大学附属医院3"); + msgListAdapter = new MsgListAdapter(R.layout.item_msg_list_layout, list, new OnChildClickListener() { + @Override + public void onChildClick(View view, int position, T data) { + } + }); + recyclerView.setAdapter(msgListAdapter); + FragmentManager fragmentManager = getSupportFragmentManager(); + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + fragmentTransaction.replace(R.id.framelayout, new MsgFragment()); + fragmentTransaction.commit(); + + LiveDataBus.get().with(Constants.MSG_LIST_SELECT_ITEM, Integer.class).observe(this, new Observer() { + @Override + public void onChanged(Integer integer) { + lastSelectedPosition = integer; + msgListAdapter.setPostion(lastSelectedPosition); + msgListAdapter.notifyDataSetChanged(); + tv_title.setText(list.get(integer)); + LiveDataBus.get().with(Constants.MSG_REFRESH_ITEM).postValue(""); + } + }); + LiveDataBus.get().with(Constants.MSG_LIST_REFRESH_ITEM, String.class).observe(this, new Observer() { + @Override + public void onChanged(String str) { + View view = myLinearLayoutManager.findViewByPosition(lastSelectedPosition); + if (view != null) { + view.requestFocus(); + } + } + }); + } +} diff --git a/app/src/main/java/com/unionmed/unionmedtv/activity/VideoCallActivity.java b/app/src/main/java/com/unionmed/unionmedtv/activity/VideoCallActivity.java new file mode 100644 index 0000000..ff8119f --- /dev/null +++ b/app/src/main/java/com/unionmed/unionmedtv/activity/VideoCallActivity.java @@ -0,0 +1,580 @@ +package com.unionmed.unionmedtv.activity; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.text.TextUtils; +import android.util.Log; +import android.view.SurfaceView; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.Nullable; +import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.lifecycle.Observer; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.blankj.utilcode.util.LogUtils; +import com.blankj.utilcode.util.StringUtils; +import com.blankj.utilcode.util.ToastUtils; +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.hjq.http.EasyHttp; +import com.hjq.http.listener.OnHttpListener; +import com.unionmed.unionmedtv.R; +import com.unionmed.unionmedtv.adapter.RemoteAdapter; +import com.unionmed.unionmedtv.api.GetImUserInfoApi; +import com.unionmed.unionmedtv.base.BaseActivity; +import com.unionmed.unionmedtv.bean.ImUserInfoBean; +import com.unionmed.unionmedtv.bean.RemoteBean; +import com.unionmed.unionmedtv.bean.Video; +import com.unionmed.unionmedtv.livedatas.LiveDataBus; +import com.unionmed.unionmedtv.network.ApiResponse; +import com.unionmed.unionmedtv.utils.CacheUtil; +import com.unionmed.unionmedtv.utils.Constants; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import cn.rongcloud.rtc.api.stream.RCRTCVideoView; +import cn.rongcloud.rtc.core.RendererCommon; +import io.rong.calllib.IRongCallListener; +import io.rong.calllib.RongCallClient; +import io.rong.calllib.RongCallCommon; +import io.rong.calllib.RongCallSession; +import io.rong.imlib.RongIMClient; +import io.rong.imlib.model.Conversation; +import io.rong.imlib.model.UserInfo; + +public class VideoCallActivity extends BaseActivity implements View.OnClickListener { + /** + * @param context + * @param targetId + * @param type 1 呼叫者 0 被叫者 + */ + public static void startActivity(Context context, String targetId, String groupId, String type) { + Intent intent = new Intent(context, VideoCallActivity.class); + intent.putExtra("targetId", targetId); + intent.putExtra("type", type); + intent.putExtra("groupId", groupId); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } + + public static String CALL = "1";//1 呼叫者 + public static String CALLED = "0";//0 被叫者 + + private String targetId; + private String groupId; + private String type; + private LinearLayout lin_put_through;//接听 + private LinearLayout lin_hang_up;//挂断 + private LinearLayout lin_mute;//静音 + private LinearLayout lin_turn_off_camera;//关闭摄像头 + private ImageView iv_icon;//被叫者头像 + private TextView tv_name;//被叫者昵称 + private TextView tv_tip;// + private ImageView iv_camera;// + private ImageView iv_put_through;// + private ImageView iv_hang_up;// + private TextView tv_camera;// + private ImageView iv_mute;// + private TextView tv_mute;// + private TextView tv_time;//通话时长 + private FrameLayout local; + private RecyclerView recyclerView; + private RemoteAdapter remoteAdapter; + public static CallStatus currentStatus = CallStatus.Idle; + private UsetInfo usetInfo; + + public UsetInfo getUsetInfo() { + return usetInfo; + } + + public void setUsetInfo(UsetInfo usetInfo) { + this.usetInfo = usetInfo; + } + + private String imgPath = ""; + private String name = ""; + + /** + * idle 通话结束 + * Calling 电话拨出 + * BeCall 代接听 + * OnCall 已接通 + */ + public enum CallStatus { + Idle, + Calling, + BeCall, + OnCall + } + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_video_call); + local = findViewById(R.id.local); + iv_icon = findViewById(R.id.iv_icon); + tv_name = findViewById(R.id.tv_name); + tv_camera = findViewById(R.id.tv_camera); + iv_camera = findViewById(R.id.iv_camera); + iv_camera.setOnClickListener(this); + tv_mute = findViewById(R.id.tv_mute); + iv_mute = findViewById(R.id.iv_mute); + iv_mute.setOnClickListener(this); + iv_put_through = findViewById(R.id.iv_put_through); + iv_put_through.setOnClickListener(this); + iv_hang_up = findViewById(R.id.iv_hang_up); + iv_hang_up.setOnClickListener(this); + tv_tip = findViewById(R.id.tv_tip); + tv_time = findViewById(R.id.tv_time); + recyclerView = findViewById(R.id.recyclerView); + recyclerView.setLayoutManager(new LinearLayoutManager(VideoCallActivity.this)); + remoteAdapter = new RemoteAdapter(R.layout.item_remote_layout); + recyclerView.setAdapter(remoteAdapter); + lin_put_through = findViewById(R.id.lin_put_through); + lin_put_through.setOnClickListener(this); + lin_hang_up = findViewById(R.id.lin_hang_up); + lin_hang_up.setOnClickListener(this); + lin_mute = findViewById(R.id.lin_mute); + lin_mute.setOnClickListener(this); + lin_turn_off_camera = findViewById(R.id.lin_turn_off_camera); + lin_turn_off_camera.setOnClickListener(this); + lin_turn_off_camera.setSelected(true); + lin_mute.setSelected(true); + + initIRongCallListener(); + type =getIntent().getStringExtra("type"); + targetId = getIntent().getStringExtra("targetId"); + groupId = getIntent().getStringExtra("groupId"); + if(type.equals("1")){ + if (!TextUtils.isEmpty(targetId)) { + List userIds = new ArrayList<>(); + userIds.add(targetId); + RongCallClient.getInstance().startCall(Conversation.ConversationType.GROUP, groupId, + userIds, null, RongCallCommon.CallMediaType.VIDEO, null); + } + }else { + changeUi(null); + } + getUserInfoByServer(targetId); + } + private long time = 0; + Handler handler; + private void reckonByTime() { + handler = new Handler(); + Runnable updateTask = new Runnable() { + @Override + public void run() { + time++; + if (time >= 3600) { + tv_time.setText( + String.format( + "%d:%02d:%02d", time / 3600, (time % 3600) / 60, (time % 60))); + } else { + tv_time.setText(String.format("%02d:%02d", (time % 3600) / 60, (time % 60))); + } + + // 再次延迟执行任务 + handler.postDelayed(this, 1000); + } + }; +// 延迟执行任务 + handler.postDelayed(updateTask, 1000); + } + public void initIRongCallListener() { + RongCallClient.getInstance().setVoIPCallListener(new IRongCallListener() { + private void addLocalView(SurfaceView view) { + local.removeAllViews(); + local.addView(view); + } + + private void clearViews() { + local.removeAllViews(); + } + + /** + * 电话已拨出。 + * 主叫端拨出电话后,通过回调 onCallOutgoing 通知当前 call 的详细信息。 + * + * @param callSession 通话实体。 + * @param localVideo 本地 camera 信息。 + */ + @Override + public void onCallOutgoing(RongCallSession callSession, SurfaceView localVideo) { + Log.i("TAG", "onCallOutgoing: ================="+callSession.getActiveTime()); + currentStatus = CallStatus.Calling; + changeUi(null); + } + + /** + * 已建立通话。 + * 通话接通时,通过回调 onCallConnected 通知当前 call 的详细信息。 + * + * @param callSession 通话实体。 + * @param localVideo 本地 camera 信息。 + */ + @Override + public void onCallConnected(RongCallSession callSession, SurfaceView localVideo) { + reckonByTime(); + currentStatus = CallStatus.OnCall; + changeUi(null); + RemoteBean remoteBean = new RemoteBean(); + remoteBean.setUserId(targetId); + remoteBean.setSurfaceView(localVideo); + remoteAdapter.addData(remoteBean); + remoteBean.setPath(CacheUtil.getToken().getHeadImg()); + remoteBean.setName(CacheUtil.getToken().getName()); + } + + /** + * 通话结束。 + * 通话中,对方挂断,己方挂断,或者通话过程网络异常造成的通话中断,都会回调 onCallDisconnected。 + * + * @param callSession 通话实体。 + * @param reason 通话中断原因。 + */ + @Override + public void onCallDisconnected(RongCallSession callSession, RongCallCommon.CallDisconnectedReason reason) { + currentStatus = CallStatus.Idle; + changeUi(reason); + + } + + /** + * 被叫端正在振铃。 + * 主叫端拨出电话,被叫端收到请求,发出振铃响应时,回调 onRemoteUserRinging。 + * + * @param userId 振铃端用户 id。 + */ + @Override + public void onRemoteUserRinging(String userId) { + Log.i("TAG", "onRemoteUserRinging: =============" + userId); + + } + + @Override + public void onRemoteUserAccept(String userId, RongCallCommon.CallMediaType mediaType) { + + } + + /** + * 被叫端加入通话。 + * 主叫端拨出电话,被叫端收到请求后,加入通话,回调 onRemoteUserJoined。 + * + * @param userId 加入用户的 id。
+ * @param mediaType 加入用户的媒体类型,audio or video。
+ * @param userType 加入用户的类型,1:正常用户,2:观察者。
+ * @param remoteVideo 加入用户者的 camera 信息。如果 userType为2,remoteVideo对象为空;
+ * 如果对端调用{@link RongCallClient#startCall(int, boolean, Conversation.ConversationType, String, List, List, RongCallCommon.CallMediaType, String, StartCameraCallback)} 或 + * {@link RongCallClient#acceptCall(String, int, boolean, StartCameraCallback)}开始的音视频通话,则可以使用如下设置改变对端视频流的镜像显示:
+ *
+             *                                            public void onRemoteUserJoined(String userId, RongCallCommon.CallMediaType mediaType, int userType, SurfaceView remoteVideo) {
+             *                                                 if (null != remoteVideo) {
+             *                                                     ((RongRTCVideoView) remoteVideo).setMirror( boolean);//观看对方视频流是否镜像处理
+             *                                                 }
+             *                                            }
+             *                                            
+ */ + @Override + public void onRemoteUserJoined(String userId, RongCallCommon.CallMediaType mediaType, int userType, SurfaceView remoteVideo) { + getUserInfoByServer(userId); + setUsetInfo(new UsetInfo() { + @Override + public void success(ImUserInfoBean imUserInfoBean) { + if (userId.equals(targetId)) { + ((RCRTCVideoView)remoteVideo).setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL); + addLocalView(remoteVideo); + imgPath = imUserInfoBean.getHeadImg(); + name = imUserInfoBean.getName(); + } else { + RemoteBean remoteBean = new RemoteBean(); + remoteBean.setUserId(userId); + remoteBean.setSurfaceView(remoteVideo); + remoteAdapter.addData(remoteBean); + remoteBean.setPath(imUserInfoBean.getHeadImg()); + remoteBean.setName(imUserInfoBean.getName()); + } + } + + @Override + public void fail() { + if (userId.equals(targetId)) { + addLocalView(remoteVideo); + } else { + RemoteBean remoteBean = new RemoteBean(); + remoteBean.setUserId(userId); + remoteBean.setSurfaceView(remoteVideo); + remoteAdapter.addData(remoteBean); + } + } + }); + } + + @Override + public void onRemoteUserInvited(String userId, RongCallCommon.CallMediaType mediaType) { + Log.i("TAG", "onRemoteUserInvited: ================" + userId); + } + + /** + * 通话中的远端参与者离开。 + * 回调 onRemoteUserLeft 通知状态更新。 + * + * @param userId 远端参与者的 id。 + * @param reason 远端参与者离开原因。 + */ + @Override + public void onRemoteUserLeft(String userId, RongCallCommon.CallDisconnectedReason reason) { + Iterator iterator = remoteAdapter.getData().iterator(); + while (iterator.hasNext()) { + RemoteBean remoteBean = iterator.next(); + if (remoteBean.getUserId().equals(userId)) { + iterator.remove(); + } + ((FrameLayout) remoteBean.getView()).removeAllViews(); + } + remoteAdapter.notifyDataSetChanged(); + } + + @Override + public void onMediaTypeChanged(String userId, RongCallCommon.CallMediaType mediaType, SurfaceView video) { + + } + + @Override + public void onError(RongCallCommon.CallErrorCode errorCode) { + currentStatus = CallStatus.Idle; + finish(); + ToastUtils.showLong("通话出现错误了" + errorCode); + } + + @Override + public void onRemoteCameraDisabled(String userId, boolean disabled) { + if (userId.equals(targetId)) { + if (disabled) { + local.setVisibility(View.GONE); + iv_icon.setVisibility(View.VISIBLE); + Glide.with(VideoCallActivity.this) + .load(imgPath) + .apply(new RequestOptions() + .placeholder(R.mipmap.rc_default_portrait) + ) + .into(iv_icon); + } else { + local.setVisibility(View.VISIBLE); + iv_icon.setVisibility(View.GONE); + } + } else { + for (int i = 0; i < remoteAdapter.getData().size(); i++) { + if (remoteAdapter.getData().get(i).getUserId().equals(userId)) { + remoteAdapter.getData().get(i).setCameraDisabled(disabled); + } + } + remoteAdapter.notifyDataSetChanged(); + } + + } + + @Override + public void onRemoteMicrophoneDisabled(String userId, boolean disabled) { + + } + + @Override + public void onNetworkReceiveLost(String userId, int lossRate) { + + } + + @Override + public void onNetworkSendLost(int lossRate, int delay) { + + } + + @Override + public void onFirstRemoteVideoFrame(String userId, int height, int width) { + + } + + @Override + public void onAudioLevelSend(String audioLevel) { + + } + + @Override + public void onAudioLevelReceive(HashMap audioLevel) { + + } + + @Override + public void onRemoteUserPublishVideoStream(String userId, String streamId, String tag, SurfaceView surfaceView) { + + } + + @Override + public void onRemoteUserUnpublishVideoStream(String userId, String streamId, String tag) { + + } + }); + } + + private void changeUi(RongCallCommon.CallDisconnectedReason reason) { + if (CallStatus.Idle == currentStatus) {//通话结束 + + if (reason != null) { + String text = null; + switch (reason) { + case REMOTE_BUSY_LINE: + text = "对方忙,请稍后再试"; + break; + case REMOTE_CANCEL: + text = "对方已取消"; + break; + case REMOTE_REJECT: + text = "对方已拒绝"; + break; + case NO_RESPONSE: + text = "对方未接听"; + break; + case NETWORK_ERROR: + case HANGUP: + case REMOTE_HANGUP: + break; + } + if (!TextUtils.isEmpty(text)) { + ToastUtils.showLong(text); + } + } + finish(); + } else if (CallStatus.Calling == currentStatus) {//电话拨出 + iv_icon.setVisibility(View.VISIBLE); + tv_name.setVisibility(View.VISIBLE); + tv_tip.setVisibility(View.VISIBLE); + lin_hang_up.setVisibility(View.VISIBLE); + } else if (CallStatus.BeCall == currentStatus) {//等待接听 + iv_icon.setVisibility(View.VISIBLE); + tv_name.setVisibility(View.VISIBLE); + tv_tip.setVisibility(View.VISIBLE); + lin_hang_up.setVisibility(View.VISIBLE); + lin_put_through.setVisibility(View.VISIBLE); + lin_mute.setVisibility(View.VISIBLE); + lin_hang_up.setVisibility(View.VISIBLE); + } else if (CallStatus.OnCall == currentStatus) {//已接听 + iv_icon.setVisibility(View.GONE); + tv_name.setVisibility(View.GONE); + tv_tip.setVisibility(View.GONE); + lin_put_through.setVisibility(View.GONE); + lin_turn_off_camera.setVisibility(View.VISIBLE); + lin_mute.setVisibility(View.VISIBLE); + lin_hang_up.setVisibility(View.VISIBLE); + + } + } + + private interface UsetInfo { + void success(ImUserInfoBean imUserInfoBean); + + void fail(); + } + + //获取用户信息 + private void getUserInfoByServer(String userId) { + EasyHttp.post(VideoCallActivity.this) + .api(new GetImUserInfoApi(CacheUtil.getToken().getToken(), userId)) + .request(new OnHttpListener>>() { + @Override + public void onSucceed(ApiResponse> result) { + if (null != result.getData() && result.getData().isInnerRequestSucceed() + && null != result.getData().getData()) { + Glide.with(VideoCallActivity.this) + .load(result.getData().getData().getHeadImg()) + .apply(new RequestOptions() + .placeholder(R.color.white_e1e1e1) + ) + .into(iv_icon); + tv_name.setText(result.getData().getData().getName()); + if (type.equals("1")) { + tv_tip.setText("等待对方接听"); + } else { + tv_tip.setText("对方邀请您进行通话"); + } + if (usetInfo != null) { + usetInfo.success(result.getData().getData()); + } + } else { + if (usetInfo != null) { + usetInfo.fail(); + } + LogUtils.e("用户信息数据解析失败"); + } + } + + @Override + public void onFail(Exception e) { + LogUtils.e("用户信息失败", "失败:" + e); + } + }); + } + + @Override + public void onClick(View view) { + if (view.getId() == R.id.lin_put_through||view.getId()==R.id.iv_put_through) {//接听 + if (RongCallClient.getInstance() != null && RongCallClient.getInstance().getCallSession() != null) { + RongCallClient.getInstance().acceptCall(RongCallClient.getInstance().getCallSession().getCallId()); + } + } else if (view.getId() == R.id.lin_hang_up||view.getId()==R.id.iv_hang_up) {//挂断 + if (RongCallClient.getInstance() != null && RongCallClient.getInstance().getCallSession() != null) { + RongCallClient.getInstance().hangUpCall(RongCallClient.getInstance().getCallSession().getCallId()); + } + } else if (view.getId() == R.id.lin_mute || view.getId() == R.id.iv_mute) {//静音 + if (lin_mute.isSelected()) { + RongCallClient.getInstance().setEnableLocalAudio(false); + lin_mute.setSelected(false); + iv_mute.setImageDrawable(getResources().getDrawable(R.mipmap.icon_mute_off)); + tv_mute.setText("静音"); + + } else { + RongCallClient.getInstance().setEnableLocalAudio(true); + lin_mute.setSelected(true); + iv_mute.setImageDrawable(getResources().getDrawable(R.mipmap.icon_mute_on)); + tv_mute.setText("声音已开"); + } + } else if (view.getId() == R.id.lin_turn_off_camera || view.getId() == R.id.iv_camera) {//关闭摄像头 + if (lin_turn_off_camera.isSelected()) { + RongCallClient.getInstance().setEnableLocalVideo(false); + lin_turn_off_camera.setSelected(false); + iv_camera.setImageDrawable(getResources().getDrawable(R.mipmap.icon_camera_off)); + tv_camera.setText("摄像头已关"); + } else { + RongCallClient.getInstance().setEnableLocalVideo(true); + lin_turn_off_camera.setSelected(true); + iv_camera.setImageDrawable(getResources().getDrawable(R.mipmap.icon_camera_on)); + tv_camera.setText("摄像头已开"); + } + for (int i = 0; i < remoteAdapter.getData().size(); i++) { + if (remoteAdapter.getData().get(i).getUserId().equals(targetId)) { + remoteAdapter.getData().get(i).setCameraDisabled(!lin_turn_off_camera.isSelected()); + } + } + remoteAdapter.notifyDataSetChanged(); + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if(handler!=null){ + handler.removeCallbacksAndMessages(null); + } + } +} diff --git a/app/src/main/java/com/unionmed/unionmedtv/adapter/ContractedDoctorAdapter.java b/app/src/main/java/com/unionmed/unionmedtv/adapter/ContractedDoctorAdapter.java index f5a1256..b1288e1 100644 --- a/app/src/main/java/com/unionmed/unionmedtv/adapter/ContractedDoctorAdapter.java +++ b/app/src/main/java/com/unionmed/unionmedtv/adapter/ContractedDoctorAdapter.java @@ -56,18 +56,18 @@ public class ContractedDoctorAdapter extends BaseQuickAdapter { + private OnChildClickListener onChildClickListener; + + public MsgItemAdapter(@Nullable List data, OnChildClickListener onChildClickListener) { + super(data); + this.onChildClickListener = onChildClickListener; + setMultiTypeDelegate(new BaseMultiTypeDelegate() { + @Override + public int getItemType(@NotNull List data, int position) { + // 根据数据,自己判断应该返回的类型 + if (data.get(position).equals("1")) { + return 0; + } else if (data.get(position).equals("2")) { + return 1; + } else if (data.get(position).equals("3")) { + return 2; + } else if (data.get(position).equals("4")) { + return 3; + } else if (data.get(position).equals("5")) { + return 4; + } else if (data.get(position).equals("6")) { + return 5; + } else { + return 0; + } + } + }); + getMultiTypeDelegate() + .addItemType(0, R.layout.item_msg_text_left_layout) + .addItemType(1, R.layout.item_msg_text_right_layout) + .addItemType(2, R.layout.item_msg_image_left_layout) + .addItemType(3, R.layout.item_msg_image_right_layout) + .addItemType(4, R.layout.item_msg_order_left_layout) + .addItemType(5, R.layout.item_msg_order_right_layout); + } + + + @Override + protected void convert(@NotNull BaseViewHolder vh, String s) { + if (vh.getItemViewType() == 0) { + + } else if (vh.getItemViewType() == 2) { + ImageView iv_imag = vh.findView(R.id.iv_image); + Glide.with(getContext()) + .load("https://lmg.jj20.com/up/allimg/4k/s/02/210924233115O14-0-lp.jpg") + .apply(new RequestOptions() + .placeholder(R.color.white_e1e1e1) + ) + .into(iv_imag); + } +// TextView tv_content=vh.findView(R.id.tv_content); +// if(getContext() instanceof MsgActivity){ +// RecyclerView recyclerView=((MsgActivity) getContext()).findViewById(R.id.recyclerView); +// tv_content.setNextFocusLeftId(recyclerView.getId()); +// } + + vh.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + onChildClickListener.onChildClick(view, vh.getLayoutPosition(), s); + } + }); + + } +} diff --git a/app/src/main/java/com/unionmed/unionmedtv/adapter/MsgListAdapter.java b/app/src/main/java/com/unionmed/unionmedtv/adapter/MsgListAdapter.java new file mode 100644 index 0000000..6fb3c42 --- /dev/null +++ b/app/src/main/java/com/unionmed/unionmedtv/adapter/MsgListAdapter.java @@ -0,0 +1,67 @@ +package com.unionmed.unionmedtv.adapter; + +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.Nullable; +import androidx.constraintlayout.widget.ConstraintLayout; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.chad.library.adapter.base.BaseDelegateMultiAdapter; +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.delegate.BaseMultiTypeDelegate; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; +import com.unionmed.unionmedtv.R; +import com.unionmed.unionmedtv.api.GetNearDoctorApi; +import com.unionmed.unionmedtv.livedatas.LiveDataBus; +import com.unionmed.unionmedtv.utils.Constants; +import com.unionmed.unionmedtv.utils.OnChildClickListener; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class MsgListAdapter extends BaseQuickAdapter { + private OnChildClickListener onChildClickListener; + private int postion=0; + + public int getPostion() { + return postion; + } + + public void setPostion(int postion) { + this.postion = postion; + } + + public MsgListAdapter(int layoutResId, @Nullable List data, OnChildClickListener onChildClickListener) { + super(layoutResId, data); + this.onChildClickListener = onChildClickListener; + + } + + + @Override + protected void convert(@NotNull BaseViewHolder vh, String s) { + TextView tv_title = vh.findView(R.id.tv_title); + tv_title.setText(s); + ConstraintLayout constraintlayout=vh.findView(R.id.constraintlayout); + if(vh.getLayoutPosition()==postion){ + constraintlayout.setSelected(true); + constraintlayout.requestFocus(); + }else { + constraintlayout.setSelected(false); + constraintlayout.clearFocus(); + } + vh.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + onChildClickListener.onChildClick(view, vh.getLayoutPosition(), s); + } + }); + + } +} diff --git a/app/src/main/java/com/unionmed/unionmedtv/adapter/RemoteAdapter.java b/app/src/main/java/com/unionmed/unionmedtv/adapter/RemoteAdapter.java new file mode 100644 index 0000000..1336b36 --- /dev/null +++ b/app/src/main/java/com/unionmed/unionmedtv/adapter/RemoteAdapter.java @@ -0,0 +1,59 @@ +package com.unionmed.unionmedtv.adapter; + +import android.text.TextUtils; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.Nullable; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.chad.library.adapter.base.BaseDelegateMultiAdapter; +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.delegate.BaseMultiTypeDelegate; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; +import com.unionmed.unionmedtv.R; +import com.unionmed.unionmedtv.activity.VideoCallActivity; +import com.unionmed.unionmedtv.api.GetNearDoctorApi; +import com.unionmed.unionmedtv.bean.RemoteBean; +import com.unionmed.unionmedtv.utils.CacheUtil; +import com.unionmed.unionmedtv.utils.OnChildClickListener; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class RemoteAdapter extends BaseQuickAdapter { + private OnChildClickListener onChildClickListener; + + public RemoteAdapter(int layoutResId) { + super(layoutResId); + } + + + @Override + protected void convert(@NotNull BaseViewHolder vh, RemoteBean remoteBean) { + FrameLayout remote = vh.findView(R.id.remote); + ImageView iv_avatar = vh.findView(R.id.iv_avatar); + remoteBean.setView(remote); + remote.removeAllViews(); + remoteBean.getSurfaceView().setZOrderOnTop(true); + remote.addView(remoteBean.getSurfaceView()); + if (remoteBean.isCameraDisabled()) { + iv_avatar.setVisibility(View.VISIBLE); + remote.setVisibility(View.GONE); + } else { + iv_avatar.setVisibility(View.GONE); + remote.setVisibility(View.VISIBLE); + Glide.with(getContext()) + .load(remoteBean.getPath()) + .apply(new RequestOptions() + .placeholder(R.mipmap.rc_default_portrait) + ) + .into(iv_avatar); + } + } + +} diff --git a/app/src/main/java/com/unionmed/unionmedtv/adapter/SmartFragmentStatePagerAdapter.java b/app/src/main/java/com/unionmed/unionmedtv/adapter/SmartFragmentStatePagerAdapter.java index 002c668..23b6af2 100644 --- a/app/src/main/java/com/unionmed/unionmedtv/adapter/SmartFragmentStatePagerAdapter.java +++ b/app/src/main/java/com/unionmed/unionmedtv/adapter/SmartFragmentStatePagerAdapter.java @@ -14,7 +14,7 @@ public abstract class SmartFragmentStatePagerAdapter extends FragmentStatePagerA private static final String TAG = "SmartSVodContent"; private SparseArray registeredFragments = new SparseArray<>(); - SmartFragmentStatePagerAdapter(FragmentManager fragmentManager) { + public SmartFragmentStatePagerAdapter(FragmentManager fragmentManager) { super(fragmentManager); } diff --git a/app/src/main/java/com/unionmed/unionmedtv/api/ApplyVideoApi.java b/app/src/main/java/com/unionmed/unionmedtv/api/ApplyVideoApi.java new file mode 100644 index 0000000..9746882 --- /dev/null +++ b/app/src/main/java/com/unionmed/unionmedtv/api/ApplyVideoApi.java @@ -0,0 +1,314 @@ +package com.unionmed.unionmedtv.api; + +import androidx.annotation.NonNull; + +import com.hjq.http.config.IRequestApi; +import com.hjq.http.config.IRequestType; +import com.hjq.http.model.BodyType; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + + +public class ApplyVideoApi implements IRequestApi , IRequestType { + @NonNull + @NotNull + @Override + public String getApi() { + return "/message/applyVideo"; + } + + + private List pkeys; + private String type; + public ApplyVideoApi(List pkeys, String type) { + this.pkeys = pkeys; + this.type = type; + } + + + @NonNull + @NotNull + @Override + public BodyType getBodyType() { + return BodyType.JSON; + } + + public class ApplyVideoModel{ + + private String createTime; + private FromBean from; + private String groupID; + private String groupName; + private String to; + private String type; + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public FromBean getFrom() { + return from; + } + + public void setFrom(FromBean from) { + this.from = from; + } + + public String getGroupID() { + return groupID; + } + + public void setGroupID(String groupID) { + this.groupID = groupID; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public String getTo() { + return to; + } + + public void setTo(String to) { + this.to = to; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public class FromBean { + private String bank_authentication; + private String code_validity; + private String create_date; + private String delete_date; + private String freeconsultation; + private String identity_id; + private String im_password; + private String im_useraccount; + private Integer isdelete; + private Integer isdevelopment; + private Integer isuse; + private String login_name; + private String media_id; + private String mobile; + private String name; + private String password; + private String pay_password; + private String personid; + private String photo_url; + private Integer pkey; + private String preRegion; + private String update_date; + private String upkey; + private String zt; + + public String getBank_authentication() { + return bank_authentication; + } + + public void setBank_authentication(String bank_authentication) { + this.bank_authentication = bank_authentication; + } + + public String getCode_validity() { + return code_validity; + } + + public void setCode_validity(String code_validity) { + this.code_validity = code_validity; + } + + public String getCreate_date() { + return create_date; + } + + public void setCreate_date(String create_date) { + this.create_date = create_date; + } + + public String getDelete_date() { + return delete_date; + } + + public void setDelete_date(String delete_date) { + this.delete_date = delete_date; + } + + public String getFreeconsultation() { + return freeconsultation; + } + + public void setFreeconsultation(String freeconsultation) { + this.freeconsultation = freeconsultation; + } + + public String getIdentity_id() { + return identity_id; + } + + public void setIdentity_id(String identity_id) { + this.identity_id = identity_id; + } + + public String getIm_password() { + return im_password; + } + + public void setIm_password(String im_password) { + this.im_password = im_password; + } + + public String getIm_useraccount() { + return im_useraccount; + } + + public void setIm_useraccount(String im_useraccount) { + this.im_useraccount = im_useraccount; + } + + public Integer getIsdelete() { + return isdelete; + } + + public void setIsdelete(Integer isdelete) { + this.isdelete = isdelete; + } + + public Integer getIsdevelopment() { + return isdevelopment; + } + + public void setIsdevelopment(Integer isdevelopment) { + this.isdevelopment = isdevelopment; + } + + public Integer getIsuse() { + return isuse; + } + + public void setIsuse(Integer isuse) { + this.isuse = isuse; + } + + public String getLogin_name() { + return login_name; + } + + public void setLogin_name(String login_name) { + this.login_name = login_name; + } + + public String getMedia_id() { + return media_id; + } + + public void setMedia_id(String media_id) { + this.media_id = media_id; + } + + public String getMobile() { + return mobile; + } + + public void setMobile(String mobile) { + this.mobile = mobile; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPay_password() { + return pay_password; + } + + public void setPay_password(String pay_password) { + this.pay_password = pay_password; + } + + public String getPersonid() { + return personid; + } + + public void setPersonid(String personid) { + this.personid = personid; + } + + public String getPhoto_url() { + return photo_url; + } + + public void setPhoto_url(String photo_url) { + this.photo_url = photo_url; + } + + public Integer getPkey() { + return pkey; + } + + public void setPkey(Integer pkey) { + this.pkey = pkey; + } + + public String getPreRegion() { + return preRegion; + } + + public void setPreRegion(String preRegion) { + this.preRegion = preRegion; + } + + public String getUpdate_date() { + return update_date; + } + + public void setUpdate_date(String update_date) { + this.update_date = update_date; + } + + public String getUpkey() { + return upkey; + } + + public void setUpkey(String upkey) { + this.upkey = upkey; + } + + public String getZt() { + return zt; + } + + public void setZt(String zt) { + this.zt = zt; + } + } + } +} diff --git a/app/src/main/java/com/unionmed/unionmedtv/api/GetImUserInfoApi.java b/app/src/main/java/com/unionmed/unionmedtv/api/GetImUserInfoApi.java new file mode 100644 index 0000000..a2d9ec8 --- /dev/null +++ b/app/src/main/java/com/unionmed/unionmedtv/api/GetImUserInfoApi.java @@ -0,0 +1,36 @@ +package com.unionmed.unionmedtv.api; + +import androidx.annotation.NonNull; + +import com.hjq.http.annotation.HttpHeader; +import com.hjq.http.config.IRequestApi; +import com.hjq.http.config.IRequestType; +import com.hjq.http.model.BodyType; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + + +public class GetImUserInfoApi implements IRequestApi, IRequestType { + @NonNull + @NotNull + @Override + public String getApi() { + return "/index/getUserInfoByImaccount"; + } + + @HttpHeader + private String token; + private String imaccount; + public GetImUserInfoApi(String token, String imaccount) { + this.token = token; + this.imaccount = imaccount; + } + @NonNull + @Override + public BodyType getBodyType() { + return BodyType.JSON; + } + +} diff --git a/app/src/main/java/com/unionmed/unionmedtv/api/GetNearDoctorApi.java b/app/src/main/java/com/unionmed/unionmedtv/api/GetNearDoctorApi.java index 53d2c3c..a9719fe 100644 --- a/app/src/main/java/com/unionmed/unionmedtv/api/GetNearDoctorApi.java +++ b/app/src/main/java/com/unionmed/unionmedtv/api/GetNearDoctorApi.java @@ -29,8 +29,8 @@ public final class GetNearDoctorApi implements IRequestApi, IRequestType { private String area; private String name; - private String f_num; - private String e_num; + private String page; + private String rows; private String choscode; private String longitude; private String latitude; @@ -38,12 +38,12 @@ public final class GetNearDoctorApi implements IRequestApi, IRequestType { private String type; - public GetNearDoctorApi(String area, String name, String f_num, String e_num, String choscode, + public GetNearDoctorApi(String area, String name, String page, String rows, String choscode, String longitude, String latitude, String pkey, String type) { this.area = area; this.name = name; - this.f_num = f_num; - this.e_num = e_num; + this.page = page; + this.rows = rows; this.choscode = choscode; this.longitude = longitude; this.latitude = latitude; diff --git a/app/src/main/java/com/unionmed/unionmedtv/application/MyApplication.java b/app/src/main/java/com/unionmed/unionmedtv/application/MyApplication.java index 98f21bf..06f5d33 100644 --- a/app/src/main/java/com/unionmed/unionmedtv/application/MyApplication.java +++ b/app/src/main/java/com/unionmed/unionmedtv/application/MyApplication.java @@ -2,6 +2,8 @@ package com.unionmed.unionmedtv.application; import android.app.Application; import android.content.Context; +import android.util.Log; +import android.view.SurfaceView; import android.view.View; import com.scwang.smart.refresh.footer.ClassicsFooter; @@ -14,12 +16,34 @@ import com.scwang.smart.refresh.layout.listener.DefaultRefreshFooterCreator; import com.scwang.smart.refresh.layout.listener.DefaultRefreshHeaderCreator; import com.tencent.mmkv.MMKV; import com.unionmed.unionmedtv.R; +import com.unionmed.unionmedtv.activity.VideoCallActivity; +import com.unionmed.unionmedtv.livedatas.LiveDataBus; import com.unionmed.unionmedtv.network.RequestHandler; import com.unionmed.unionmedtv.network.RequestServer; import com.hjq.http.EasyConfig; import com.tencent.bugly.crashreport.CrashReport; -import com.unionmed.unionmedtv.utils.CacheUtil; +import com.unionmed.unionmedtv.utils.Constants; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.HashMap; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import io.rong.calllib.IRongCallListener; +import io.rong.calllib.IRongReceivedCallListener; +import io.rong.calllib.RongCallClient; +import io.rong.calllib.RongCallCommon; +import io.rong.calllib.RongCallMissedListener; +import io.rong.calllib.RongCallSession; +import io.rong.common.utils.SSLUtils; +import io.rong.imlib.RongIMClient; import okhttp3.OkHttpClient; public class MyApplication extends Application { @@ -35,16 +59,101 @@ public class MyApplication extends Application { .setServer(new RequestServer()) // 设置请求处理策略 .setHandler(new RequestHandler(this)) - .addHeader("client","IPTV") + .addHeader("client", "IPTV") // 添加全局请求参数 //.addParam("token", "6666666") // 添加全局请求头 .addHeader("Content-Type", "application/json;charset=UTF-8") .into(); + setSSL_Rong(); + //初始化im + initRong(); + } + private SSLContext mySSLContext; + //融云一定需要配置【顺序不能 乱】 + private void setSSL_Rong() { + try { + TrustManager tm[] = { + new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + Log.d("checkClientTrusted", "authType:" + authType); + } + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + Log.d("checkServerTrusted", "authType:" + authType); + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + } + }; + mySSLContext = SSLContext.getInstance("TLS"); + mySSLContext.init(null, tm, null); + } catch (KeyManagementException | NoSuchAlgorithmException e) { + e.printStackTrace(); + } + SSLUtils.setSSLContext(mySSLContext); + SSLUtils.setHostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }); } + + private void initRong() { + //配置融云私有化地址 + RongIMClient.setServerInfo("https://mini.union-med.net:1444", "https://mini.union-med.net:1446"); + + //Im 初始化 + String appKey = "tdrvipp1mc4b5"; + RongIMClient.init(this, appKey, false); + Log.i("TAG", "initRong: ==================="+RongCallClient.getInstance()); + //监听通话呼入 + RongCallClient.setReceivedCallListener(new IRongReceivedCallListener() { + /** + * 来电回调 + * @param callSession 通话实体 + */ + @Override + public void onReceivedCall(RongCallSession callSession) { + VideoCallActivity.currentStatus=VideoCallActivity.CallStatus.BeCall; + VideoCallActivity.startActivity(getApplicationContext(),callSession.getInviterUserId(),"",VideoCallActivity.CALLED); + } + + /** + * targetSDKVersion 大于等于 23 时检查权限的回调。当 targetSDKVersion 小于 23 的时候不需要实现。 + * 在这个回调里用户需要使用Android6.0新增的动态权限分配接口通知用户授权, + * 然后根据用户授权或者不授权分别回调 + * RongCallClient.getInstance().onPermissionGranted()和 + * RongCallClient.getInstance().onPermissionDenied()来通知CallLib。 + * + * @param callSession 通话实体 + */ + @Override + public void onCheckPermission(RongCallSession callSession) { + } + }); + +//监听漏接电话 + RongCallClient.setMissedCallListener(new RongCallMissedListener() { + /** + * 漏接通话回调 + * @param callSession 通话实体 + * @param reason 远端参与者离开原因。 + */ + @Override + public void onRongCallMissed(RongCallSession callSession, RongCallCommon.CallDisconnectedReason reason) { + } + }); + } + static { //设置全局的Header构建器 SmartRefreshLayout.setDefaultRefreshHeaderCreator(new DefaultRefreshHeaderCreator() { diff --git a/app/src/main/java/com/unionmed/unionmedtv/bean/ImUserInfoBean.java b/app/src/main/java/com/unionmed/unionmedtv/bean/ImUserInfoBean.java new file mode 100644 index 0000000..7b544ce --- /dev/null +++ b/app/src/main/java/com/unionmed/unionmedtv/bean/ImUserInfoBean.java @@ -0,0 +1,154 @@ +package com.unionmed.unionmedtv.bean; + +public class ImUserInfoBean { + /*{ + "name": "谢航宇", + "headImg": "http://47.118.51.167:9000/appheadimg/appheadimg_1622108669577.jpg", + "mobile": "17720718419", + "preRegion": null, + "isAtuh": "1", + "upkey": "7", + "pkey": null, + "identity_id": null, + "isSetPsw": null, + "im_useraccount": "717720718419", + "im_password": null, + "currentAddress": null + userType:100-系统,200-医院,300-用户 + }*/ + private String name; + private String headImg; + private String mobile; + private Object preRegion; + private String isAtuh; + private String upkey; + private Object pkey; + private Object identity_id; + private Object isSetPsw; + private String im_useraccount; + private Object im_password; + private Object currentAddress; + private String userType; + private String isuse;//1账号可用,0账号已注销 + private String online; + + public String getOnline() { + return online; + } + + public void setOnline(String online) { + this.online = online; + } + + public String getIsuse() { + return isuse; + } + + public void setIsuse(String isuse) { + this.isuse = isuse; + } + + public String getUserType() { + return userType; + } + + public void setUserType(String userType) { + this.userType = userType; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getHeadImg() { + return headImg; + } + + public void setHeadImg(String headImg) { + this.headImg = headImg; + } + + public String getMobile() { + return mobile; + } + + public void setMobile(String mobile) { + this.mobile = mobile; + } + + public Object getPreRegion() { + return preRegion; + } + + public void setPreRegion(Object preRegion) { + this.preRegion = preRegion; + } + + public String getIsAtuh() { + return isAtuh; + } + + public void setIsAtuh(String isAtuh) { + this.isAtuh = isAtuh; + } + + public String getUpkey() { + return upkey; + } + + public void setUpkey(String upkey) { + this.upkey = upkey; + } + + public Object getPkey() { + return pkey; + } + + public void setPkey(Object pkey) { + this.pkey = pkey; + } + + public Object getIdentity_id() { + return identity_id; + } + + public void setIdentity_id(Object identity_id) { + this.identity_id = identity_id; + } + + public Object getIsSetPsw() { + return isSetPsw; + } + + public void setIsSetPsw(Object isSetPsw) { + this.isSetPsw = isSetPsw; + } + + public String getIm_useraccount() { + return im_useraccount; + } + + public void setIm_useraccount(String im_useraccount) { + this.im_useraccount = im_useraccount; + } + + public Object getIm_password() { + return im_password; + } + + public void setIm_password(Object im_password) { + this.im_password = im_password; + } + + public Object getCurrentAddress() { + return currentAddress; + } + + public void setCurrentAddress(Object currentAddress) { + this.currentAddress = currentAddress; + } +} diff --git a/app/src/main/java/com/unionmed/unionmedtv/bean/RemoteBean.java b/app/src/main/java/com/unionmed/unionmedtv/bean/RemoteBean.java new file mode 100644 index 0000000..6a89cb0 --- /dev/null +++ b/app/src/main/java/com/unionmed/unionmedtv/bean/RemoteBean.java @@ -0,0 +1,63 @@ +package com.unionmed.unionmedtv.bean; + + +import android.view.SurfaceView; +import android.view.View; + +public class RemoteBean{ + private String userId; + private SurfaceView surfaceView; + private String path;//用户头像 + private String name;//用户名称 + private View view; + + public View getView() { + return view; + } + + public void setView(View view) { + this.view = view; + } + + private boolean cameraDisabled=false;//摄像头是否关闭 + + public boolean isCameraDisabled() { + return cameraDisabled; + } + + public void setCameraDisabled(boolean cameraDisabled) { + this.cameraDisabled = cameraDisabled; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public SurfaceView getSurfaceView() { + return surfaceView; + } + + public void setSurfaceView(SurfaceView surfaceView) { + this.surfaceView = surfaceView; + } +} diff --git a/app/src/main/java/com/unionmed/unionmedtv/bean/TokenBean.java b/app/src/main/java/com/unionmed/unionmedtv/bean/TokenBean.java index 10c80bb..8cc842a 100644 --- a/app/src/main/java/com/unionmed/unionmedtv/bean/TokenBean.java +++ b/app/src/main/java/com/unionmed/unionmedtv/bean/TokenBean.java @@ -28,7 +28,7 @@ public class TokenBean { */ private String name; - private Object headImg; + private String headImg; private String mobile; private City preRegion; private String isAtuh;//1认证成功 0需要认证 @@ -54,11 +54,11 @@ public class TokenBean { this.name = name; } - public Object getHeadImg() { + public String getHeadImg() { return headImg; } - public void setHeadImg(Object headImg) { + public void setHeadImg(String headImg) { this.headImg = headImg; } diff --git a/app/src/main/java/com/unionmed/unionmedtv/fragment/MsgFragment.java b/app/src/main/java/com/unionmed/unionmedtv/fragment/MsgFragment.java new file mode 100644 index 0000000..5ee257d --- /dev/null +++ b/app/src/main/java/com/unionmed/unionmedtv/fragment/MsgFragment.java @@ -0,0 +1,122 @@ +package com.unionmed.unionmedtv.fragment; + +import android.os.Bundle; +import android.os.Handler; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.fragment.app.Fragment; +import androidx.lifecycle.Observer; +import androidx.recyclerview.widget.RecyclerView; + +import com.blankj.utilcode.util.ToastUtils; +import com.example.yideng.loaddialoglibrary.LmiotDialog; +import com.unionmed.unionmedtv.R; +import com.unionmed.unionmedtv.activity.DoctorActivity; +import com.unionmed.unionmedtv.adapter.MsgItemAdapter; +import com.unionmed.unionmedtv.livedatas.LiveDataBus; +import com.unionmed.unionmedtv.utils.Constants; +import com.unionmed.unionmedtv.utils.LinearSpacingItemDecoration; +import com.unionmed.unionmedtv.utils.MsgItemLinearLayoutManager; +import com.unionmed.unionmedtv.utils.OnChildClickListener; + +import java.util.ArrayList; +import java.util.List; + + +public class MsgFragment extends Fragment implements View.OnClickListener { + private RecyclerView recyclerView; + private MsgItemAdapter msgItemAdapter; + private List list = new ArrayList<>(); + private LinearLayout lin; + private TextView tv_look; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_msg, container, false); + recyclerView = view.findViewById(R.id.recyclerView); + lin = view.findViewById(R.id.lin); + tv_look = view.findViewById(R.id.tv_look); + tv_look.setOnClickListener(this); + tv_look.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View view, boolean b) { + if (b == false) { + LiveDataBus.get().with(Constants.MSG_LIST_REFRESH_ITEM).postValue(""); + } + } + }); + MsgItemLinearLayoutManager msgItemLinearLayoutManager = new MsgItemLinearLayoutManager(getActivity()); + msgItemLinearLayoutManager.setLeftView(getActivity().findViewById(R.id.recyclerView)); + msgItemLinearLayoutManager.setRecyclerView(recyclerView); + recyclerView.setLayoutManager(msgItemLinearLayoutManager); + recyclerView.addItemDecoration(new LinearSpacingItemDecoration(getActivity(), 14)); + list.clear(); + list.add("1"); + list.add("2"); + list.add("3"); + list.add("4"); + list.add("5"); + list.add("6"); + msgItemAdapter = new MsgItemAdapter(list, new OnChildClickListener() { + @Override + public void onChildClick(View view, int position, T data) { + + } + }); + recyclerView.setAdapter(msgItemAdapter); + if (list.size() > 0) { + recyclerView.smoothScrollToPosition(list.size() - 1); + } + LiveDataBus.get().with(Constants.MSG_SELECT_ITEM, Integer.class).observe(getActivity(), new Observer() { + @Override + public void onChanged(Integer integer) { + recyclerView.clearFocus(); + if (recyclerView.getVisibility() == View.VISIBLE) { + msgItemLinearLayoutManager.scrollToPosition(list.size() - 1); + recyclerView.post(new Runnable() { + @Override + public void run() { + if (msgItemLinearLayoutManager.getItemCount() > 0) { + int pos = msgItemLinearLayoutManager.findLastVisibleItemPosition(); + recyclerView.smoothScrollToPosition(pos); + View selectView = msgItemLinearLayoutManager.findViewByPosition(pos); + if (selectView != null) { + selectView.requestFocus(); + }else { + recyclerView.requestFocus(); + } + } else { + LiveDataBus.get().with(Constants.MSG_LIST_REFRESH_ITEM).postValue(""); + } + } + }); + } + } + }); + //刷新页面聊天数据 + LiveDataBus.get().with(Constants.MSG_REFRESH_ITEM, String.class).observe(getActivity(), new Observer() { + @Override + public void onChanged(String s) { + lin.setVisibility(View.VISIBLE); + recyclerView.setVisibility(View.GONE); +// LmiotDialog.show(getActivity()); + } + }); + return view; + } + + @Override + public void onClick(View view) { + if (view.getId() == R.id.tv_look) { + lin.setVisibility(View.GONE); + lin.clearFocus(); + recyclerView.setVisibility(View.VISIBLE); + recyclerView.clearFocus(); + LiveDataBus.get().with(Constants.MSG_SELECT_ITEM).postValue(0); + } + } +} diff --git a/app/src/main/java/com/unionmed/unionmedtv/fragment/MyDoctorFragment.java b/app/src/main/java/com/unionmed/unionmedtv/fragment/MyDoctorFragment.java index c9a6246..2c252d6 100644 --- a/app/src/main/java/com/unionmed/unionmedtv/fragment/MyDoctorFragment.java +++ b/app/src/main/java/com/unionmed/unionmedtv/fragment/MyDoctorFragment.java @@ -22,6 +22,7 @@ import com.unionmed.unionmedtv.activity.DoctorDetailActivity; import com.unionmed.unionmedtv.activity.DoctorActivity; import com.unionmed.unionmedtv.activity.HospitalActivity; import com.unionmed.unionmedtv.activity.HospitalDetailActivity; +import com.unionmed.unionmedtv.activity.MsgActivity; import com.unionmed.unionmedtv.adapter.ContractedDoctorAdapter; import com.unionmed.unionmedtv.adapter.DoctorAdapter; import com.unionmed.unionmedtv.api.GetContractedDoctorApi; @@ -67,6 +68,7 @@ public class MyDoctorFragment extends Fragment implements View.OnClickListener { @Override public void onChildClick(View view, int position, T data) { selectPostion = position; +// MsgActivity.StartActivity(getActivity()); GetContractedDoctorApi.DoctorInfo.MemberBean memberBean = (GetContractedDoctorApi.DoctorInfo.MemberBean) data; DoctorDetailActivity.StartActivity(getActivity(), memberBean.getPersoninfo().get(0).getUseraccount()); } diff --git a/app/src/main/java/com/unionmed/unionmedtv/login/activity/fragment/LoginPhoneFragment.java b/app/src/main/java/com/unionmed/unionmedtv/login/activity/fragment/LoginPhoneFragment.java index ac0a91a..9fa2ed9 100644 --- a/app/src/main/java/com/unionmed/unionmedtv/login/activity/fragment/LoginPhoneFragment.java +++ b/app/src/main/java/com/unionmed/unionmedtv/login/activity/fragment/LoginPhoneFragment.java @@ -187,6 +187,7 @@ public class LoginPhoneFragment extends Fragment implements View.OnClickListener tokenBean.getName(), tokenBean.getPreRegion().getPkey()); } else { + LmiotDialog.hidden(); CacheUtil.setToken(null); new XPopup.Builder(getActivity()).isRequestFocus(true) .asCustom(new TipDialog(getActivity(), "请先前往手机app进行实名认证,认证成功后才可登录", new TipDialog.DialogClick() { diff --git a/app/src/main/java/com/unionmed/unionmedtv/presenter/TypeDoctorPresenter.java b/app/src/main/java/com/unionmed/unionmedtv/presenter/TypeDoctorPresenter.java index f75e312..a4d4aae 100644 --- a/app/src/main/java/com/unionmed/unionmedtv/presenter/TypeDoctorPresenter.java +++ b/app/src/main/java/com/unionmed/unionmedtv/presenter/TypeDoctorPresenter.java @@ -59,18 +59,18 @@ public class TypeDoctorPresenter extends Presenter { vh.tv_name.setText(memberBean.getName()); if (!memberBean.getPersoninfo().isEmpty()) { - if (!memberBean.getPersoninfo().get(0).getDepartment().isEmpty() - && !memberBean.getPersoninfo().get(0).getZc().isEmpty()) {//部门职称都不为null + if (!TextUtils.isEmpty(memberBean.getPersoninfo().get(0).getDepartment()) + && !TextUtils.isEmpty(memberBean.getPersoninfo().get(0).getZc())) {//部门职称都不为null vh.tv_dept.setText(memberBean.getPersoninfo().get(0).getDepartment() + " | " + memberBean.getPersoninfo().get(0).getZc()); - } else if (memberBean.getPersoninfo().get(0).getDepartment().isEmpty() - && memberBean.getPersoninfo().get(0).getZc().isEmpty()) {//部门职称都为null + } else if (TextUtils.isEmpty(memberBean.getPersoninfo().get(0).getDepartment()) + && TextUtils.isEmpty(memberBean.getPersoninfo().get(0).getZc())) {//部门职称都为null vh.tv_dept.setText("- -"); - } else if (!memberBean.getPersoninfo().get(0).getDepartment().isEmpty() - && memberBean.getPersoninfo().get(0).getZc().isEmpty()) {//部门不为null,职称为null + } else if (!TextUtils.isEmpty(memberBean.getPersoninfo().get(0).getDepartment()) + && TextUtils.isEmpty(memberBean.getPersoninfo().get(0).getZc())) {//部门不为null,职称为null vh.tv_dept.setText(memberBean.getPersoninfo().get(0).getDepartment()); - } else if (memberBean.getPersoninfo().get(0).getDepartment().isEmpty() - && !memberBean.getPersoninfo().get(0).getZc().isEmpty()) {//部门为null,职称不为null + } else if (TextUtils.isEmpty(memberBean.getPersoninfo().get(0).getDepartment()) + && !TextUtils.isEmpty(memberBean.getPersoninfo().get(0).getZc())) {//部门为null,职称不为null vh.tv_dept.setText(memberBean.getPersoninfo().get(0).getZc()); } diff --git a/app/src/main/java/com/unionmed/unionmedtv/utils/Constants.java b/app/src/main/java/com/unionmed/unionmedtv/utils/Constants.java index 8981b79..90198a1 100644 --- a/app/src/main/java/com/unionmed/unionmedtv/utils/Constants.java +++ b/app/src/main/java/com/unionmed/unionmedtv/utils/Constants.java @@ -28,5 +28,10 @@ public class Constants { public static final int DEFAULT_ERROR_VALUE = -1; public static final String CITY_SELECT = "city_select"; public static final String EXIT_LOGIN = "exit_login"; + public static final String MSG_LIST_SELECT_ITEM = "msg_list_select_item";//聊天列表选中 + public static final String MSG_SELECT_ITEM = "msg_select_item";//聊天消息选中 + public static final String MSG_LIST_REFRESH_ITEM = "msg_list_refresh_item";//从聊天消息页回到聊天列表 + public static final String MSG_REFRESH_ITEM = "msg_refresh_item";//刷新聊天消息数据 + public static final String BE_CALL = "be_call";//收到来电 } diff --git a/app/src/main/java/com/unionmed/unionmedtv/utils/MsgItemLinearLayoutManager.java b/app/src/main/java/com/unionmed/unionmedtv/utils/MsgItemLinearLayoutManager.java new file mode 100644 index 0000000..2613fec --- /dev/null +++ b/app/src/main/java/com/unionmed/unionmedtv/utils/MsgItemLinearLayoutManager.java @@ -0,0 +1,96 @@ +package com.unionmed.unionmedtv.utils; + +import android.content.Context; +import android.os.Build; +import android.util.AttributeSet; +import android.view.View; + +import androidx.annotation.RequiresApi; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.unionmed.unionmedtv.livedatas.LiveDataBus; + +/** + * NAME:YONG_ + * Created at: 2019/4/30 + * Describe: 防止RecyclerView快速移动焦点跑飞 + */ +public class MsgItemLinearLayoutManager extends LinearLayoutManager { + private RecyclerView recyclerView; + private View leftView; + + public RecyclerView getRecyclerView() { + return recyclerView; + } + + public void setRecyclerView(RecyclerView recyclerView) { + this.recyclerView = recyclerView; + } + + public View getLeftView() { + return leftView; + } + + public void setLeftView(View leftView) { + this.leftView = leftView; + } + + public MsgItemLinearLayoutManager(Context context) { + super(context); + } + + public MsgItemLinearLayoutManager(Context context, int orientation, boolean reverseLayout) { + super(context, orientation, reverseLayout); + } + + public MsgItemLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + + @Override + public View onInterceptFocusSearch(View focused, int direction) { + int currentPosition = getPosition(getFocusedChild()); + switch (direction) { + case View.FOCUS_DOWN: + if (currentPosition != getItemCount() - 1) { + if(recyclerView!=null){ + recyclerView.smoothScrollToPosition(currentPosition + 1); + } + return findViewByPosition(currentPosition + 1); + } else { + if(recyclerView!=null){ + recyclerView.smoothScrollToPosition(currentPosition); + } + return findViewByPosition(currentPosition); + } + case View.FOCUS_UP: + if (currentPosition != 0) { + if(recyclerView!=null){ + recyclerView.smoothScrollToPosition(currentPosition-1); + } + return findViewByPosition(currentPosition - 1); + } else { + if(recyclerView!=null){ + recyclerView.smoothScrollToPosition(currentPosition); + } + return findViewByPosition(currentPosition); + } + case View.FOCUS_LEFT: + LiveDataBus.get().with(Constants.MSG_LIST_REFRESH_ITEM).postValue(""); + if(leftView!=null){ + leftView.requestFocus(); + return leftView; + } + break; + case View.FOCUS_RIGHT: + if(recyclerView!=null){ + recyclerView.smoothScrollToPosition(currentPosition); + } + return findViewByPosition(currentPosition); + } + return super.onInterceptFocusSearch(focused, direction); + } + +} diff --git a/app/src/main/java/com/unionmed/unionmedtv/utils/MyLinearLayoutManager.java b/app/src/main/java/com/unionmed/unionmedtv/utils/MyLinearLayoutManager.java new file mode 100644 index 0000000..546ed11 --- /dev/null +++ b/app/src/main/java/com/unionmed/unionmedtv/utils/MyLinearLayoutManager.java @@ -0,0 +1,86 @@ +package com.unionmed.unionmedtv.utils; + +import android.animation.ValueAnimator; +import android.content.Context; +import android.graphics.Rect; +import android.os.Build; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; +import android.view.animation.CycleInterpolator; + +import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.unionmed.unionmedtv.livedatas.LiveDataBus; + +import org.jetbrains.annotations.NotNull; + +/** + * NAME:YONG_ + * Created at: 2019/4/30 + * Describe: 防止RecyclerView快速移动焦点跑飞 + */ +public class MyLinearLayoutManager extends LinearLayoutManager { + private View rightView; + + public View getRightView() { + return rightView; + } + + public void setRightView(View rightView) { + this.rightView = rightView; + } + + + public MyLinearLayoutManager(Context context) { + super(context); + } + + public MyLinearLayoutManager(Context context, int orientation, boolean reverseLayout) { + super(context, orientation, reverseLayout); + } + + public MyLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + + @Override + public View onInterceptFocusSearch(View focused, int direction) { + int currentPosition = getPosition(getFocusedChild()); + switch (direction) { + case View.FOCUS_DOWN: + if (currentPosition == getItemCount() - 1) { + scrollToPosition(currentPosition); + return findViewByPosition(currentPosition); + } else { + scrollToPosition(currentPosition + 1); + LiveDataBus.get().with(Constants.MSG_LIST_SELECT_ITEM).postValue(currentPosition + 1); + return findViewByPosition(currentPosition + 1); + } + case View.FOCUS_UP: + if (currentPosition == 0) { + scrollToPosition(currentPosition); + return findViewByPosition(currentPosition); + } else { + scrollToPosition(currentPosition - 1); + LiveDataBus.get().with(Constants.MSG_LIST_SELECT_ITEM).postValue(currentPosition - 1); + return findViewByPosition(currentPosition - 1); + } + case View.FOCUS_LEFT: + scrollToPosition(currentPosition); + return findViewByPosition(currentPosition); + case View.FOCUS_RIGHT: + LiveDataBus.get().with(Constants.MSG_SELECT_ITEM).postValue(currentPosition - 1); + if (rightView != null) { + rightView.requestFocus(); + return rightView; + } + } + return super.onInterceptFocusSearch(focused, direction); + } +} diff --git a/app/src/main/res/drawable/bg_00ffffff.xml b/app/src/main/res/drawable/bg_00ffffff.xml new file mode 100644 index 0000000..40e046a --- /dev/null +++ b/app/src/main/res/drawable/bg_00ffffff.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/bg_101e27.xml b/app/src/main/res/drawable/bg_101e27.xml new file mode 100644 index 0000000..7b98d77 --- /dev/null +++ b/app/src/main/res/drawable/bg_101e27.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/bg_50616d.xml b/app/src/main/res/drawable/bg_50616d.xml new file mode 100644 index 0000000..f7d60e4 --- /dev/null +++ b/app/src/main/res/drawable/bg_50616d.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/msg_list_item_select.xml b/app/src/main/res/drawable/msg_list_item_select.xml new file mode 100644 index 0000000..012e9b2 --- /dev/null +++ b/app/src/main/res/drawable/msg_list_item_select.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml index bc5f76d..9ebdc54 100644 --- a/app/src/main/res/layout/activity_home.xml +++ b/app/src/main/res/layout/activity_home.xml @@ -62,7 +62,7 @@ android:paddingRight="10dp" android:paddingLeft="10dp" android:layout_marginLeft="10dp" - android:nextFocusRight="@+id/tv_city" + android:nextFocusRight="@+id/iv_msg" android:gravity="center" android:textColor="@color/white_f1f1f1" android:background="@drawable/selector_focus_bg_corner15_without_default_bg" @@ -83,7 +83,20 @@ app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> - + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_video_call.xml b/app/src/main/res/layout/activity_video_call.xml new file mode 100644 index 0000000..42c1861 --- /dev/null +++ b/app/src/main/res/layout/activity_video_call.xml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_msg.xml b/app/src/main/res/layout/fragment_msg.xml new file mode 100644 index 0000000..599fbce --- /dev/null +++ b/app/src/main/res/layout/fragment_msg.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_msg_image_left_layout.xml b/app/src/main/res/layout/item_msg_image_left_layout.xml new file mode 100644 index 0000000..a08c90f --- /dev/null +++ b/app/src/main/res/layout/item_msg_image_left_layout.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_msg_image_right_layout.xml b/app/src/main/res/layout/item_msg_image_right_layout.xml new file mode 100644 index 0000000..0e83772 --- /dev/null +++ b/app/src/main/res/layout/item_msg_image_right_layout.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_msg_list_layout.xml b/app/src/main/res/layout/item_msg_list_layout.xml new file mode 100644 index 0000000..eefe02b --- /dev/null +++ b/app/src/main/res/layout/item_msg_list_layout.xml @@ -0,0 +1,34 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_msg_order_left_layout.xml b/app/src/main/res/layout/item_msg_order_left_layout.xml new file mode 100644 index 0000000..748b5c3 --- /dev/null +++ b/app/src/main/res/layout/item_msg_order_left_layout.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_msg_order_right_layout.xml b/app/src/main/res/layout/item_msg_order_right_layout.xml new file mode 100644 index 0000000..6543faf --- /dev/null +++ b/app/src/main/res/layout/item_msg_order_right_layout.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_msg_text_left_layout.xml b/app/src/main/res/layout/item_msg_text_left_layout.xml new file mode 100644 index 0000000..00f0d2b --- /dev/null +++ b/app/src/main/res/layout/item_msg_text_left_layout.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_msg_text_right_layout.xml b/app/src/main/res/layout/item_msg_text_right_layout.xml new file mode 100644 index 0000000..3901043 --- /dev/null +++ b/app/src/main/res/layout/item_msg_text_right_layout.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_remote_layout.xml b/app/src/main/res/layout/item_remote_layout.xml new file mode 100644 index 0000000..b9d62ce --- /dev/null +++ b/app/src/main/res/layout/item_remote_layout.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-xhdpi/icon_camera_off.png b/app/src/main/res/mipmap-xhdpi/icon_camera_off.png new file mode 100644 index 0000000..8c521e6 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_camera_off.png differ diff --git a/app/src/main/res/mipmap-xhdpi/icon_camera_on.png b/app/src/main/res/mipmap-xhdpi/icon_camera_on.png new file mode 100644 index 0000000..5d7580c Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_camera_on.png differ diff --git a/app/src/main/res/mipmap-xhdpi/icon_msg.png b/app/src/main/res/mipmap-xhdpi/icon_msg.png index 41f50a6..3fc2834 100644 Binary files a/app/src/main/res/mipmap-xhdpi/icon_msg.png and b/app/src/main/res/mipmap-xhdpi/icon_msg.png differ diff --git a/app/src/main/res/mipmap-xhdpi/icon_mute.png b/app/src/main/res/mipmap-xhdpi/icon_mute.png deleted file mode 100644 index 7d821c7..0000000 Binary files a/app/src/main/res/mipmap-xhdpi/icon_mute.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xhdpi/icon_mute_off.png b/app/src/main/res/mipmap-xhdpi/icon_mute_off.png new file mode 100644 index 0000000..f8c2655 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_mute_off.png differ diff --git a/app/src/main/res/mipmap-xhdpi/icon_mute_on.png b/app/src/main/res/mipmap-xhdpi/icon_mute_on.png new file mode 100644 index 0000000..7c8c472 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_mute_on.png differ diff --git a/app/src/main/res/mipmap-xhdpi/icon_turn_off_camera.png b/app/src/main/res/mipmap-xhdpi/icon_turn_off_camera.png deleted file mode 100644 index 1ee5aae..0000000 Binary files a/app/src/main/res/mipmap-xhdpi/icon_turn_off_camera.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xhdpi/rc_default_portrait.png b/app/src/main/res/mipmap-xhdpi/rc_default_portrait.png new file mode 100644 index 0000000..d32054a Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/rc_default_portrait.png differ diff --git a/settings.gradle b/settings.gradle index ec822c4..4fa2743 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,6 @@ include ':app' include ':library-player' +include ':imlib' +include ':calllib' +include ':rtclib' +