liumingming

first commit

Showing 80 changed files with 4594 additions and 0 deletions
*.iml
.gradle
/local.properties
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
.DS_Store
/build
/captures
.externalNativeBuild
... ...
No preview for this file type
No preview for this file type
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="1.8" />
</component>
</project>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
</project>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="PLATFORM" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
<option name="useQualifiedModuleNames" value="true" />
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven" />
<option name="name" value="maven" />
<option name="url" value="http://maven.aliyun.com/nexus/content/repositories/releases/" />
</remote-repository>
<remote-repository>
<option name="id" value="BintrayJCenter" />
<option name="name" value="BintrayJCenter" />
<option name="url" value="https://jcenter.bintray.com/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven3" />
<option name="name" value="maven3" />
<option name="url" value="http://develop.hh-medic.com/repository/maven-public" />
</remote-repository>
<remote-repository>
<option name="id" value="Google" />
<option name="name" value="Google" />
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven2" />
<option name="name" value="maven2" />
<option name="url" value="https://jitpack.io" />
</remote-repository>
<remote-repository>
<option name="id" value="$USER_HOME$/Library/Android/sdk/extras/google/m2repository" />
<option name="name" value="$USER_HOME$/Library/Android/sdk/extras/google/m2repository" />
<option name="url" value="file:$USER_HOME$/Library/Android/sdk/extras/google/m2repository/" />
</remote-repository>
<remote-repository>
<option name="id" value="$USER_HOME$/Library/Android/sdk/extras/m2repository" />
<option name="name" value="$USER_HOME$/Library/Android/sdk/extras/m2repository" />
<option name="url" value="file:$USER_HOME$/Library/Android/sdk/extras/m2repository/" />
</remote-repository>
<remote-repository>
<option name="id" value="$USER_HOME$/Library/Android/sdk/extras/android/m2repository" />
<option name="name" value="$USER_HOME$/Library/Android/sdk/extras/android/m2repository" />
<option name="url" value="file:$USER_HOME$/Library/Android/sdk/extras/android/m2repository/" />
</remote-repository>
</component>
</project>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="15">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
<item index="6" class="java.lang.String" itemvalue="android.annotation.Nullable" />
<item index="7" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.Nullable" />
<item index="9" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableDecl" />
<item index="10" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableType" />
<item index="11" class="java.lang.String" itemvalue="com.android.annotations.Nullable" />
<item index="12" class="java.lang.String" itemvalue="org.eclipse.jdt.annotation.Nullable" />
<item index="13" class="java.lang.String" itemvalue="io.reactivex.annotations.Nullable" />
<item index="14" class="java.lang.String" itemvalue="io.reactivex.rxjava3.annotations.Nullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="14">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
<item index="5" class="java.lang.String" itemvalue="android.annotation.NonNull" />
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.NonNull" />
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullDecl" />
<item index="9" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullType" />
<item index="10" class="java.lang.String" itemvalue="com.android.annotations.NonNull" />
<item index="11" class="java.lang.String" itemvalue="org.eclipse.jdt.annotation.NonNull" />
<item index="12" class="java.lang.String" itemvalue="io.reactivex.annotations.NonNull" />
<item index="13" class="java.lang.String" itemvalue="io.reactivex.rxjava3.annotations.NonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
... ...
## 视频医生 Android SDK接入文档 (3.4.0.02251433)
<!--![demo](demo.gif)-->
[接入过程遇到的问题及解决方案的汇总参考](QA.md)
[TRTC版本SDK接入遇到的图像方向问题及解决方案](Rotation.md)
## [查看版本更新说明](#六版本更新说明)
* [一、SDK接入引用说明](#一sdk接入引用说明)
* [1. 建议接入环境](#1-建议接入环境)
* [1.1 建议接入使用IDE版本](#11-建议接入使用ide版本)
* [1.2 建议接入SDK版本](#12-建议接入sdk版本)
* [2. 视频医生Android SDK通过maven仓库引用来导入工程,如下](#2-视频医生android-sdk通过maven仓库引用来导入工程如下)
* [2.1 在build.gradle文件中配置远程库地址,在respositories中添加相应配置](#21-在buildgradle文件中配置远程库地址在respositories中添加相应配置)
* [2.2 在build.gradle文件中dependencies中配置库的引用](#22-在buildgradle文件中dependencies中配置库的引用)
* [2.3 配置NDK架构选择,必须进行对应配置](#23-配置ndk架构选择必须进行对应配置)
* [2.4 java8支持的配置,必须配置](#24-java8支持的配置必须配置)
* [3. 我们用到的常用第三方库以及库的版本](#3-我们用到的常用第三方库以及库的版本)
* [二、SDK接入引用说明](#二sdk接入引用说明)
* [1. SDK初始化](#1-sdk初始化)
* [1.1 SDK配置选项 HHSDKOptions](#11-sdk配置选项-hhsdkoptions)
* [1.2 音箱接入快捷获取基本配置选项方式](#12-音箱接入快捷获取基本配置选项方式)
* [1.3 SDK初始化](#13-sdk初始化)
* [1.4 SDK使用到的主要权限说明](#14-sdk使用到的主要权限说明)
* [2. SDK功能介绍](#2-sdk功能介绍)
* [2.1 获取SDK版本号](#21-获取sdk版本号)
* [2.2 登录](#22-登录)
* [2.3 登出](#23-登出)
* [2.4 选择成员呼叫(推荐使用)](#24-选择成员呼叫推荐使用)
* [2.5 选定成员呼叫](#25-选定成员呼叫)
* [2.6 获取用户登录状态](#26-获取用户登录状态)
* [2.7 获取病历列表地址](#27-获取病历列表地址)
* [2.8 获取病历详情地址](#28-获取病历详情地址)
* [2.9 获取所有成员病历列表地址(推荐使用)](#29-获取所有成员病历列表地址推荐使用)
* [2.10 陪诊](#210-陪诊)
* [2.11 进入消息界面](#211-进入消息界面)
* [2.12 设置呼叫附加参数](#212-设置呼叫附加参数)
* [3. 回调说明](#3-回调说明)
* [3.1 登录回调(HHLoginListener)](#31-登录回调hhloginlistener)
* [3.2 呼叫回调(HHCallListener)](#32-呼叫回调hhcalllistener)
* [3.3 呼叫回调扩展(HHCallExListener)继承自HHCallListener](#33-呼叫回调扩展HHCallExListener继承自HHCallListener)
* [三、常见问题](#三常见问题)
* [1. AndroidManifest合并冲突问题](#1-androidmanifest合并冲突问题)
* [2. error:style attribute '@android:attr/windowEnterAnimation' not found](#2-errorstyle-attribute-androidattrwindowenteranimation-not-found)
* [3. 如果遇到库冲突也就是duplicate某个包这说明库冲突了,这种问题可以用如下方法解决](#3-如果遇到库冲突也就是duplicate某个包这说明库冲突了这种问题可以用如下方法解决)
* [4. 推送相关配置](#4-推送相关配置)
* [4.1 申请华为和小米的推送](#41-申请华为和小米的推送)
* [4.2 另外我们需要在配置文件AndroidManifest.xml文件配置push相关配置,如下:](#42-另外我们需要在配置文件androidmanifestxml文件配置push相关配置如下)
* [4.3 我们提供push相关jar包](#43-我们提供push相关jar包)
* [四、错误码整理](#四错误码整理)
* [五、Demo下载地址](#五demo下载地址)
* [六、版本更新说明](#六版本更新说明)
### 一、SDK接入引用说明
#### 1. 建议接入环境
##### 1.1 建议接入使用IDE版本
Android Studio 3.x.x版本以上版本
##### 1.2 建议接入SDK版本以及最低支持设备系统版本
|配置项|版本|
|---|---|
|compileSdkVersion| 28及以上|
|minSdkVersion| 17及以上|
|targetSdkVersion| 28及以上|
|最低支持设备系统| >= 4.2 |
#### 2. 视频医生Android SDK通过maven仓库引用来导入工程,如下
##### 2.1 在build.gradle文件中配置远程库地址,在respositories中添加相应配置
```
repositories {
maven {url 'http://developer.huawei.com/repo/'} //这个是在用到华为推送的时候才需要配置
maven {
credentials {
username 'hh-public'
password 'OFGB5wX0'
}
url 'http://develop.hh-medic.com/repository/maven-public'
}
}
```
##### 2.2 在build.gradle文件中dependencies中配置库的引用
```
implementation "com.hhmedic.android.sdk:hh_trtc:3.4.0.02251433"
```
<span style="color:red;">注:添加以上配置后需要进行gradle sync才能同步生效,配置maven库地址的时候不能省略用户名和密码,否则同步不下来。</span>
##### 2.3 配置NDK架构选择,必须进行对应配置(这个配置在2.5.4.03011601这个版本后废弃)
```
ndk {
//设置支持的SO库架构
abiFilters "armeabi-v7a"
}
```
##### 2.4 java8支持的配置,必须配置
```
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
```
#### 3. 我们用到的常用第三方库以及库的版本
```
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.orhanobut:logger:2.2.0'
implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation 'com.zhihu.android:matisse:0.5.3-beta3'
implementation 'com.squareup.okhttp3:okhttp:3.x.x' //这个版本号只是一个代写
```
> 如果由于这些包引用出现冲突例如是duplicate某个jar包或文件有可能是某些库引用的版本和我们不一致,直接force一个合适的版本就行。具体写法可以参考[这里](#5-如果遇到库冲突也就是duplicate某个包这说明库冲突了这种问题可以用如下方法解决)。
### 二、SDK接入引用说明
#### 1. SDK初始化
##### 1.1 SDK配置选项 HHSDKOptions
```java
HHSDKOptions options = new HHSDKOptions("sdkProductId");
```
参数说明:
| 参数定义 | 说明 |
| --- | --- |
| sdkProductId | 分配的产品ID |
| sDebug |是否开启调试(开启会打印log)|
|mDeviceType|接入设备类型(NORMAL, SOUND),NORMAL表示手机、Pad SOUND 表示音箱|
|mImei|设备序列号(只有音箱接入的时候需要传入)|
|dev|是否开始测试服模式,开启后连接测试服|
|isOpenCamera|视频过程中是否开启拍照|
|mOrientation|屏幕方向 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT 或 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE|
|enableMedical|是否开启个人中心的档案库显示|
|enableActivate|是否开启个人中心激活码激活功能|
##### 1.2 SDK初始化
>SDK初始化最好是放到自定义的Application中去初始化。
```java
HHSDKOptions options = ...;
options.isDebug = true;
options.mDeviceType = DeviceType.NORMAL;
options.dev = true;
options.isOpenCamera = false;
options.mOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
options.pushConfig = new HHPushConfig() //这里是需要实例化然后补充参数后赋值
HHDoctor.init(getApplicationContext(),options);
```
##### 1.3 SDK使用到的主要权限说明
| 权限 | 说明 |
| --- | --- |
| android.permission.READ_PHONE_STATE | 在视频通话过程中如果有电话进来我们会做挂断视频保证正常电话通话 |
|android.permission.CAMERA|保证正常使用设备的摄像设备|
|android.permission.RECORD_AUDIO|保证正常使用设备的音频设备|
|android.permission.WRITE_EXTERNAL_STORAGE android.permission.READ_EXTERNAL_STORAGE | 保证正常读取存储设备上的媒体文件 |
#### 2. SDK功能介绍
##### 2.1 获取SDK版本号
```java
public static String SDKVersion()
```
>通过这个接口在调试的过程可以获取到当前SDK的版本号
##### 2.2 登录
```java
public static void login(Context context,String userToken,HHLoginListener listener)
```
参数说明
| 参数定义 | 说明 |
| --- | --- |
|Context context|上下文,当前操作Activity|
|String userToken|接入方和视频医生服务端对接后返回的userToken|
|HHLoginListener listener|登录回调|
##### 2.3 登出
```java
public static void logOut(Context context)
```
参数说明:
| 参数定义 | 说明 |
| --- | --- |
|Context context|上下文,当前操作Activity|
##### 2.4 选择成员呼叫(*推荐使用*)
```java
public static void call(Context context,HHCallListener listener)
```
参数说明:
| 参数定义 | 说明 |
| --- | --- |
|Context context|上下文,当前呼叫发起Activity|
|HHCallListener listener|呼叫回调|
##### 2.5 选定成员呼叫
```java
public static void call(Context context, String userToken,HHCallListener listener)
```
参数说明:
| 参数定义 | 说明 |
| --- | --- |
|Context context|上下文,当前呼叫发起Activity|
|userToken|咨询人的userToken|
|HHCallListener listener|呼叫回调|
##### 2.6 获取用户登录状态
```java
public static boolean isLogined(Context context)
```
参数说明:
| 参数定义 | 说明 |
| --- | --- |
|Context context|上下文,当前呼叫发起Activity|
##### 2.7 获取病历列表地址
```
public static String getMedicListUrl(Context context,String userToken)
```
参数说明:
| 参数定义 | 说明 |
| --- | --- |
|Context context|当前上下文,一般为当前Activity|
|String userToken|由视频医生提供方分配给第三方的用户安全标志,userToken为与视频医生提供方对接得到的用户安全标志|
##### 2.8 获取病历详情地址
```
public static String getMedicDetailUrl(Context context,String userToken,String medicId)
```
参数说明:
| 参数定义 | 说明 |
| --- | --- |
|Context context|当前上下文,一般为当前Activity|
|String userToken|由视频医生提供方分配给第三方的用户安全标志,userToken为与视频医生提供方对接得到的用户安全标志|
|String medicId |病历存档ID,这个存档ID由视频医生提供方同步到接入方的存档ID|
##### 2.9 获取所有成员病历列表地址(*推荐使用*)
```
public static String getAllMedics(Context context,String userToken)
```
参数说明:
| 参数定义 | 说明 |
| --- | --- |
|Context context|当前上下文,一般为当前Activity|
|String userToken|由视频医生提供方分配给第三方的用户安全标志,userToken为与视频医生提供方对接得到的用户安全标志|
##### 2.10 陪诊
```
public static void multiCall(Context context, CallType type, HHInviteUser user)
```
参数说明:
| 参数定义 | 说明 |
| --- | --- |
|Context context|当前上下文,一般为当前Activity|
|CallType type|呼叫类型,其中包括儿科和全科,值分别为CallType.child和CallType.all |
|HHInviteUser user|被邀请的陪诊人,具体用法说明如本表下方|
```
String userToken = "与和缓对接得到的被邀请用户userToken";
String userName = "被邀请用户的昵称(名字),这个字段为选填";
String userPhoto = "被邀请用户的头像提示,这个字段为为选填";
HHInviteUser inviteUser = new HHInviteUser(userToken);
inviteUser.setNickName(userName);
inviteUser.setPhotoUrl(userPhoto);
```
##### 2.11 进入消息界面
```
public static void message(Context context)
```
参数说明:
| 参数定义 | 说明 |
| --- | --- |
|Context context|当前上下文,一般为当前Activity|
##### 2.12 设置呼叫附加参数
> 注意这个方法需要在呼叫前进行设置才会生效
```java
public static void setExtension(String ext)
```
参数说明:
| 参数定义 | 说明 |
| --- | --- |
|String ext|文本数据,不支持json格式,最长长度支持64位|
#### 3. 回调说明
>主要说明在各个接口用到的回调代理
##### 3.1 登录回调(HHLoginListener)
```java
public interface HHLoginListener
{
/**
* 登录成功
*/
void onSuccess();
/**
* 登录失败
* @param tips
*/
void onError(String tips);
}
```
##### 3.2 呼叫回调(HHCallListener)
```java
public interface HHCallListener
{
/**
* 启动呼叫
*/
void onStart(String orderId);
/**
* 呼叫中
*/
void onCalling();
/**
* 通话中(该回调方法在3.0.0*版本以后废弃请使用HHCallExListener中的onDoctorAgree回调方法替代)
*/
void onInTheCall();
/**
* 通话结束
*/
void onFinish();
/**
* 呼叫成功,等待医生接受
*/
void onCallSuccess();
/**
* 呼叫失败
* @param code 错误码
*/
void onFail(int code);
/**
* 取消呼叫 含 取消排队
*/
void onCancel();
/**
*
* 排队超时 自动取消
*/
void onLineUpTimeout();
/**
*
* 需要排队等待
*/
void onLineUp();
}
```
##### 3.3 呼叫回调扩展(HHCallExListener)继承自HHCallListener
```java
public interface HHCallExListener extends HHCallListener {
/**
* 返回呼叫医生信息
**/
void onLoadDoctor(HHCallInfo callInfo);
/**
* 医生接听进入通话
**/
void onDoctorAgree();
void onCallError(String error);
}
```
### 三、常见问题
#### 1. AndroidManifest合并冲突问题
```
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
```
可以更替乘如下写法
```
<manifest package="cn.edu.fudan.rndrobot"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<provider
tools:replace="android:authorities"
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
tools:replace="android:resource"
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
</manifest>
```
#### 2. error:style attribute '@android:attr/windowEnterAnimation' not found
在Project/gradle.properties中添加 android.enableAapt2=false
#### 3. 如果遇到库冲突也就是duplicate某个包这说明库冲突了,这种问题可以用如下方法解决
这种问题遇到的情况有可能是用到的库和我们SDK中用到的库冲突,如果是module的冲突类似于问题4中的那种可以用exclude来进行排序module就行,另外一种情况是库和我们SDK库引用的版本的版本不一样,只要对库的版本选一个最合适的版本force一下版本就可以解决了。force大概写法如下:
```
configurations.all {
resolutionStrategy {
force "com.android.support:recyclerview-v7:27.1.1"
}
}
```
#### 4. 推送相关配置
> 如果需要使用SDK的push功能,需要进行相应文件和配置的添加,主要是小米和华为推送SDK包添加,以及推送参数的申请,小米
推送需要接入方提供AppSecret和包名给我们,华为需要接入方提供AppID和AppSecret以及包名给我们,我们使用这些参数去生成对应SDK中需要配置的参数。
##### 4.1 申请华为和小米的推送
- 需要将小米的AppSecret提供
- 需要将华为的AppId和AppSecret提供
> 我们使用这些以上提供的数据来生成我们需要的参数,注意如下两个参数均需视频医生提供方来生成。另外需要提供唤醒的时候应该跳到哪个界面的配置,通知的图标配置,小米推送的AppId和小米推送的AppKey。如下:
```java
public class HHPushConfig {
/**
* 通知栏提醒的响应intent的activity类型。<br>
* 可以为null。如果未提供,将使用包的launcher的入口intent的activity。
*/
public Class<? extends Activity> notificationEntrance;
/**
* 状态栏提醒的小图标的资源ID。<br>
* 如果不提供,使用app的icon
*/
public int notificationSmallIconId;
/**
* 小米推送 appId
*/
public String xmAppId;
/**
* 小米推送 appKey
*/
public String xmAppKey;
public String xmCertificateName; //这个参数是由小米提供的参数生成
public String hwCertificateName; //这个是由华为提供的参数生成
public String vivoCertificateName; //这个是由vivo提供的参数生成
}
```
##### 4.2 另外我们需要在配置文件AndroidManifest.xml文件配置push相关配置,如下:
```xml
//小米push相关
<!-- 小米push permission -->
<permission android:name="{这里需要替换成你的包名}.permission.MIPUSH_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="{这里需要替换成你的包名}.permission.MIPUSH_RECEIVE" />
<!-- end-->
<!-- 小米 推送-->
<!-- 小米推送配置 -->
<!--配置的service和receiver-->
<service
android:name="com.xiaomi.push.service.XMPushService"
android:process=":mixpush"
android:enabled="true"
/>
<service
android:name="com.xiaomi.push.service.XMJobService"
android:enabled="true"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE"
android:process=":mixpush" />
<!--注:此service必须在3.0.1版本以后(包括3.0.1版本)加入-->
<service
android:enabled="true"
android:exported="true"
android:name="com.xiaomi.mipush.sdk.PushMessageHandler" />
<service android:enabled="true"
android:name="com.xiaomi.mipush.sdk.MessageHandleService" />
<!--注:此service必须在2.2.5版本以后(包括2.2.5版本)加入-->
<receiver
android:exported="true"
android:name="com.xiaomi.push.service.receivers.NetworkStatusReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver
android:exported="false"
android:process=":mixpush"
android:name="com.xiaomi.push.service.receivers.PingReceiver" >
<intent-filter>
<action android:name="com.xiaomi.push.PING_TIMER" />
</intent-filter>
</receiver>
<receiver
android:name="com.netease.nimlib.mixpush.mi.MiPushReceiver"
android:exported="true">
<intent-filter android:priority="0x7fffffff">
<action android:name="com.xiaomi.mipush.RECEIVE_MESSAGE"/>
<action android:name="com.xiaomi.mipush.MESSAGE_ARRIVED"/>
<action android:name="com.xiaomi.mipush.ERROR"/>
</intent-filter>
</receiver>
<!-- 小米 end -->
//华为push相关
<meta-data
android:name="com.huawei.hms.client.appid"
android:value="华为的AppID" />
<provider
android:name="com.huawei.hms.update.provider.UpdateProvider"
android:authorities="{这里需要替换成自己的包名,不用带大括号}.hms.update.provider"
android:exported="false"
android:grantUriPermissions="true"/>
```
##### 4.3 我们提供push相关jar包
> jar包由我们发送给接入方
需要额外添加gradle引用
```
api 'com.huawei.android.hms:push:2.6.0.301'
```
如果使用华为的push需要添加混淆配置
```
-keep class com.huawei.hms.**{*;}
```
### 四、错误码整理
|错误码|说明|
|---|---|
|-1||
|-5|未登录|
|-2||
### 五、Demo下载地址
https://github.com/HHMedic/HHDoctorSDK_demo_Android/tree/trtc
### 六、版本更新说明
版本更新说明
|版本号|说明|
|---|---|
|3.1.6.10081541|兼容Android Q读取照片问题,如果targetSDKVersion设置的29 需要在AndroidManifest开启uestLegacyExternalStorage设置为true|
|3.1.6.09141533|解决一些layout相关问题|
|3.1.6.09131705|优化文案格式化|
|3.1.6.08191852|增加绿通、挂号、重疾、护理挂号服务|
|3.1.2.04011456|音视频优化|
|3.0.8.01061149|音视频优化|
|3.0.6.12022116|优化混淆规则|
|3.0.6.11161853|新版TRTC首发|
... ...
## 视频医生带药SDK接入说明文档
### 一、SDK引入说明
#### 1. 接入环境说明同视频医生接入文档相同[《视频医生接入环境说明》](https://github.com/HHMedic/HHDoctorSDK_demo_Android#1-%E5%BB%BA%E8%AE%AE%E6%8E%A5%E5%85%A5%E7%8E%AF%E5%A2%83)
#### 2. 基本引入同视频医生接入文档相同[视频医生接入引入文档](https://github.com/HHMedic/HHDoctorSDK_demo_Android#2-%E8%A7%86%E9%A2%91%E5%8C%BB%E7%94%9Fandroid-sdk%E9%80%9A%E8%BF%87maven%E4%BB%93%E5%BA%93%E5%BC%95%E7%94%A8%E6%9D%A5%E5%AF%BC%E5%85%A5%E5%B7%A5%E7%A8%8B%E5%A6%82%E4%B8%8B)
> 注意用药SDK依赖于视频医生的引入,同时账户系统依赖于视频医生基础SDk
#### 3. 带药SDK引入
先在 build.gradle(Project:XXXX) 的 repositories 添加:
```
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
```
注意以上这个配置是基于原视频SDK的新增项目,请务必添加,用药SDK中使用到了第三方库如下:
```
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.46'
```
如果这个库和接入项目中有冲突请及时告知。
然后添加用药库引用
```
implementation 'com.hhmedic.android.sdk:medicine:2.1.0'
```
#### 4. SDK引入特别说明
用药SDK用到data binding技术,需要接入方自行开启,需要开启databinding功能,需要在gradle配置文件android节点下开启如下:
```
android {
...
dataBinding {
enabled = true
}
...
}
```
以上代码...代指其他配置不需要添加到gradle配置文件。
### 二、 SDK接入接口使用说明
> 注意用药SDK使用是基于视频医生SDK,所以是基于视频医生SDK的初始化,接口统一调用类为HHMedicine,调用方式为静态方法调用,通过HHMedicine.+接口名称方式调用
#### 1. 初始化用药SDK
```
HHMedicine.init();
```
> 注意初始化用药SDK依然和视频医生SDK相同需要将初始化代码放到Application的onCreate中去做。
#### 2.访问用药订单列表
```
public static void orderList(@NonNull Context context,@NonNull String userToken)
```
参数说明:
|参数定义|参数说明|
|---|---|
|Context context|上下文,指Activity|
|String userToken|通过与视频医生提供方服务器对接得到|
#### 3. 访问购药订单详情
```
public static void orderDetail(@NonNull Context context, @NonNull String orderId, @NonNull String userToken, @Nullable OnOrderListener listener)
```
参数说明:
|参数定义|参数说明|
|---|---|
|Context context|上下文,指Activity|
|String orderId|用药订单号|
|String userToken|通过与视频医生提供方服务器对接得到|
|String OnOrderListener|购药支付后回调|
#### 4. 支付明细
```
public static void payDetail(@NonNull Context context,@NonNull String userToken)
```
参数说明:
|参数定义|参数说明|
|---|---|
|Context context|上下文,指Activity|
|String userToken|通过与视频医生提供方服务器对接得到|
#### 5. 收货地址管理
```
public static void addressList(@NonNull Context context)
```
参数说明:
|参数定义|参数说明|
|---|---|
|Context context|上下文,指Activity|
### 三、 回调说明
#### 1. 查看订单详情支付结果回调
```
public interface OnOrderListener
{
void onSuccess(String orderId);
}
```
在支付完后会有回调,onSuccess会收到支付完成orderId
### 四、版本更新说明
|版本号|说明|
|---|---|
|2.1.0| 发布用带SDK|
... ...
## 接入SDK过程中遇到的问题及一般解决方案
### 1. 由于SDK中引用库和接入方引入库发生冲突造成的问题
* 问题描述1如下:
> Execution failed for task ':app-container:transformClassesAndResourcesWithProguardForPrdRelease'.***********(Can't process class [module-info.class] (null))
* 问题描述2如下:
> ava.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/gson/GsonBuilder;
* 问题描述3如下:
> 如果遇到库冲突也就是duplicate某个包这说明库冲突了
*以上已经具体描述了由于引用了相同库不同版本会造成的问题,这类问题一般可以采用force引用库版本来解决,具体操作示例如下,以gson库为例。*
```
android {
.....
configurations.all {
resolutionStrategy.force 'com.google.code.gson:gson:2.8.0'
}
}
```
如果是遇到如上问题可以通过以上gradle配置代码给出的示例代码去force对应的库版本一般可以解决,目前遇到的真实案例就是这个库版本冲突造成的问题,请参考。
### 2. SDK接入过程出现了如下图的类似问题 Verifier rejected class
![6341606638198_.pic_hd](media/6341606638198_.pic_hd.jpg)
遇到如图类似的问题这种情况是因为接入SDK的项目中存在一些特殊引用库把我们SDK内部一些代码篡改造成的。遇到这类问题可以及时联系我们或更新成其他版本的SDK。
... ...
## 和缓视频医生Android SDK对接文档 3.4.0.02251433(快速接入版本)
### 一、引入SDK
```
在project的build.gradle文件中加入如下配置,由于SDK是做成了私有库所以必须加入此配置
repositories {
maven {
credentials {
username 'hh-public'
password 'OFGB5wX0'
}
url 'http://develop.hh-medic.com/repository/maven-public'
}
}
在app moudule的build.gradle文件中引用和缓视频医生SDK,如下:
implementation 'com.hhmedic.android.sdk:hh_trtc:3.4.0.02251433'
```
### 二、 初始化SDK
```
HHSDKOptions options = new HHSDKOptions(sdkProductId); //productId由和缓分配的产品Id
options.dev = true; //修改这个参数来切换测试环境和正式环境,当设置为true的时候是测试环境,设置为false为生产环境
HHDoctor.init(getApplicationContext(), options);
```
### 三、登录登出
```
//登录
String userToken = "这个参数是服务器和和缓服务器对接后得到的用户userToken";
HHDoctor.login(this, userToken, new HHLoginListener() {
@Override
public void onSuccess() {
//这里处理登录后的逻辑
}
@Override
public void onError(String s) {
//处理登录失败后的逻辑,一般不会发生
}
});
//登出
HHDoctor.logOut(this); //this指的是上下文Context
```
### 四、跳转首页(必须登录后)
```
HHDoctor.message(this); //this指的是上下文Context
```
### 五、Demo及详细文档
Demo
https://github.com/HHMedic/HHDoctorSDK_demo_Android/tree/trtc
详细接入文档
https://github.com/HHMedic/HHDoctorSDK_demo_Android/blob/trtc/Document.md
TRTC版本接入图像旋转问题及解决方案整理
https://github.com/HHMedic/HHDoctorSDK_demo_Android/blob/trtc/Rotation.md
**注意如果需要对APP瘦身一定保留引用和缓视频SDK后出现的pic_error_78219.png这张图片,这张图片有特殊用途,删除会造成SDK不可用。**
... ...
## TRTC版本接入图像旋转问题及解决方案整理
如果是硬件设备接入请注意以下提示:
> 由于硬件设备的摄像头采集方向不确定,在接入过程会遇到设备横屏情况下采集图像根据设备的默认方向(竖向)进行裁剪造成图像在和缓工作台显示为裁剪后的图像,如果遇到这种情况可以有限先不设置远程图像方向,优先考虑设置图像采集方向(设置为横屏采集)来尝试,具体设置如下:
```
//SDK初始化首先先声明一个如下配置
TRTCCloudDef.TRTCVideoEncParam encParam = new TRTCCloudDef.TRTCVideoEncParam();
// videoResolutionMode 设置为横屏
encParam.videoResolutionMode = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_MODE_LANDSCAPE;
//再使用VideoSetting中的setVideoEncParam这个方法设置进去就可以.
VideoSetting.setVideoEncParam(setVideoEncParam)
```
### 一、本地预览图像方向不正问题及解决方案
**本地预览图像在一些特殊设备上会出现方向不正的问题,遇到这类问题需要通过初始化参数来对图像做一些调整,调整方式如下。**
初始化配置类HHSDKOptions中设置localRenderRotation 配置的值,图像调整方向为顺时针调整,可设置值分别有如下参数,如表格列出。
调整方向参数整理如下表格:
|参数|调整方向及角度(原图像角度基础上调整)|
|---|---|
|RTCCloudDef.TRTC_VIDEO_ROTATION_0|顺时针调整0度(无效果)|
|RTCCloudDef.TRTC_VIDEO_ROTATION_90|顺时针调整90度|
|RTCCloudDef.TRTC_VIDEO_ROTATION_180|顺时针调整180度|
|RTCCloudDef.TRTC_VIDEO_ROTATION_270|顺时针调整270度|
在本地图像的方向调整好后有可能在医生工作台看客户图像方向不正的问题,那么就需要看第二大部分进行相关设置的介绍。
### 二、远端图像方向不正的问题及解决方案
**在对接的过程可能会遇到格式各样的设置(也可以简称硬件),有时候会遇到本地图像的方向调整好了,但在远端(医生端)看起来图像方向不正,这个时候就需要通过VideoSetting这个类针对远端图像方向做调整,具体调用方式可以参考如下代码。**
```java
//首先需要关闭设备重力感应。
VideoSetting.setEnableGSENSORMode(false);
//设置远端图像的调整方向,调整方向为顺时针,调整方向参数是可以修改的,可调整
//参数请参考后面给出的表格中的参数。
VideoSetting.setRemoteRotation(TRTCCloudDef.TRTC_VIDEO_ROTATION_90);
//这个设置可以在调整的时候不添加,如果通过以上两条设置仍然不生效,再另行添加这个设置进行实验。
VideoSetting.setVideoResolutionMode(TRTCCloudDef.TRTC_VIDEO_RESOLUTION_MODE_LANDSCAPE);
```
调整方向参数整理如下表格:
|参数|调整方向及角度(原图像角度基础上调整)|
|---|---|
|RTCCloudDef.TRTC_VIDEO_ROTATION_0|顺时针调整0度(无效果)|
|RTCCloudDef.TRTC_VIDEO_ROTATION_90|顺时针调整90度|
|RTCCloudDef.TRTC_VIDEO_ROTATION_180|顺时针调整180度|
|RTCCloudDef.TRTC_VIDEO_ROTATION_270|顺时针调整270度|
... ...
/build
... ...
import java.text.SimpleDateFormat
apply plugin: 'com.android.application'
static def increasedVersionCode() {
return (int) (System.currentTimeMillis() / 1000 / 60)
}
static def buildTime() {
def df = new SimpleDateFormat("MMddHH")
return df.format(new Date())
}
def doctor_sdk_name = "hh_trtc"
def doctor_sdk_version = "3.4.0.02251433"
def qmui_version = '2.0.0-alpha11'
android {
compileSdkVersion 29
defaultConfig {
applicationId "com.hhmedic.app.patient.trtc.demo.new"
minSdkVersion 19
targetSdkVersion 29
versionCode increasedVersionCode()
versionName "3.4.0.${buildTime()}"
multiDexEnabled true
ndk {
//设置支持的SO库架构
abiFilters "armeabi-v7a","armeabi","arm64-v8a"
}
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}
packagingOptions {
pickFirst 'lib/armeabi-v7a/libsecsdk.so'
pickFirst 'lib/arm64-v8a/libsecsdk.so'
pickFirst 'lib/armeabi/libsecsdk.so'
exclude 'META-INF/proguard/androidx-annotations.pro'
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
dataBinding true
}
// dataBinding {
// enabled = true
// }
android.applicationVariants.all { variant ->
variant.outputs.all
{
outputFileName = "hh_android_trtc_new_demo_${defaultConfig.versionName}.apk"
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.13.1'
api "com.qmuiteam:qmui:$qmui_version"
implementation 'com.yanzhenjie:permission:2.0.3'
implementation "com.hhmedic.android.sdk:$doctor_sdk_name:$doctor_sdk_version"
implementation 'com.zhihu.android:matisse:0.5.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'com.tencent.bugly:crashreport_upgrade:latest.release'
}
... ...
-dontwarn com.tencent.bugly.**
-keep public class com.tencent.bugly.**{*;}
-keep class android.support.**{*;}
\ No newline at end of file
... ...
package com.hhmedic.android.hhdoctorvideodemo;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.hhmedic.android.hhdoctorvideodemo", appContext.getPackageName());
}
}
... ...
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hhmedic.android.hhdoctorvideodemo">
<application
android:name=".application.DoctorApplication"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".activity.SettingAct"
android:screenOrientation="portrait"/>
<activity
android:name=".activity.MultiVideoAct"
android:screenOrientation="portrait" />
<activity
android:name=".activity.MainActivity"
android:screenOrientation="portrait"
android:theme="@style/PageTheme">
<intent-filter>
<action android:name="com.hhmedic.home" />
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activity.CallSelectorAct"
android:launchMode="singleTask"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="com.hhmedic.doctor.robot" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<receiver android:name=".receiver.Controller">
<intent-filter>
<action android:name="com.hhmedic.doctor.robot.controller" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver android:name=".receiver.DepartReceiver">
<intent-filter>
<action android:name="com.hhmedic.doctor.select.depart" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<activity
android:name=".activity.ViewDetailAct"
android:screenOrientation="portrait" />
</application>
</manifest>
\ No newline at end of file
... ...
package com.hhmedic.android.hhdoctorvideodemo.activity;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
import com.qmuiteam.qmui.util.QMUIStatusBarHelper;
public class BaseActivity extends AppCompatActivity {
public String TAG = getClass().getSimpleName();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// requestWindowFeature(Window.FEATURE_NO_TITLE);
// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
if (!useDataBinding() && contentViewId() != 0) {
setContentView(contentViewId());
}
QMUIStatusBarHelper.setStatusBarLightMode(this);
QMUIStatusBarHelper.translucent(this);
initUI();
}
protected int contentViewId() {
return 0;
}
@Override
public void setContentView(View view) {
super.setContentView(view);
initUI();
}
protected void initUI() {
}
protected boolean useDataBinding() {
return false;
}
protected void initActionBar(Toolbar toolbar)
{
if (toolbar == null)
{
return;
}
setSupportActionBar(toolbar);
initActionBar();
}
public void initActionBar()
{
if(getSupportActionBar() ==null)
{
return ;
}
// 以下代码用于去除阴影
if(Build.VERSION.SDK_INT >= 21)
{
getSupportActionBar().setElevation(0);
}
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
if(item.getItemId() == android.R.id.home)
{
finish();
return true;
}
return false;
}
}
... ...
package com.hhmedic.android.hhdoctorvideodemo.activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.hhmedic.android.hhdoctorvideodemo.R;
import com.hhmedic.android.hhdoctorvideodemo.application.HHDemoUtils;
import com.hhmedic.android.sdk.HHDoctor;
import com.hhmedic.android.sdk.Location;
import com.hhmedic.android.sdk.listener.HHCallListener;
import com.hhmedic.android.sdk.module.video.hangup.HangUp;
import com.orhanobut.logger.Logger;
public class CallSelectorAct extends BaseActivity implements View.OnClickListener{
private boolean noticeTTS;
// private EditText mOrderIdEdit;
private ChatFrontPop mPop;
// private Timer mTimer;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected int contentViewId() {
return R.layout.act_call_selector;
}
@Override
protected void initUI() {
super.initUI();
initActionBar(findViewById(R.id.toolbar));
setTitle(R.string.hp_sdk_demo_main);
findViewById(R.id.is_in_develop).setVisibility(LocalConfig.isDevelop(this) ? View.VISIBLE : View.GONE);
// findViewById(R.id.multi_video).setOnClickListener(this);
// findViewById(R.id.all_btn).setOnClickListener(this);
// findViewById(R.id.child_btn).setOnClickListener(this);
// findViewById(R.id.back_btn).setOnClickListener(this);
findViewById(R.id.view_list).setOnClickListener(this);
// findViewById(R.id.view_detail).setOnClickListener(this);
// findViewById(R.id.view_all).setOnClickListener(this);
findViewById(R.id.message).setOnClickListener(this);
findViewById(R.id.call).setOnClickListener(this);
// mOrderIdEdit = findViewById(R.id.orderId);
// mOrderIdEdit.setText(LocalConfig.DefaultCallOrderId);
findViewById(R.id.set_location).setOnClickListener(v -> setLocation());
// findViewById(R.id.hang_up).setOnClickListener(v -> {
// HangUp.doHangup(() -> {
// Logger.e("do hangup listener =============");
// Toast.makeText(this, "已经触发挂断回调", Toast.LENGTH_SHORT).show();
// });
// });
}
@Override
public void onClick(View v) {
switch (v.getId()) {
// case R.id.all_btn:
// callAdult();
// break;
// case R.id.child_btn:
// callChild();
// break;
// case R.id.view_all:
// viewAll();
// break;
case R.id.view_list:
viewList();
break;
// case R.id.view_detail:
// viewDetail();
// break;
// case R.id.back_btn:
// HHDoctor.logOut(this);
// LocalConfig.setLoginedToken(this, "");
// finish();
// break;
case R.id.message:
forwardMessage();
break;
case R.id.call:
selectCall();
break;
// case R.id.multi_video:
// forwardMultiVideo();
// break;
default:
break;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.call_selector_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.logout:
logout();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
HHDemoUtils.notice(this,getString(R.string.hp_notice_depart));
}
@Override
public void onResume() {
super.onResume();
if (!noticeTTS) {
HHDemoUtils.notice(this,getString(R.string.hp_notice_depart));
}
noticeTTS = true;
}
/**
* 呼叫成人医生
*/
// private void callAdult() {
//
//// CallExtensionSetting.setJsonExtMessage("callAdult");
//
// HHDoctor.callForAdult(this, new HHCallExListener() {
//
// @Override
// public void onLoadDoctor(HHCallInfo callInfo) {
//
// }
//
// @Override
// public void onDoctorAgree() {
//
//// testFrontView();
// }
//
// @Override
// public void onCallError(String error) {
//
// }
//
// @Override
// public void onStart(String orderId) {
// Log.i(TAG,"call onStart");
// }
//
// @Override
// public void onCalling() {
// Log.i(TAG,"call onCalling");
// }
//
// @Override
// public void onInTheCall() {
// Log.i(TAG,"call onInTheCall");
// }
//
// @Override
// public void onFinish() {
// Log.i(TAG,"call onFinish");
// }
//
// @Override
// public void onCallSuccess() {
// Log.i(TAG,"call onCallSuccess");
// }
//
// @Override
// public void onFail(int i) {
// Log.i(TAG,"call onFail");
// }
//
// @Override
// public void onCancel() {
// Log.i(TAG,"call onCancel");
// }
//
// @Override
// public void onLineUpTimeout() {
// Log.i(TAG,"call onLineUpTimeout");
// }
//
// @Override
// public void onLineUp() {
// Log.i(TAG,"call onLineUp");
// }
// });
// }
/**
* 呼叫儿童医生
*/
// private void callChild() {
//// CallExtensionSetting.setJsonExtMessage("callChild");
// HHDoctor.callForChild(this, new HHCallListener() {
//
// @Override
// public void onStart(String orderId) {
// Log.i(TAG,"call onStart");
// }
//
// @Override
// public void onCalling() {
// Log.i(TAG,"call onCalling");
// }
//
// @Override
// public void onInTheCall() {
// Log.i(TAG,"call onInTheCall");
// }
//
// @Override
// public void onFinish() {
// Log.i(TAG,"call onFinish");
// }
//
// @Override
// public void onCallSuccess() {
// Log.i(TAG,"call onCallSuccess");
// }
//
// @Override
// public void onFail(int i) {
// Log.i(TAG,"call onFail");
// }
//
// @Override
// public void onCancel() {
// Log.i(TAG,"call onCancel");
// }
//
// @Override
// public void onLineUpTimeout() {
// Log.i(TAG,"call onLineUpTimeout");
// }
//
// @Override
// public void onLineUp() {
// Log.i(TAG,"call onLineUp");
// }
// });
// }
// private void forwardMultiVideo() {
// Intent intent = new Intent(this, MultiVideoAct.class);
// startActivity(intent);
// }
/**
* 查看所有成员病历存档列表
*/
// private void viewAll() {
// Intent intent = new Intent(this, ViewDetailAct.class);
// String url = HHDoctor.getAllMedics(this, LocalConfig.getLoginedToken(this));
// Log.e("list url", url);
// intent.putExtra("url", url);
// intent.putExtra("title", "病历存档列表");
// startActivity(intent);
// }
/**
* 查看病历存档列表
*/
private void viewList() {
Intent intent = new Intent(this, ViewDetailAct.class);
String url = HHDoctor.getMedicListUrl(this, LocalConfig.getLoginedToken(this));
Log.e("list url", url);
intent.putExtra("url", url);
intent.putExtra("title", "病历存档列表");
startActivity(intent);
}
/**
* 查看病历存档详情
*/
// private void viewDetail() {
// String orderId = mOrderIdEdit.getText().toString();
// if (orderId.isEmpty()) {
// Toast.makeText(this, "请提供病历订单号", Toast.LENGTH_SHORT).show();
// return;
// }
// Intent intent = new Intent(this, ViewDetailAct.class);
// String url = HHDoctor.getMedicDetailUrl(this, LocalConfig.getLoginedToken(this), orderId);
// intent.putExtra("url", url);
// intent.putExtra("title", "病历存档详情");
// startActivity(intent);
// }
private void forwardMessage() {
HHDoctor.message(this);
}
private void selectCall() {
// CallExtensionSetting.setNormalExtMessage("selectCall");
HHDoctor.call(this, new HHCallListener() {
@Override
public void onStart(String orderId) {
}
@Override
public void onCalling() {
}
@Override
public void onInTheCall() {
}
@Override
public void onFinish() {
removeTestFrontView();
}
@Override
public void onCallSuccess() {
}
@Override
public void onFail(int code) {
removeTestFrontView();
}
@Override
public void onCancel() {
removeTestFrontView();
}
@Override
public void onLineUpTimeout() {
}
@Override
public void onLineUp() {
}
});
}
/**
* 使用购药功能需要设置经纬度
*/
private void setLocation() {
double lng = 0.0;
double lat = 0.0;
try {
lng = Double.parseDouble(((EditText)findViewById(R.id.lng)).getText().toString());
lat = Double.parseDouble(((EditText)findViewById(R.id.lat)).getText().toString());
} catch (Exception e) {
e.printStackTrace();
}
Location.sendLocation(this,lng,lat);
Toast.makeText(this, "经纬度已经发送", Toast.LENGTH_SHORT).show();
}
// private void testFrontView() {
// ChatFrontPop pop = new ChatFrontPop(this);
// View parent = HHDoctor.getChatParentView();
// pop.showAtLocation(parent, Gravity.NO_GRAVITY,0,0);
// mPop = pop;
// }
private void removeTestFrontView() {
if (mPop != null) {
mPop.dismiss();
mPop = null;
}
}
private void logout() {
HHDoctor.logOut(this);
LocalConfig.setLoginedToken(this, "");
finish();
}
}
... ...
package com.hhmedic.android.hhdoctorvideodemo.activity;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupWindow;
import android.widget.Toast;
import com.hhmedic.android.hhdoctorvideodemo.R;
import com.hhmedic.android.sdk.module.video.hangup.HangUp;
import com.orhanobut.logger.Logger;
public class ChatFrontPop extends PopupWindow {
public ChatFrontPop(Context context) {
super(context);
initView(context);
}
private void initView(Context context)
{
View view = LayoutInflater.from(context).inflate(R.layout.hh_chat_front_layout,null);
setContentView(view);
setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
setFocusable(true);
setOutsideTouchable(true);
setBackgroundDrawable(new ColorDrawable(0));
setClippingEnabled(false);
view.findViewById(R.id.close).setOnClickListener(v -> {
HangUp.doHangup(() -> {
Logger.e("do hangup listener =============");
Toast.makeText(context, "已经触发挂断回调", Toast.LENGTH_SHORT).show();
});
dismiss();
});
}
}
... ...
package com.hhmedic.android.hhdoctorvideodemo.activity;
public class HHSDKConfig {
public final static String pid = "9002";
}
... ...
package com.hhmedic.android.hhdoctorvideodemo.activity;
import android.content.Context;
import android.content.SharedPreferences;
import com.hhmedic.android.hhdoctorvideodemo.application.SharedPreferenceUtils;
public class LocalConfig {
private static final String KEY = "isDevelop";
private static final String USER_TOKEN = "demo_user_token";
private static final String PID = "pid";
private static final String ENABLE_ADD_MEMBER = "can_add_member";
private static final String ENABLE_MULTI_CALL = "enable_multi_call";
private static final String ENABLE_ACTIVATE = "enable_activate";
private static final String ENABLE_MEDICAL = "enable_medical";
private static final String ENABLE_USER_CENTER = "enable_user_center";
private static final String ENABLE_SUMMARY_CARD = "enable_summary_card";
private static final String ENABLE_MEDICAL_CARD = "enable_medical_card";
private static final String ENABLE_VIP_INFO = "enable_vip_info";
private static final String ENABLE_ADD_MEMBER_IN_DOC = "can_add_member_in_doc";
private static final String ENABLE_CAN_BUY = "can_buy";
private static final String HIDE_CAMERA_CONTROL = "hide_camera_control";
private static final String CLOSE_CAMERA_CALL = "close_camera_call";
private static final String CLOSE_MORE_FUNC = "close_more_func";
private static final String MESSAGE_TITLE = "message_title";
static final String DefaultUserToken = "64FF786AE1D0A319EB92840A39B108143F0D04F68EA2608F6783B874E4F50EEF";
static final String DefaultCallOrderId = "1559198060885";
static final String DefaultMedicineOrderId = "Y2019053014434215200";
static void setDevelop(Context context, Boolean isDevelop) {
SharedPreferenceUtils.setValue(context,KEY,isDevelop);
}
public static boolean isDevelop(Context context) {
return SharedPreferenceUtils.getBooleanValue(context,KEY,true);
}
static void setLoginedToken(Context context, String token) {
SharedPreferenceUtils.setValue(context,USER_TOKEN,token.trim());
}
static String getLoginedToken(Context context) {
return SharedPreferenceUtils.getStringValue(context,USER_TOKEN).trim();
}
public static void setPid(Context context,String pid) {
SharedPreferenceUtils.setValue(context,PID,pid);
}
public static String getPid(Context context) {
return SharedPreferenceUtils.getStringValue(context,PID);
}
public static void setEnableAddMember(Context context, Boolean canAddMember) {
SharedPreferenceUtils.setValue(context, ENABLE_ADD_MEMBER,canAddMember);
}
public static boolean getEnableAddMember(Context context) {
return SharedPreferenceUtils.getBooleanValue(context, ENABLE_ADD_MEMBER, true);
}
public static void setEnableMultiCall(Context context,boolean canAddMember) {
SharedPreferenceUtils.setValue(context, ENABLE_MULTI_CALL,canAddMember);
}
public static boolean getEnableMultiCall(Context context) {
return SharedPreferenceUtils.getBooleanValue(context, ENABLE_MULTI_CALL, true);
}
public static void setEnableActivate(Context context,boolean canAddMember) {
SharedPreferenceUtils.setValue(context, ENABLE_ACTIVATE,canAddMember);
}
public static boolean getEnableActivate(Context context) {
return SharedPreferenceUtils.getBooleanValue(context, ENABLE_ACTIVATE, true);
}
public static void setEnableMedical(Context context,boolean canAddMember) {
SharedPreferenceUtils.setValue(context, ENABLE_MEDICAL,canAddMember);
}
public static boolean getEnableMedical(Context context) {
return SharedPreferenceUtils.getBooleanValue(context, ENABLE_MEDICAL, true);
}
public static void setMessageTitle(Context context,String title) {
SharedPreferenceUtils.setValue(context,MESSAGE_TITLE,title);
}
public static String getMessageTitle(Context context) {
return SharedPreferenceUtils.getStringValue(context,MESSAGE_TITLE);
}
public static void setEnableUserCenter(Context context,boolean enable) {
SharedPreferenceUtils.setValue(context, ENABLE_USER_CENTER,enable);
}
public static boolean getEnableUserCenter(Context context) {
return SharedPreferenceUtils.getBooleanValue(context, ENABLE_USER_CENTER, true);
}
public static void setEnableSummaryCard(Context context,boolean enable) {
SharedPreferenceUtils.setValue(context, ENABLE_SUMMARY_CARD,enable);
}
public static boolean getEnableSummaryCard(Context context) {
return SharedPreferenceUtils.getBooleanValue(context, ENABLE_SUMMARY_CARD, true);
}
public static void setEnableMedicalCard(Context context,boolean canAddMember) {
SharedPreferenceUtils.setValue(context, ENABLE_MEDICAL_CARD,canAddMember);
}
public static Boolean getEnableMedicalCard(Context context) {
return SharedPreferenceUtils.getBooleanValue(context, ENABLE_MEDICAL_CARD, true);
}
public static void setEnableVipInfo(Context context,boolean canShowVipInfo){
SharedPreferenceUtils.setValue(context, ENABLE_VIP_INFO,canShowVipInfo);
}
public static boolean getEnableVipInfo(Context context) {
return SharedPreferenceUtils.getBooleanValue(context, ENABLE_VIP_INFO, true);
}
public static void setEnableAddMemberInDoc(Context context,boolean canShowVipInfo){
SharedPreferenceUtils.setValue(context, ENABLE_ADD_MEMBER_IN_DOC,canShowVipInfo);
}
public static boolean getEnableAddMemberInDoc(Context context) {
return SharedPreferenceUtils.getBooleanValue(context, ENABLE_ADD_MEMBER_IN_DOC, true);
}
public static void setEnableCanBuy(Context context,boolean canShowVipInfo){
SharedPreferenceUtils.setValue(context, ENABLE_CAN_BUY,canShowVipInfo);
}
public static boolean getEnableCanBuy(Context context) {
return SharedPreferenceUtils.getBooleanValue(context, ENABLE_CAN_BUY, true);
}
public static void setHideCameraControl(Context context,boolean canShowVipInfo){
SharedPreferenceUtils.setValue(context, HIDE_CAMERA_CONTROL,canShowVipInfo);
}
public static boolean getHideCameraControl(Context context) {
return SharedPreferenceUtils.getBooleanValue(context, HIDE_CAMERA_CONTROL, false);
}
public static void setCloseCameraCall(Context context,boolean canShowVipInfo){
SharedPreferenceUtils.setValue(context, CLOSE_CAMERA_CALL,canShowVipInfo);
}
public static boolean getCloseCameraCall(Context context) {
return SharedPreferenceUtils.getBooleanValue(context, CLOSE_CAMERA_CALL, false);
}
public static void setCloseMoreFunc(Context context, boolean close) {
SharedPreferenceUtils.setValue(context, CLOSE_MORE_FUNC, close);
}
public static boolean getCloseMoreFunc(Context context) {
return SharedPreferenceUtils.getBooleanValue(context, CLOSE_MORE_FUNC, false);
}
}
... ...
package com.hhmedic.android.hhdoctorvideodemo.activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import com.hhmedic.android.hhdoctorvideodemo.R;
import com.hhmedic.android.sdk.HHDoctor;
import com.hhmedic.android.sdk.config.HHSDKOptions;
import com.hhmedic.android.sdk.config.MessageOptions;
import com.hhmedic.android.sdk.listener.HHLoginListener;
import com.orhanobut.logger.Logger;
import java.util.HashMap;
public class MainActivity extends BaseActivity {
private EditText mUserTokenEdit;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected int contentViewId() {
return R.layout.activity_main;
}
@Override
protected void initUI() {
super.initUI();
initActionBar(findViewById(R.id.toolbar));
setTitle(R.string.login_button);
findViewById(R.id.login_button).setOnClickListener(v -> login());
mUserTokenEdit = findViewById(R.id.userToken);
findViewById(R.id.is_in_develop).setVisibility(LocalConfig.isDevelop(this) ? View.VISIBLE : View.GONE);
findViewById(R.id.use_default_toke).setOnClickListener(v -> mUserTokenEdit.setText(LocalConfig.DefaultUserToken));
findViewById(R.id.login_third_button).setOnClickListener(view -> loginWithThirdId());
findViewById(R.id.init_sdk).setOnClickListener(view -> initSDK());
}
private void login() {
doLogin();
}
private void doLogin() {
String userToken = mUserTokenEdit.getText().toString().trim(); //这个ID是和和缓对接之后得到的和缓的UserToken
if (userToken.isEmpty()) {
Toast.makeText(this, "请输入需要登录的userToken", Toast.LENGTH_SHORT).show();
return;
}
loginWithToken(userToken);
}
private void loginWithToken(String userToken) {
LocalConfig.setLoginedToken(this, userToken);
HHDoctor.login(this, userToken, new HHLoginListener() {
@Override
public void onSuccess() {
loginForward();
}
@Override
public void onError(String s) {
Logger.e(s);
Toast.makeText(MainActivity.this, "请确保参数使用环境,不要使用非正式环境参数访问正式环境" + s, Toast.LENGTH_SHORT).show();
}
});
}
private void loginWithThirdId() {
String uid = ((EditText)findViewById(R.id.uid)).getText().toString().trim();
String time = ((EditText)findViewById(R.id.time)).getText().toString().trim();
String secret = ((EditText)findViewById(R.id.secret)).getText().toString().trim();
if (TextUtils.isEmpty(uid) || TextUtils.isEmpty(time) || TextUtils.isEmpty(secret)) {
Toast.makeText(this, "请输入所必须的参数再进行登录操作", Toast.LENGTH_SHORT).show();
return;
}
HashMap<String,Object> hashMap = new HashMap<>();
hashMap.put("uid",uid);
hashMap.put("time", time);
hashMap.put("secret", secret);
HHDoctor.loginForThirdId(this, hashMap, new HHLoginListener() {
@Override
public void onSuccess() {
// loginForward();
}
@Override
public void onError(String tips) {
Logger.e(tips);
Toast.makeText(MainActivity.this, tips, Toast.LENGTH_SHORT).show();
}
});
}
private void initSDK() {
initSDK(this);
}
/**
* 跳转选择呼叫类型界面
*/
private void loginForward() {
Intent intent = new Intent(this, CallSelectorAct.class);
startActivity(intent);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.main_setting_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.setting:
Intent settingIntent = new Intent(this, SettingAct.class);
startActivity(settingIntent);
return true;
}
return super.onOptionsItemSelected(item);
}
public static void initSDK(Context context) {
String pid = LocalConfig.getPid(context);
if (TextUtils.isEmpty(pid)) {
pid = HHSDKConfig.pid;
}
HHSDKOptions options = new HHSDKOptions(pid); //productId是视频医生提供方分配的产品Id
options.isDebug = true;
options.dev = LocalConfig.isDevelop(context);
options.enableAddMember = LocalConfig.getEnableAddMember(context);
options.enableMultiCall = LocalConfig.getEnableMultiCall(context);
options.messageTitle = LocalConfig.getMessageTitle(context);
options.enableMedical = LocalConfig.getEnableMedical(context);
options.enableActivate = LocalConfig.getEnableActivate(context);
options.enableVipInfo = LocalConfig.getEnableVipInfo(context);
options.enableAddMemberInDoc = LocalConfig.getEnableAddMemberInDoc(context);
options.enableCloseCamera = LocalConfig.getHideCameraControl(context);
options.isCloseCameraCall = LocalConfig.getCloseCameraCall(context);
options.isCloseMoreFunc = LocalConfig.getCloseMoreFunc(context);
// options.localRenderRotation = TRTCCloudDef.TRTC_VIDEO_ROTATION_90;
MessageOptions messageOptions = new MessageOptions();
messageOptions.hideUserCenter = LocalConfig.getEnableUserCenter(context);
messageOptions.isFilterSummary = LocalConfig.getEnableSummaryCard(context);
messageOptions.isFilterMedicinal = LocalConfig.getEnableMedicalCard(context);
messageOptions.enableBuyService = LocalConfig.getEnableCanBuy(context);
options.messageOptions = messageOptions;
// VideoSetting.setEnableGSENSORMode(false);
// VideoSetting.setRemoteRotation(TRTCCloudDef.TRTC_VIDEO_ROTATION_90);
HHDoctor.init(context, options);
}
}
... ...
package com.hhmedic.android.hhdoctorvideodemo.activity;
import androidx.databinding.DataBindingUtil;
import android.os.Bundle;
import androidx.annotation.Nullable;
import com.hhmedic.android.hhdoctorvideodemo.R;
import com.hhmedic.android.hhdoctorvideodemo.databinding.ActivityMultiVideoBinding;
import com.hhmedic.android.sdk.HHDoctor;
import com.hhmedic.android.sdk.module.call.CallType;
import com.hhmedic.android.sdk.video.multi.entity.HHInviteUser;
public class MultiVideoAct extends BaseActivity {
public ActivityMultiVideoBinding mBinding;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBinding = DataBindingUtil.setContentView(this,R.layout.activity_multi_video);
setContentView(mBinding.getRoot());
}
@Override
protected boolean useDataBinding() {
return true;
}
@Override
protected void initUI() {
super.initUI();
initActionBar(mBinding.toolbar);
mBinding.startCall.setOnClickListener( view -> startCall());
}
private void startCall() {
String userToken = mBinding.editUserToken.getText().toString();
String userName = mBinding.editUserName.getText().toString();
String userPhoto = mBinding.editUserPhoto.getText().toString();
HHInviteUser inviteUser = new HHInviteUser(userToken);
inviteUser.setNickName(userName);
inviteUser.setPhotoUrl(userPhoto);
HHDoctor.multiCall(this, CallType.all,inviteUser);
}
}
... ...
package com.hhmedic.android.hhdoctorvideodemo.activity;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;
import androidx.appcompat.widget.SwitchCompat;
import androidx.databinding.DataBindingUtil;
import com.hhmedic.android.hhdoctorvideodemo.R;
import com.hhmedic.android.hhdoctorvideodemo.application.DoctorApplication;
import com.hhmedic.android.hhdoctorvideodemo.databinding.ActivitySettingLayoutBinding;
import com.hhmedic.android.sdk.HHDoctor;
public class SettingAct extends BaseActivity {
private ActivitySettingLayoutBinding mBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected void initUI() {
super.initUI();
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_setting_layout);
initActionBar(mBinding.toolbarLayout.toolbar);
setTitle(R.string.activity_setting_title);
SwitchCompat mIsDevelopSwitch = mBinding.developSwitch;
mIsDevelopSwitch.setChecked(LocalConfig.isDevelop(this));
mIsDevelopSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
LocalConfig.setDevelop(this, isChecked);
switchReload();
});
SwitchCompat mCanAddSwitch = mBinding.canAddMember;
mCanAddSwitch.setChecked(LocalConfig.getEnableAddMember(this));
mCanAddSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
LocalConfig.setEnableAddMember(this, isChecked);
switchReload();
});
SwitchCompat mEnableMultiCallSwitch = mBinding.enableMultiCall;
mEnableMultiCallSwitch.setChecked(LocalConfig.getEnableMultiCall(this));
mEnableMultiCallSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
LocalConfig.setEnableMultiCall(this, isChecked);
switchReload();
});
SwitchCompat mEnableActivate = mBinding.enableActivate;
mEnableActivate.setChecked(LocalConfig.getEnableActivate(this));
mEnableActivate.setOnCheckedChangeListener((buttonView, isChecked) -> {
LocalConfig.setEnableActivate(this, isChecked);
switchReload();
});
SwitchCompat mEnableMedical = mBinding.enableMedical;
mEnableMedical.setChecked(LocalConfig.getEnableMedical(this));
mEnableMedical.setOnCheckedChangeListener((buttonView, isChecked) -> {
LocalConfig.setEnableMedical(this, isChecked);
switchReload();
});
SwitchCompat mEnableUserCenter = mBinding.enableUserCenter;
mEnableUserCenter.setChecked(LocalConfig.getEnableUserCenter(this));
mEnableUserCenter.setOnCheckedChangeListener((buttonView, isChecked) -> {
LocalConfig.setEnableUserCenter(this, isChecked);
switchReload();
});
SwitchCompat mEnableSummaryCard = mBinding.enableSummaryCard;
mEnableSummaryCard.setChecked(LocalConfig.getEnableSummaryCard(this));
mEnableSummaryCard.setOnCheckedChangeListener((buttonView, isChecked) -> {
LocalConfig.setEnableSummaryCard(this, isChecked);
switchReload();
});
SwitchCompat mEnableMedicalCard = mBinding.enableMedicalCard;
mEnableMedicalCard.setChecked(LocalConfig.getEnableMedicalCard(this));
mEnableMedicalCard.setOnCheckedChangeListener((buttonView, isChecked) -> {
LocalConfig.setEnableMedicalCard(this, isChecked);
switchReload();
});
SwitchCompat mEnableVipInfo = mBinding.enableVipInfo;
mEnableVipInfo.setChecked(LocalConfig.getEnableVipInfo(this));
mEnableVipInfo.setOnCheckedChangeListener((buttonView, isChecked) -> {
LocalConfig.setEnableVipInfo(this, isChecked);
switchReload();
});
SwitchCompat mEnableAddMemberInDoc = mBinding.canAddMemberInDoc;
mEnableAddMemberInDoc.setChecked(LocalConfig.getEnableAddMemberInDoc(this));
mEnableAddMemberInDoc.setOnCheckedChangeListener((buttonView, isChecked) -> {
LocalConfig.setEnableAddMemberInDoc(this, isChecked);
switchReload();
});
SwitchCompat mEnableCanBuy = mBinding.canBuy;
mEnableCanBuy.setChecked(LocalConfig.getEnableCanBuy(this));
mEnableCanBuy.setOnCheckedChangeListener((buttonView, isChecked) -> {
LocalConfig.setEnableCanBuy(this, isChecked);
switchReload();
});
SwitchCompat mHideCameraControl = mBinding.hideCameraControl;
mHideCameraControl.setChecked(LocalConfig.getHideCameraControl(this));
mHideCameraControl.setOnCheckedChangeListener((buttonView, isChecked) -> {
LocalConfig.setHideCameraControl(this, isChecked);
switchReload();
});
SwitchCompat mCloseCameraCall = mBinding.closeCameraCall;
mCloseCameraCall.setChecked(LocalConfig.getCloseCameraCall(this));
mCloseCameraCall.setOnCheckedChangeListener((buttonView, isChecked) -> {
LocalConfig.setCloseCameraCall(this, isChecked);
switchReload();
});
SwitchCompat mCloseMoreFunc = mBinding.closeMoreFunc;
mCloseMoreFunc.setChecked(LocalConfig.getCloseMoreFunc(this));
mCloseMoreFunc.setOnCheckedChangeListener((buttonView, isChecked) -> {
LocalConfig.setCloseMoreFunc(this, isChecked);
switchReload();
});
findViewById(R.id.is_in_develop).setVisibility(LocalConfig.isDevelop(this) ? View.VISIBLE : View.GONE);
mBinding.pid.setText(LocalConfig.getPid(this));
mBinding.buttonSetPid.setOnClickListener(v -> {
String pid = mBinding.pid.getText().toString();
if (TextUtils.isEmpty(pid)) {
Toast.makeText(SettingAct.this, "请填写需要设置的PID", Toast.LENGTH_SHORT).show();
return;
}
LocalConfig.setPid(this, pid);
switchReload();
});
String message_title = LocalConfig.getMessageTitle(this);
if (!TextUtils.isEmpty(message_title)) {
mBinding.messageTitle.setText(message_title);
}
mBinding.buttonSetMessageTitle.setOnClickListener(v -> {
String title = mBinding.messageTitle.getText().toString();
if (TextUtils.isEmpty(title)) {
Toast.makeText(SettingAct.this, "请填写需要设置的Message 界面的Title", Toast.LENGTH_SHORT).show();
return;
}
LocalConfig.setMessageTitle(this, title);
switchReload();
});
mBinding.buttonSetExtMessage.setOnClickListener(v -> {
String message = mBinding.extMessage.getText().toString();
if (TextUtils.isEmpty(message)) {
Toast.makeText(SettingAct.this, "请填写需要设置的呼叫传入的附加信息", Toast.LENGTH_SHORT).show();
return;
}
HHDoctor.setExtension(message);
Toast.makeText(SettingAct.this, "设置完成", Toast.LENGTH_SHORT).show();
});
}
private void switchReload() {
// Toast.makeText(SettingAct.this, "切换设置后需要重启打开APP才会生效", Toast.LENGTH_SHORT).show();
// new Handler().postDelayed(() -> System.exit(0), 1000);
DoctorApplication.initSDK(getApplicationContext());
Toast.makeText(SettingAct.this, "设置参数已经生效", Toast.LENGTH_SHORT).show();
}
@Override
protected boolean useDataBinding() {
return true;
}
}
\ No newline at end of file
... ...
package com.hhmedic.android.hhdoctorvideodemo.activity;
import android.content.Intent;
import android.os.Build;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.TextView;
import com.hhmedic.android.hhdoctorvideodemo.R;
import static android.view.KeyEvent.KEYCODE_BACK;
public class ViewDetailAct extends AppCompatActivity {
private WebView mWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_detail);
initUI(getIntent());
}
private void initUI(Intent intent) {
findViewById(R.id.back_btn).setOnClickListener(v -> {
if (mWebView.canGoBack()) {
mWebView.goBack();
return;
}
finish();
});
TextView textView = findViewById(R.id.title);
textView.setText(intent.getStringExtra("title"));
mWebView = findViewById(R.id.webView);
configWeb(mWebView);
mWebView.loadUrl(intent.getStringExtra("url"));
}
private void configWeb(WebView webView)
{
if (webView == null) {
mWebView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
mWebView.clearHistory();
((ViewGroup) mWebView.getParent()).removeView(mWebView);
mWebView.destroy();
mWebView = null;
return;
}
WebSettings settings = webView.getSettings();
settings.setAppCacheEnabled(true);
settings.setCacheMode(WebSettings.LOAD_DEFAULT);
settings.setJavaScriptEnabled(true);
settings.setLoadWithOverviewMode(true);
settings.setUseWideViewPort(true);
settings.setDomStorageEnabled(true);
//开启 database storage API 功能
settings.setDatabaseEnabled(true);
settings.setSupportZoom(true);
settings.setUseWideViewPort(true);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KEYCODE_BACK && mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
protected void onDestroy() {
if (mWebView != null) {
}
super.onDestroy();
}
}
... ...
package com.hhmedic.android.hhdoctorvideodemo.application;
/**
* Created by iOS on 2018/3/20.
*
*
*/
public class Command
{
public static final String REFUSE = "REFUSE";
public static final String CANCEL = "CANCEL";
public static final String ACCEPT = "ACCEPT";
public static final String DEPT_ADULT = "ADULT";
public static final String DEPT_CHILD = "CHILD";
}
... ...
package com.hhmedic.android.hhdoctorvideodemo.application;
import android.app.Application;
import android.content.Context;
import android.text.TextUtils;
import androidx.multidex.MultiDex;
import com.hhmedic.android.hhdoctorvideodemo.activity.HHSDKConfig;
import com.hhmedic.android.hhdoctorvideodemo.activity.LocalConfig;
import com.hhmedic.android.sdk.HHDoctor;
import com.hhmedic.android.sdk.config.HHSDKOptions;
import com.hhmedic.android.sdk.config.MessageOptions;
import com.tencent.bugly.Bugly;
public class DoctorApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(base);
}
@Override
public void onCreate() {
super.onCreate();
initSDK(getApplicationContext());
// initTim();
Bugly.init(getApplicationContext(), "f9b08d0fa3", false);
}
public static void initSDK(Context context) {
String pid = LocalConfig.getPid(context);
if (TextUtils.isEmpty(pid)) {
pid = HHSDKConfig.pid;
}
HHSDKOptions options = new HHSDKOptions(pid); //productId是视频医生提供方分配的产品Id
options.isDebug = true;
options.dev = LocalConfig.isDevelop(context);
options.enableAddMember = LocalConfig.getEnableAddMember(context);
options.enableMultiCall = LocalConfig.getEnableMultiCall(context);
options.messageTitle = LocalConfig.getMessageTitle(context);
options.enableMedical = LocalConfig.getEnableMedical(context);
options.enableActivate = LocalConfig.getEnableActivate(context);
options.enableVipInfo = LocalConfig.getEnableVipInfo(context);
options.enableAddMemberInDoc = LocalConfig.getEnableAddMemberInDoc(context);
options.enableCloseCamera = LocalConfig.getHideCameraControl(context);
options.isCloseCameraCall = LocalConfig.getCloseCameraCall(context);
options.isCloseMoreFunc = LocalConfig.getCloseMoreFunc(context);
MessageOptions messageOptions = new MessageOptions();
messageOptions.hideUserCenter = LocalConfig.getEnableUserCenter(context);
messageOptions.isFilterSummary = LocalConfig.getEnableSummaryCard(context);
messageOptions.isFilterMedicinal = LocalConfig.getEnableMedicalCard(context);
messageOptions.enableBuyService = LocalConfig.getEnableCanBuy(context);
options.messageOptions = messageOptions;
HHDoctor.init(context, options);
}
}
... ...
package com.hhmedic.android.hhdoctorvideodemo.application;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.orhanobut.logger.Logger;
/**
* Created by iOS on 2018/3/21.
*
*
*/
public class HHDemoUtils
{
public static void notice(Context context,String text)
{
try
{
Log.e("notice message",text);
Intent aIntent = new Intent(Actions.NOTICE);
aIntent.putExtra(Keys.MESSAGE,text);
context.sendBroadcast(aIntent);
}
catch (Exception e)
{
Logger.e(e.toString());
}
}
/**
* 请求权限
* @param context context
*/
public static void requestPermission(Context context)
{
try
{
Log.e("HHDoctor","request permission");
Intent aIntent = new Intent(Actions.PERMISSION);
context.sendBroadcast(aIntent);
}
catch (Exception e)
{
Logger.e(e.toString());
}
}
static class Actions
{
/**
* 通知
*/
static final String NOTICE = "com.hhmedic.doctor.notify";
/**
* 申请权限通知
*/
static final String PERMISSION = "com.hhmedic.doctor.focus";
}
public static class Keys
{
static final String MESSAGE = "message";
}
}
... ...
package com.hhmedic.android.hhdoctorvideodemo.application;
import android.content.Context;
import android.content.SharedPreferences;
public class SharedPreferenceUtils {
private static final String PREFERENCE_NAME = "HH_SDK_DEMO";
public static void setValue(Context context,String key,String value) {
SharedPreferences.Editor editor = getEditor(context);
editor.putString(key, value);
editor.apply();
}
public static void setValue(Context context,String key,Boolean value) {
SharedPreferences.Editor editor = getEditor(context);
editor.putBoolean(key, value);
editor.apply();
}
public static String getStringValue(Context context,String key) {
return getSharePreference(context).getString(key,"");
}
public static boolean getBooleanValue(Context context,String key,boolean defaultValue) {
return getSharePreference(context).getBoolean(key, defaultValue);
}
private static SharedPreferences getSharePreference(Context context) {
return context.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE);
}
private static SharedPreferences.Editor getEditor(Context context) {
SharedPreferences preferences = getSharePreference(context);
return preferences.edit();
}
}
... ...
package com.hhmedic.android.hhdoctorvideodemo.receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import com.hhmedic.android.sdk.HHDoctor;
import com.orhanobut.logger.Logger;
/**
* Created by iOS on 2018/3/19.
*
*
*/
public class Controller extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
Logger.e("get controller");
String command = intent.getStringExtra("command");
if (!TextUtils.isEmpty(command))
{
// HHDoctor.hangUp();
}
}
}
... ...
package com.hhmedic.android.hhdoctorvideodemo.receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import com.hhmedic.android.hhdoctorvideodemo.application.Command;
import com.hhmedic.android.hhdoctorvideodemo.application.HHDemoUtils;
import com.hhmedic.android.sdk.HHDoctor;
import com.hhmedic.android.sdk.listener.HHCallListener;
/**
* Created by iOS on 2018/3/20.
*
*
*/
public class DepartReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
String command = intent.getStringExtra("command");
if (!TextUtils.isEmpty(command))
{
switch (command) {
case Command.DEPT_ADULT:
HHDoctor.callForAdult(context, new HHCallListener() {
@Override
public void onStart(String orderId) {
}
@Override
public void onCalling() {
}
@Override
public void onInTheCall() {
}
@Override
public void onFinish() {
}
@Override
public void onCallSuccess() {
}
@Override
public void onFail(int i) {
}
@Override
public void onCancel() {
}
@Override
public void onLineUpTimeout() {
}
@Override
public void onLineUp() {
}
});
break;
case Command.DEPT_CHILD:
HHDoctor.callForChild(context, new HHCallListener() {
@Override
public void onStart(String orderId) {
}
@Override
public void onCalling() {
}
@Override
public void onInTheCall() {
}
@Override
public void onFinish() {
}
@Override
public void onCallSuccess() {
}
@Override
public void onFail(int i) {
}
@Override
public void onCancel() {
}
@Override
public void onLineUpTimeout() {
}
@Override
public void onLineUp() {
}
});
break;
default:
break;
}
}
}
}
... ...
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</vector>
... ...
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@android:color/black"/>
</shape>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/hp_blue_btn_bg_disable" android:state_enabled="false" />
<item android:drawable="@drawable/hp_blue_btn_bg_press" android:state_pressed="true" />
<item android:drawable="@drawable/hp_blue_btn_bg_normal" />
</selector>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dp"/>
<solid android:color="#ffb6deff"/>
</shape>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dp"/>
<solid android:color="@color/hp_color"/>
</shape>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dp"/>
<solid android:color="#ff009dee"/>
</shape>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/hp_depart_icon_all_press" />
<item android:drawable="@drawable/hp_depart_icon_all" />
</selector>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/hp_depart_icon_child_press" />
<item android:drawable="@drawable/hp_depart_icon_child" />
</selector>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillColor="#26A69A"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
</vector>
... ...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent" android:background="@android:color/transparent">
</LinearLayout>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:fitsSystemWindows="true"
android:orientation="vertical">
<include layout="@layout/demo_toolbar" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusableInTouchMode="true"
android:orientation="vertical"
android:paddingStart="10dp"
android:paddingTop="20dp"
android:paddingEnd="10dp"
android:paddingBottom="10dp">
<!-- <RelativeLayout-->
<!-- android:id="@+id/title_layout"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content">-->
<!-- <Button-->
<!-- android:id="@+id/back_btn"-->
<!-- style="@style/hh_btn_style"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:contentDescription="@string/app_name"-->
<!-- android:text="@string/logout_button"-->
<!-- android:textSize="16sp" />-->
<!-- <TextView-->
<!-- android:id="@+id/title"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_centerHorizontal="true"-->
<!-- android:layout_centerVertical="true"-->
<!-- android:text="@string/hp_main_title"-->
<!-- android:textColor="@color/colorPrimary"-->
<!-- android:textSize="24sp" />-->
<!-- </RelativeLayout>-->
<TextView
android:id="@+id/is_in_develop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:text="@string/tip_is_in_develop"
android:textColor="@android:color/holo_red_dark" />
<LinearLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="30dp"
android:baselineAligned="false"
android:gravity="start"
android:orientation="vertical">
<!-- <Button-->
<!-- android:id="@+id/multi_video"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="@string/hp_multi_video"-->
<!-- android:textColor="@color/colorPrimary"-->
<!-- android:textSize="20sp" />-->
<!-- <Button-->
<!-- android:id="@+id/child_btn"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginTop="@dimen/dp_10"-->
<!-- android:text="@string/call_child"-->
<!-- android:textColor="@color/colorPrimary"-->
<!-- android:textSize="20sp" />-->
<!-- <Button-->
<!-- android:id="@+id/all_btn"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginTop="@dimen/dp_10"-->
<!-- android:text="@string/call_adult"-->
<!-- android:textColor="@color/colorPrimary"-->
<!-- android:textSize="20sp" />-->
<!-- <Button-->
<!-- android:id="@+id/view_all"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginTop="@dimen/dp_10"-->
<!-- android:text="@string/hp_view_order_list_all"-->
<!-- android:textColor="@color/colorPrimary"-->
<!-- android:textSize="20sp" />-->
<!-- <Button-->
<!-- android:id="@+id/view_list"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginTop="@dimen/dp_10"-->
<!-- android:text="@string/hp_view_list"-->
<!-- android:textColor="@color/colorPrimary"-->
<!-- android:textSize="20sp" />-->
<!-- <LinearLayout-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:orientation="horizontal">-->
<!-- <EditText-->
<!-- android:id="@+id/orderId"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginStart="15dp"-->
<!-- android:layout_weight="1"-->
<!-- android:hint="@string/hp_input_hint_order_id"-->
<!-- android:importantForAutofill="no"-->
<!-- android:inputType="text"-->
<!-- android:textSize="16sp" />-->
<!-- <Button-->
<!-- android:id="@+id/view_detail"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginTop="@dimen/dp_10"-->
<!-- android:layout_marginEnd="15dp"-->
<!-- android:text="@string/hp_view_detail"-->
<!-- android:textColor="@color/colorPrimary"-->
<!-- android:textSize="20sp" />-->
<!-- </LinearLayout>-->
<Button
android:id="@+id/message"
style="@style/demo_blue_button"
android:text="@string/hp_button_forward_message" />
<Button
android:id="@+id/call"
style="@style/demo_blue_button"
android:layout_marginTop="@dimen/dp_10"
android:text="@string/hp_button_select_call" />
<TextView
android:id="@+id/medicine_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginStart="15dp"
android:layout_marginTop="15dp"
android:text="@string/hp_buy_medicine_tips"
android:textColor="@color/hp_notify_red" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_10">
<EditText
android:id="@+id/lng"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="15dp"
android:layout_weight="1"
android:autofillHints="userToken"
android:hint="@string/hp_hint_location_lng"
android:inputType="text"
android:text="@string/hh_location_lng"
android:textSize="12sp" />
<EditText
android:id="@+id/lat"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="15dp"
android:layout_weight="1"
android:autofillHints="userToken"
android:hint="@string/hp_hint_location_lat"
android:inputType="text"
android:text="@string/hh_location_lat"
android:textSize="12sp" />
<Button
android:id="@+id/set_location"
style="@style/demo_blue_button"
android:minHeight="0dp"
android:text="@string/hp_button_set_location" />
</LinearLayout>
<Button
android:id="@+id/view_list"
style="@style/demo_blue_button"
android:layout_marginTop="@dimen/dp_15"
android:text="@string/hp_view_list"
android:textAllCaps="false" />
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:orientation="vertical"
android:fitsSystemWindows="true">
<include layout="@layout/demo_toolbar"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/dp_15"
android:layout_marginBottom="@dimen/dp_15">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/is_in_develop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:text="@string/tip_is_in_develop"
android:textColor="@android:color/holo_red_dark"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/userToken"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="15dp"
android:autofillHints="userToken"
android:hint="@string/input_user_token"
android:inputType="text"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/is_in_develop" />
<Button
android:id="@+id/use_default_toke"
style="@style/demo_blue_button"
android:text="@string/use_default_token"
android:textAllCaps="false"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/login_button"
app:layout_constraintTop_toBottomOf="@id/userToken" />
<Button
android:id="@+id/login_button"
style="@style/demo_blue_button"
android:text="@string/login_button"
app:layout_constraintLeft_toRightOf="@id/use_default_toke"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/userToken" />
<TextView
android:id="@+id/login_for_third_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:text="@string/login_for_third_id_info"
android:textColor="@android:color/black"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginTop="30dp"
app:layout_constraintTop_toBottomOf="@id/login_button" />
<EditText
android:id="@+id/uid"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="15dp"
android:autofillHints="userToken"
android:hint="@string/place_holder_uid"
android:inputType="text"
android:textSize="12sp"
android:text="425"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/login_for_third_id" />
<EditText
android:id="@+id/time"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="15dp"
android:autofillHints="userToken"
android:hint="@string/place_holder_time"
android:inputType="text"
android:textSize="12sp"
android:text="1640139588"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/uid" />
<EditText
android:id="@+id/secret"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="15dp"
android:autofillHints="userToken"
android:hint="@string/place_holder_secret"
android:inputType="text"
android:textSize="12sp"
android:text="6e899d7877958befe81756e24e4dfef1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/time" />
<Button
android:id="@+id/login_third_button"
style="@style/demo_blue_button"
android:text="@string/button_login_third_id"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/secret"
android:layout_marginTop="@dimen/dp_15"/>
<Button
android:id="@+id/init_sdk"
style="@style/demo_blue_button"
android:text="@string/init_sdk"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/login_third_button"
android:layout_marginTop="@dimen/dp_15"
android:visibility="gone"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</LinearLayout>
... ...
<?xml version="1.0" encoding="utf-8"?>
<layout>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.hhmedic.android.hhdoctorvideodemo.activity.MultiVideoAct">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="@dimen/hh_action_bar_height"
android:background="?attr/colorPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:theme="@style/Toolbar"
app:titleTextAppearance="@style/Toolbar.TitleText"
app:titleTextColor="@android:color/white" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar">
<TextView
style="@style/input_title"
android:text="@string/hp_tip_edit_user_token" />
<EditText
android:id="@+id/edit_user_token"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hp_tip_edit_user_token"
android:importantForAutofill="no"
android:inputType="text" />
<TextView
style="@style/input_title"
android:text="@string/hp_tip_edit_user_name" />
<EditText
android:id="@+id/edit_user_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hp_tip_edit_user_name"
android:importantForAutofill="no"
android:inputType="text" />
<TextView
style="@style/input_title"
android:text="@string/hp_tip_edit_user_photo" />
<EditText
android:id="@+id/edit_user_photo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hp_tip_edit_user_photo"
android:importantForAutofill="no"
android:inputType="text" />
<Button
android:id="@+id/start_call"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_10"
android:layout_marginStart="@dimen/dp_10"
android:text="@string/hp_button_start_multi_video"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
... ...
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<include
android:id="@+id/toolbar_layout"
layout="@layout/demo_toolbar" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/dp_15"
android:layout_marginBottom="@dimen/dp_15">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/is_in_develop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:text="@string/tip_is_in_develop"
android:textColor="@android:color/holo_red_dark"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/pid"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="15dp"
android:autofillHints="userToken"
android:hint="@string/hp_hint_pid"
android:inputType="text"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/is_in_develop" />
<Button
android:id="@+id/button_set_pid"
style="@style/demo_blue_button"
android:text="@string/hp_button_set_pid"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/pid" />
<EditText
android:id="@+id/message_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="15dp"
android:autofillHints="userToken"
android:hint="@string/hp_edit_hint_message_title"
android:inputType="text"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_set_pid" />
<Button
android:id="@+id/button_set_message_title"
style="@style/demo_blue_button"
android:text="@string/hp_button_set_message_title"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/message_title" />
<EditText
android:id="@+id/ext_message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="15dp"
android:autofillHints="userToken"
android:hint="@string/hp_edit_hint_ext_message"
android:inputType="text"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_set_message_title" />
<Button
android:id="@+id/button_set_ext_message"
style="@style/demo_blue_button"
android:text="@string/hp_button_set_ext_message"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/ext_message" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/enable_multi_call"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_10"
android:checked="true"
android:paddingStart="15dp"
android:paddingEnd="15dp"
android:text="@string/hp_switch_enable_multi_call"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_set_ext_message" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/can_add_member"
style="@style/config_switch"
android:checked="true"
android:text="@string/hp_switch_can_add_member"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/enable_multi_call" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/developSwitch"
style="@style/config_switch"
android:checked="true"
android:text="@string/is_develop"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/can_add_member" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/enable_activate"
style="@style/config_switch"
android:checked="true"
android:text="@string/hp_switch_enable_activate"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/developSwitch" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/enable_medical"
style="@style/config_switch"
android:checked="true"
android:text="@string/hp_switch_enable_medical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/enable_activate" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/enable_user_center"
style="@style/config_switch"
android:checked="true"
android:text="@string/hp_switch_enable_user_center"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/enable_medical" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/enable_summary_card"
style="@style/config_switch"
android:checked="true"
android:text="@string/hp_switch_enable_summary_card"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/enable_user_center" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/enable_medical_card"
style="@style/config_switch"
android:checked="true"
android:text="@string/hp_switch_enable_medical_card"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/enable_summary_card" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/enable_vip_info"
style="@style/config_switch"
android:checked="true"
android:text="@string/hp_switch_enable_vip_info"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/enable_medical_card" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/can_add_member_in_doc"
style="@style/config_switch"
android:checked="true"
android:text="@string/hp_switch_can_add_member_in_doc"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/enable_vip_info" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/can_buy"
style="@style/config_switch"
android:checked="true"
android:text="@string/hp_switch_can_buy"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/can_add_member_in_doc" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/hide_camera_control"
style="@style/config_switch"
android:checked="true"
android:text="@string/hp_switch_hide_camera_control"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/can_buy" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/close_camera_call"
style="@style/config_switch"
android:checked="true"
android:text="@string/hp_switch_close_camera_call"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/hide_camera_control" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/close_more_func"
style="@style/config_switch"
android:checked="true"
android:text="@string/hp_switch_close_more_func"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/close_camera_call" />
<!-- <EditText-->
<!-- android:id="@+id/userToken"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginStart="10dp"-->
<!-- android:layout_marginTop="15dp"-->
<!-- android:layout_marginEnd="15dp"-->
<!-- android:autofillHints="userToken"-->
<!-- android:hint="@string/input_user_token"-->
<!-- android:inputType="text"-->
<!-- android:textSize="12sp"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/close_camera_call" />-->
<!-- <Button-->
<!-- android:id="@+id/use_default_toke"-->
<!-- style="@style/demo_blue_button"-->
<!-- android:text="@string/use_default_token"-->
<!-- android:textAllCaps="false"-->
<!-- app:layout_constraintLeft_toLeftOf="parent"-->
<!-- app:layout_constraintRight_toLeftOf="@id/login_button"-->
<!-- app:layout_constraintTop_toBottomOf="@id/userToken" />-->
<!-- <Button-->
<!-- android:id="@+id/login_button"-->
<!-- style="@style/demo_blue_button"-->
<!-- android:text="@string/login_button"-->
<!-- app:layout_constraintLeft_toRightOf="@id/use_default_toke"-->
<!-- app:layout_constraintRight_toRightOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/userToken" />-->
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</LinearLayout>
</layout>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.hhmedic.android.hhdoctorvideodemo.activity.ViewDetailAct">
<include layout="@layout/hp_back_layout" />
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
... ...
<?xml version="1.0" encoding="utf-8"?>
<layout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="@dimen/hh_action_bar_height"
android:background="?attr/colorPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:theme="@style/Toolbar"
app:titleTextAppearance="@style/Toolbar.TitleText" />
<View style="@style/hh_toolbar_line" />
</LinearLayout>
</layout>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@android:color/holo_red_dark">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:id="@+id/close"
android:text="@string/button_close"/>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/title_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageButton
android:id="@+id/back_btn"
style="@style/hh_btn_style"
android:src="@drawable/hp_back_btn_bg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/app_name" />
<TextView
android:id="@+id/title"
android:textSize="24sp"
android:textColor="@color/colorPrimary"
android:text="@string/hp_main_title"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/logout"
android:title="@string/logout_button"
app:showAsAction="always"/>
</menu>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/setting"
android:title="@string/menu_setting"
app:showAsAction="always"/>
</menu>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#0c92f0</color>
<color name="colorPrimaryDark">#ff0082de</color>
<color name="colorAccent">#ff1482f0</color>
<color name="hp_color">#ff0592f5</color>
<color name="hp_vip_black_bg">#ff424559</color>
<color name="uikit_line_color">#ffd2d2d2</color>
<color name="hh_toolbar_bottom_line">#ffe4e4e4</color>
</resources>
... ...
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="hh_action_bar_height">46dp</dimen>
<dimen name="dp_10">10dp</dimen>
<dimen name="dp_15">15dp</dimen>
</resources>
\ No newline at end of file
... ...
<resources>
<string name="app_name">新Trtc Demo</string>
<string name="user_token">UserToken:</string>
<string name="input_user_token">请输入UserToken</string>
<string name="is_develop">测试环境</string>
<string name="tip_is_in_develop">当前为测试环境</string>
<string name="login_button">登录</string>
<string name="use_default_token">使用默认登录token</string>
<string name="logout_button">登出</string>
<string name="call_adult">呼叫成人医生</string>
<string name="call_child">呼叫儿童医生</string>
<string name="hp_input_hint_order_id">请输入病历订单号</string>
<string name="hp_sdk_demo_main">SDK主要功能示例</string>
<string name="hp_call_dept_all">成人</string>
<string name="hp_call_dept_child">儿童</string>
<string name="hp_view_list">查看病历列表</string>
<string name="hp_view_detail">查看病历详情</string>
<string name="hp_main_title">请选择类别</string>
<string name="hp_medicine_demo">药Demo入口</string>
<string name="hp_view_order_list_all">所有成员病历列表</string>
<string name="hp_view_order_list">订单列表</string>
<string name="hp_view_order_detail">订单详情</string>
<string name="hp_view_order_detail_hint">请输入订单ID</string>
<string name="hp_view_pay_detail">和豆支付详情</string>
<string name="hp_address_manager">地址管理</string>
<string name="hp_notice_depart">请选择给儿童看还是成人看</string>
<string name="hp_hint_pid">请输入您需要设定的sdk productId</string>
<string name="hp_button_set_pid">设置 SDK ProductID</string>
<string name="hp_multi_video">多人视频:陪诊</string>
<string name="hp_tip_edit_user_token">请输入被邀请人的userToken</string>
<string name="hp_tip_edit_user_name">请输入被邀请人的姓名(选填)</string>
<string name="hp_tip_edit_user_photo">请输入被邀请人的头像地址(选填)</string>
<string name="hp_button_start_multi_video">开始多人视频:陪诊</string>
<string name="hp_button_select_user_call">选择成员呼叫</string>
<string name="hp_upload_count">总共上传了%d张图片</string>
<string name="hp_switch_can_add_member_in_doc">允许档案库添加成员</string>
<string name="hp_switch_can_buy">开启购买</string>
<string name="hp_switch_hide_camera_control">显示摄像头关闭按钮</string>
<string name="hp_switch_close_camera_call">关闭摄像头呼叫</string>
<string name="hp_switch_close_more_func">关闭首届面更多功能入口</string>
<string name="hp_switch_can_add_member">允许添加成员</string>
<string name="hp_switch_enable_multi_call">开启多人视频</string>
<string name="hp_switch_enable_activate">开启激活码激活</string>
<string name="hp_switch_enable_medical">开启档案库</string>
<string name="hp_switch_enable_user_center">隐藏个人中心</string>
<string name="hp_switch_enable_summary_card">过滤咨询总结卡片</string>
<string name="hp_switch_enable_medical_card">过滤药卡</string>
<string name="hp_switch_enable_vip_info">显示会员信息</string>
<string name="hp_button_forward_message">进入消息界面</string>
<string name="hp_button_select_call">选人呼叫</string>
<string name="hp_edit_hint_message_title">请输入Message界面的title</string>
<string name="hp_button_set_message_title">设置Message Title</string>
<string name="hp_edit_hint_ext_message">请输入呼叫需传入的附加数据</string>
<string name="hp_button_set_ext_message">设置呼叫附加数据</string>
<string name="hp_buy_medicine_tips">如果使用购药功能需要向和缓sdk传入国标定位</string>
<string name="hp_hint_location_lng">请输入经度</string>
<string name="hp_hint_location_lat">请输入纬度</string>
<string name="hp_button_set_location">设置经纬度</string>
<string name="hh_location_lng">116.431941</string>
<string name="hh_location_lat">39.940199</string>
<string name="button_close">测试挂断</string>
<string name="menu_setting">设置SDK配置</string>
<string name="activity_setting_title">SDK参数配置</string>
<string name="button_clear_listener">延时60s清除Listener</string>
<string name="login_for_third_id_info">以下为使用loginForThirdId接口登录区域</string>
<string name="button_login_third_id">使用三方信息登录</string>
<string name="place_holder_uid">请输入第三方uid</string>
<string name="place_holder_time">请输入第三方time</string>
<string name="place_holder_secret">请输入第三方secret</string>
<string name="init_sdk">初始化SDK</string>
</resources>
... ...
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@android:color/white</item>
<item name="colorPrimaryDark">@android:color/white</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowIsTranslucent">false</item>
</style>
<style name="PageTheme" parent="AppTheme">
<item name="colorPrimary">@android:color/white</item>
<item name="colorPrimaryDark">@android:color/white</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="colorControlNormal">@android:color/black</item>
<!-- <item name="android:windowIsTranslucent">true</item>-->
</style>
<style name="Callback" parent="AppTheme">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
</style>
<style name="Toolbar" parent="Theme.AppCompat.Light">
<!-- <item name="android:fitsSystemWindows">true</item>-->
<item name="actionMenuTextColor">@android:color/black</item>
<item name="colorPrimary">@android:color/white</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="colorControlNormal">@android:color/black</item>
</style>
<style name="Toolbar.TitleText" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
<item name="android:textSize">17sp</item>
<item name="android:textColor">@android:color/black</item>
</style>
<style name="hh_line">
<item name="android:layout_height">1px</item>
<item name="android:layout_width">match_parent</item>
<item name="android:background">@color/uikit_line_color</item>
</style>
<style name="hh_toolbar_line" parent="hh_line">
<item name="android:background">@color/hh_toolbar_bottom_line</item>
<item name="android:layout_height">2px</item>
</style>
<style name="input_title">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textSize">16sp</item>
<item name="android:layout_marginTop">@dimen/dp_10</item>
</style>
<style name="config_switch">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginTop">@dimen/dp_10</item>
<item name="android:paddingStart">15dp</item>
<item name="android:paddingEnd">15dp</item>
</style>
<style name="demo_blue_button">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginStart">@dimen/dp_10</item>
<item name="android:paddingStart">@dimen/dp_10</item>
<item name="android:paddingEnd">@dimen/dp_10</item>
<item name="android:background">@drawable/hp_blue_btn_bg</item>
<item name="android:textColor">@android:color/white</item>
<item name="android:minHeight">0dp</item>
<item name="android:paddingTop">@dimen/dp_6</item>
<item name="android:paddingBottom">@dimen/dp_6</item>
<item name="android:textAllCaps">false</item>
</style>
</resources>
... ...
package com.hhmedic.android.hhdoctorvideodemo;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}
\ No newline at end of file
... ...
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
maven {
url 'http://maven.aliyun.com/nexus/content/repositories/releases/'
}
maven { url "https://jitpack.io" }
maven {
credentials {
username 'hh-public'
password 'OFGB5wX0'
}
url 'http://develop.hh-medic.com/repository/maven-public'
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
... ...
This file is too large to display.
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
android.enableJetifier=true
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
... ...
No preview for this file type
#Fri Oct 12 15:02:16 CST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
... ...
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
... ...
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
... ...
include ':app'
... ...