初次提交,修改了头像不能展示
58
tuicore/build.gradle
Normal file
@@ -0,0 +1,58 @@
|
||||
plugins {
|
||||
id 'com.android.library'
|
||||
}
|
||||
//apply from: "../MobSdk.gradle"
|
||||
android {
|
||||
compileSdkVersion 30
|
||||
buildToolsVersion "30.0.3"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 30
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
// 主题资源文件夹
|
||||
sourceSets {
|
||||
main {
|
||||
res.srcDirs += "src/main/res-light"
|
||||
res.srcDirs += "src/main/res-lively"
|
||||
res.srcDirs += "src/main/res-serious"
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
flatDir {
|
||||
dirs '../IMLib/libs'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
api fileTree(include: ['*.jar','*.aar'], dir: '../../../../tuikit/android/libs')
|
||||
|
||||
api fileTree(include: ['*.jar','*.aar'], dir: 'libs')
|
||||
api 'androidx.appcompat:appcompat:1.3.1'
|
||||
api 'com.github.bumptech.glide:glide:4.12.0'
|
||||
api 'androidx.recyclerview:recyclerview:1.2.1'
|
||||
|
||||
def projects = this.rootProject.getAllprojects().stream().map{project->project.name}.collect()
|
||||
println "all projects : {$projects}"
|
||||
if (projects.contains("imsdk-plus")) {
|
||||
api project(':imsdk-plus')
|
||||
} else {
|
||||
api rootProject.getProperties().containsKey("imSdk") ? rootProject.ext.imSdk : "com.tencent.imsdk:imsdk-plus:6.9.3557"
|
||||
}
|
||||
|
||||
}
|
||||
37
tuicore/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.tencent.qcloud.tuicore">
|
||||
|
||||
<application>
|
||||
<activity
|
||||
android:name=".component.activities.SelectionActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
<activity
|
||||
android:name=".component.activities.ImageSelectActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".util.PermissionRequester$PermissionActivity"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
android:multiprocess="true"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@style/CoreActivityTranslucent"
|
||||
android:windowSoftInputMode="stateHidden|stateAlwaysHidden" />
|
||||
|
||||
<provider
|
||||
android:name=".ServiceInitializer"
|
||||
android:authorities="${applicationId}.TUICore.Init"
|
||||
android:enabled="true"
|
||||
android:exported="false"/>
|
||||
|
||||
<provider
|
||||
android:name=".util.TUIFileProvider"
|
||||
android:authorities="${applicationId}.tuicore.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths_public"/>
|
||||
</provider>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.tencent.qcloud.tuicore;
|
||||
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.tencent.qcloud.tuicore.interfaces.ITUINotification;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* Notification registration, removal and triggering
|
||||
*/
|
||||
class EventManager {
|
||||
private static final String TAG = EventManager.class.getSimpleName();
|
||||
|
||||
private static class EventManagerHolder {
|
||||
private static final EventManager eventManager = new EventManager();
|
||||
}
|
||||
|
||||
public static EventManager getInstance() {
|
||||
return EventManagerHolder.eventManager;
|
||||
}
|
||||
|
||||
private final Map<Pair<String, String>, List<ITUINotification>> eventMap = new ConcurrentHashMap<>();
|
||||
|
||||
private EventManager() {}
|
||||
|
||||
public void registerEvent(String key, String subKey, ITUINotification notification) {
|
||||
Log.i(TAG, "registerEvent : key : " + key + ", subKey : " + subKey + ", notification : " + notification);
|
||||
if (TextUtils.isEmpty(key) || TextUtils.isEmpty(subKey) || notification == null) {
|
||||
return;
|
||||
}
|
||||
Pair<String, String> keyPair = new Pair<>(key, subKey);
|
||||
List<ITUINotification> list = eventMap.get(keyPair);
|
||||
if (list == null) {
|
||||
list = new CopyOnWriteArrayList<>();
|
||||
eventMap.put(keyPair, list);
|
||||
}
|
||||
if (!list.contains(notification)) {
|
||||
list.add(notification);
|
||||
}
|
||||
}
|
||||
|
||||
public void unRegisterEvent(String key, String subKey, ITUINotification notification) {
|
||||
Log.i(TAG, "removeEvent : key : " + key + ", subKey : " + subKey + " notification : " + notification);
|
||||
if (TextUtils.isEmpty(key) || TextUtils.isEmpty(subKey) || notification == null) {
|
||||
return;
|
||||
}
|
||||
Pair<String, String> keyPair = new Pair<>(key, subKey);
|
||||
List<ITUINotification> list = eventMap.get(keyPair);
|
||||
if (list == null) {
|
||||
return;
|
||||
}
|
||||
list.remove(notification);
|
||||
}
|
||||
|
||||
public void unRegisterEvent(ITUINotification notification) {
|
||||
Log.i(TAG, "removeEvent : notification : " + notification);
|
||||
if (notification == null) {
|
||||
return;
|
||||
}
|
||||
for (Pair<String, String> key : eventMap.keySet()) {
|
||||
List<ITUINotification> value = eventMap.get(key);
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
for (ITUINotification item : value) {
|
||||
if (item == notification) {
|
||||
value.remove(item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyEvent(String key, String subKey, Map<String, Object> param) {
|
||||
Log.i(TAG, "notifyEvent : key : " + key + ", subKey : " + subKey);
|
||||
if (TextUtils.isEmpty(key) || TextUtils.isEmpty(subKey)) {
|
||||
return;
|
||||
}
|
||||
Pair<String, String> keyPair = new Pair<>(key, subKey);
|
||||
List<ITUINotification> notificationList = eventMap.get(keyPair);
|
||||
if (notificationList != null) {
|
||||
for(ITUINotification notification : notificationList) {
|
||||
notification.onNotifyEvent(key, subKey, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.tencent.qcloud.tuicore;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.tencent.qcloud.tuicore.interfaces.ITUIExtension;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* UI extension registration and acquisition
|
||||
*/
|
||||
class ExtensionManager {
|
||||
private static final String TAG = ExtensionManager.class.getSimpleName();
|
||||
|
||||
private static class ExtensionManagerHolder {
|
||||
private static final ExtensionManager extensionManager = new ExtensionManager();
|
||||
}
|
||||
|
||||
public static ExtensionManager getInstance() {
|
||||
return ExtensionManagerHolder.extensionManager;
|
||||
}
|
||||
|
||||
private final Map<String, List<ITUIExtension>> extensionHashMap = new ConcurrentHashMap<>();
|
||||
|
||||
private ExtensionManager() {}
|
||||
|
||||
public void registerExtension(String key, ITUIExtension extension) {
|
||||
Log.i(TAG, "registerExtension key : " + key + ", extension : " + extension);
|
||||
if (TextUtils.isEmpty(key) || extension == null) {
|
||||
return;
|
||||
}
|
||||
List<ITUIExtension> list = extensionHashMap.get(key);
|
||||
if (list == null) {
|
||||
list = new CopyOnWriteArrayList<>();
|
||||
extensionHashMap.put(key, list);
|
||||
}
|
||||
if (!list.contains(extension)) {
|
||||
list.add(extension);
|
||||
}
|
||||
}
|
||||
|
||||
public void unRegisterExtension(String key, ITUIExtension extension) {
|
||||
Log.i(TAG, "removeExtension key : " + key + ", extension : " + extension);
|
||||
if (TextUtils.isEmpty(key) || extension == null) {
|
||||
return;
|
||||
}
|
||||
List<ITUIExtension> list = extensionHashMap.get(key);
|
||||
if (list == null) {
|
||||
return;
|
||||
}
|
||||
list.remove(extension);
|
||||
}
|
||||
|
||||
public Map<String, Object> getExtensionInfo(String key, Map<String, Object> param) {
|
||||
Log.i(TAG, "getExtensionInfo key : " + key );
|
||||
if (TextUtils.isEmpty(key)) {
|
||||
return null;
|
||||
}
|
||||
List<ITUIExtension> list = extensionHashMap.get(key);
|
||||
if (list == null) {
|
||||
return null;
|
||||
}
|
||||
for(ITUIExtension extension : list) {
|
||||
return extension.onGetExtensionInfo(key, param);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.tencent.qcloud.tuicore;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* If each module needs to be initialized, it needs to implement the init method of this class
|
||||
* and register it in the form of ContentProvider in the Manifest file.
|
||||
*/
|
||||
public class ServiceInitializer extends ContentProvider {
|
||||
|
||||
/**
|
||||
* @param context applicationContext
|
||||
*/
|
||||
public void init(Context context) {}
|
||||
|
||||
/**
|
||||
* LightTheme id
|
||||
*/
|
||||
public int getLightThemeResId() {
|
||||
return R.style.TUIBaseLightTheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* LivelyTheme id
|
||||
*/
|
||||
public int getLivelyThemeResId() {
|
||||
return R.style.TUIBaseLivelyTheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* SeriousTheme id
|
||||
*/
|
||||
public int getSeriousThemeResId() {
|
||||
return R.style.TUIBaseSeriousTheme;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// The following methods do not need to be overridden //
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private static Context appContext;
|
||||
|
||||
public static Context getAppContext() {
|
||||
return appContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
if (appContext == null) {
|
||||
appContext = getContext().getApplicationContext();
|
||||
}
|
||||
|
||||
TUIRouter.init(appContext);
|
||||
TUIConfig.init(appContext);
|
||||
TUIThemeManager.addLightTheme(getLightThemeResId());
|
||||
TUIThemeManager.addLivelyTheme(getLivelyThemeResId());
|
||||
TUIThemeManager.addSeriousTheme(getSeriousThemeResId());
|
||||
TUIThemeManager.setTheme(appContext);
|
||||
init(appContext);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getType(@NonNull Uri uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.tencent.qcloud.tuicore;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.tencent.qcloud.tuicore.interfaces.ITUIService;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Service register and call
|
||||
*/
|
||||
class ServiceManager {
|
||||
private static final String TAG = ServiceManager.class.getSimpleName();
|
||||
|
||||
private static class ServiceManagerHolder {
|
||||
private static final ServiceManager serviceManager = new ServiceManager();
|
||||
}
|
||||
|
||||
public static ServiceManager getInstance() {
|
||||
return ServiceManagerHolder.serviceManager;
|
||||
}
|
||||
|
||||
private final Map<String, ITUIService> serviceMap = new ConcurrentHashMap<>();
|
||||
|
||||
private ServiceManager() {}
|
||||
|
||||
public void registerService(String serviceName, ITUIService service) {
|
||||
Log.i(TAG, "registerService : " + serviceName + " " + service);
|
||||
if (TextUtils.isEmpty(serviceName) || service == null) {
|
||||
return;
|
||||
}
|
||||
serviceMap.put(serviceName, service);
|
||||
}
|
||||
|
||||
public void unregisterService(String serviceName) {
|
||||
Log.i(TAG, "unregisterService : " + serviceName);
|
||||
if (TextUtils.isEmpty(serviceName)) {
|
||||
return;
|
||||
}
|
||||
serviceMap.remove(serviceName);
|
||||
}
|
||||
|
||||
public ITUIService getService(String serviceName) {
|
||||
Log.i(TAG, "getService : " + serviceName);
|
||||
if (TextUtils.isEmpty(serviceName)) {
|
||||
return null;
|
||||
}
|
||||
return serviceMap.get(serviceName);
|
||||
}
|
||||
|
||||
public Object callService(String serviceName, String method, Map<String, Object> param) {
|
||||
Log.i(TAG, "callService : " + serviceName + " method : " + method);
|
||||
ITUIService service = serviceMap.get(serviceName);
|
||||
if (service != null) {
|
||||
return service.onCall(method, param);
|
||||
} else {
|
||||
Log.w(TAG, "can't find service : " + serviceName);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
346
tuicore/src/main/java/com/tencent/qcloud/tuicore/TUIConfig.java
Normal file
@@ -0,0 +1,346 @@
|
||||
package com.tencent.qcloud.tuicore;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.tencent.imsdk.v2.V2TIMUserFullInfo;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* TUI configuration, such as file path configuration, user information
|
||||
*/
|
||||
public class TUIConfig {
|
||||
|
||||
private static Context appContext;
|
||||
|
||||
private static String appDir = "";
|
||||
private static String selfFaceUrl = "";
|
||||
private static String selfNickName = "";
|
||||
private static int selfAllowType = 0;
|
||||
private static long selfBirthDay = 0L;
|
||||
private static String selfSignature = "";
|
||||
private static int gender;
|
||||
|
||||
public static final String TUICORE_SETTINGS_SP_NAME = "TUICoreSettings";
|
||||
|
||||
private static final String RECORD_DIR_SUFFIX = "/record/";
|
||||
private static final String RECORD_DOWNLOAD_DIR_SUFFIX = "/record/download/";
|
||||
private static final String VIDEO_DOWNLOAD_DIR_SUFFIX = "/video/download/";
|
||||
private static final String IMAGE_BASE_DIR_SUFFIX = "/image/";
|
||||
private static final String IMAGE_DOWNLOAD_DIR_SUFFIX = "/image/download/";
|
||||
private static final String MEDIA_DIR_SUFFIX = "/media/";
|
||||
private static final String FILE_DOWNLOAD_DIR_SUFFIX = "/file/download/";
|
||||
private static final String CRASH_LOG_DIR_SUFFIX = "/crash/";
|
||||
|
||||
private static boolean initialized = false;
|
||||
private static boolean enableGroupGridAvatar = true;
|
||||
private static int defaultAvatarImage;
|
||||
private static int defaultGroupAvatarImage;
|
||||
|
||||
public static void init(Context context) {
|
||||
if (initialized) {
|
||||
return;
|
||||
}
|
||||
TUIConfig.appContext = context;
|
||||
initPath();
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
public static String getDefaultAppDir() {
|
||||
if (TextUtils.isEmpty(appDir)) {
|
||||
Context context = null;
|
||||
if (appContext != null) {
|
||||
context = appContext;
|
||||
} else if (TUIRouter.getContext() != null) {
|
||||
context = TUIRouter.getContext();
|
||||
} else if (TUILogin.getAppContext() != null) {
|
||||
context = TUILogin.getAppContext();
|
||||
}
|
||||
if (context != null) {
|
||||
appDir = context.getFilesDir().getAbsolutePath();
|
||||
}
|
||||
}
|
||||
return appDir;
|
||||
}
|
||||
|
||||
public static void setDefaultAppDir(String appDir) {
|
||||
TUIConfig.appDir = appDir;
|
||||
}
|
||||
|
||||
public static String getRecordDir() {
|
||||
return getDefaultAppDir() + RECORD_DIR_SUFFIX;
|
||||
}
|
||||
|
||||
public static String getRecordDownloadDir() {
|
||||
return getDefaultAppDir() + RECORD_DOWNLOAD_DIR_SUFFIX;
|
||||
}
|
||||
|
||||
public static String getVideoDownloadDir() {
|
||||
return getDefaultAppDir() + VIDEO_DOWNLOAD_DIR_SUFFIX;
|
||||
}
|
||||
|
||||
public static String getImageBaseDir() {
|
||||
return getDefaultAppDir() + IMAGE_BASE_DIR_SUFFIX;
|
||||
}
|
||||
|
||||
public static String getImageDownloadDir() {
|
||||
return getDefaultAppDir() + IMAGE_DOWNLOAD_DIR_SUFFIX;
|
||||
}
|
||||
|
||||
public static String getMediaDir() {
|
||||
return getDefaultAppDir() + MEDIA_DIR_SUFFIX;
|
||||
}
|
||||
|
||||
public static String getFileDownloadDir() {
|
||||
return getDefaultAppDir() + FILE_DOWNLOAD_DIR_SUFFIX;
|
||||
}
|
||||
|
||||
public static String getCrashLogDir() {
|
||||
return getDefaultAppDir() + CRASH_LOG_DIR_SUFFIX;
|
||||
}
|
||||
|
||||
public static String getSelfFaceUrl() {
|
||||
return selfFaceUrl;
|
||||
}
|
||||
|
||||
public static void setSelfFaceUrl(String selfFaceUrl) {
|
||||
TUIConfig.selfFaceUrl = selfFaceUrl;
|
||||
}
|
||||
|
||||
public static String getSelfNickName() {
|
||||
return selfNickName;
|
||||
}
|
||||
|
||||
public static void setSelfNickName(String selfNickName) {
|
||||
TUIConfig.selfNickName = selfNickName;
|
||||
}
|
||||
|
||||
public static int getSelfAllowType() {
|
||||
return selfAllowType;
|
||||
}
|
||||
|
||||
public static void setSelfAllowType(int selfAllowType) {
|
||||
TUIConfig.selfAllowType = selfAllowType;
|
||||
}
|
||||
|
||||
public static long getSelfBirthDay() {
|
||||
return selfBirthDay;
|
||||
}
|
||||
|
||||
public static void setSelfBirthDay(long selfBirthDay) {
|
||||
TUIConfig.selfBirthDay = selfBirthDay;
|
||||
}
|
||||
|
||||
public static String getSelfSignature() {
|
||||
return selfSignature;
|
||||
}
|
||||
|
||||
public static void setSelfSignature(String selfSignature) {
|
||||
TUIConfig.selfSignature = selfSignature;
|
||||
}
|
||||
|
||||
public static void setGender(int gender) {
|
||||
TUIConfig.gender = gender;
|
||||
}
|
||||
|
||||
public static int getGender() {
|
||||
return gender;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取群组会话否展示九宫格样式的头像,默认为 true
|
||||
* Gets whether to display the avatar in the nine-square grid style in the group conversation, the default is true
|
||||
*/
|
||||
public static boolean isEnableGroupGridAvatar() {
|
||||
return enableGroupGridAvatar;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置群组会话是否展示九宫格样式的头像
|
||||
* Set whether to display the avatar in the nine-square grid style in group conversations
|
||||
*/
|
||||
public static void setEnableGroupGridAvatar(boolean enableGroupGridAvatar) {
|
||||
TUIConfig.enableGroupGridAvatar = enableGroupGridAvatar;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 c2c 会话的默认头像
|
||||
*
|
||||
* Get the default avatar for c2c conversation
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static int getDefaultAvatarImage() {
|
||||
return defaultAvatarImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 c2c 会话的默认头像
|
||||
*
|
||||
*Set the default avatar for c2c conversation
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static void setDefaultAvatarImage(int defaultAvatarImage) {
|
||||
TUIConfig.defaultAvatarImage = defaultAvatarImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 group 会话的默认头像
|
||||
*
|
||||
* Get the default avatar for group conversation
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static int getDefaultGroupAvatarImage() {
|
||||
return defaultGroupAvatarImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 group 会话的默认头像
|
||||
*
|
||||
*Set the default avatar for group conversation
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static void setDefaultGroupAvatarImage(int defaultGroupAvatarImage) {
|
||||
TUIConfig.defaultGroupAvatarImage = defaultGroupAvatarImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set login user information
|
||||
*/
|
||||
public static void setSelfInfo(V2TIMUserFullInfo userFullInfo) {
|
||||
TUIConfig.selfFaceUrl = userFullInfo.getFaceUrl();
|
||||
TUIConfig.selfNickName = userFullInfo.getNickName();
|
||||
TUIConfig.selfAllowType = userFullInfo.getAllowType();
|
||||
TUIConfig.selfBirthDay = userFullInfo.getBirthday();
|
||||
TUIConfig.selfSignature = userFullInfo.getSelfSignature();
|
||||
TUIConfig.gender = userFullInfo.getGender();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear login user information
|
||||
*/
|
||||
public static void clearSelfInfo() {
|
||||
TUIConfig.selfFaceUrl = "";
|
||||
TUIConfig.selfNickName = "";
|
||||
TUIConfig.selfAllowType = 0;
|
||||
TUIConfig.selfBirthDay = 0L;
|
||||
TUIConfig.selfSignature = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* init file path
|
||||
*/
|
||||
public static void initPath() {
|
||||
File f = new File(getMediaDir());
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
|
||||
f = new File(getRecordDir());
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
|
||||
f = new File(getRecordDownloadDir());
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
|
||||
f = new File(getVideoDownloadDir());
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
|
||||
f = new File(getImageDownloadDir());
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
|
||||
f = new File(getFileDownloadDir());
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
|
||||
f = new File(getCrashLogDir());
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
public static Context getAppContext() {
|
||||
return appContext;
|
||||
}
|
||||
|
||||
public static void setSceneOptimizParams(final String scene){
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
String packageName = "";
|
||||
String sdkAPPId = TUILogin.getSdkAppId() + "";
|
||||
String userId = TUILogin.getUserId();
|
||||
if(getAppContext() != null){
|
||||
packageName = getAppContext().getPackageName();
|
||||
}
|
||||
|
||||
URL url = new URL("https://demos.trtc.tencent-cloud.com/prod/base/v1/events/stat");
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setConnectTimeout(5000);
|
||||
conn.setReadTimeout(5000);
|
||||
conn.setDoOutput(true);
|
||||
conn.setDoInput(true);
|
||||
conn.setUseCaches(false);
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setRequestProperty("Content-Type", "application/json");
|
||||
|
||||
JSONObject msgObject = new JSONObject();
|
||||
msgObject.put("sdkappid", sdkAPPId);
|
||||
msgObject.put("bundleId", "");
|
||||
msgObject.put("component", scene);
|
||||
msgObject.put("package", packageName);
|
||||
|
||||
JSONObject bodyObject = new JSONObject();
|
||||
bodyObject.put("userId", userId);
|
||||
bodyObject.put("event", "useScenario");
|
||||
bodyObject.put("msg", msgObject);
|
||||
String paramStr = String.valueOf(bodyObject);
|
||||
|
||||
OutputStream out = conn.getOutputStream();
|
||||
out.write(paramStr.getBytes());
|
||||
out.flush();
|
||||
out.close();
|
||||
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
||||
InputStream is = conn.getInputStream();
|
||||
ByteArrayOutputStream message = new ByteArrayOutputStream();
|
||||
int len = 0;
|
||||
byte buffer[] = new byte[1024];
|
||||
while ((len = is.read(buffer)) != -1) {
|
||||
message.write(buffer, 0, len);
|
||||
}
|
||||
String msg = new String(message.toByteArray());
|
||||
Log.d("setSceneOptimizParams", "msg:" + msg);
|
||||
is.close();
|
||||
message.close();
|
||||
conn.disconnect();
|
||||
} else {
|
||||
Log.d("setSceneOptimizParams", "ResponseCode:" + conn.getResponseCode());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.d("TUICore", "setSceneOptimizParams exception");
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,387 @@
|
||||
package com.tencent.qcloud.tuicore;
|
||||
|
||||
import com.tencent.imsdk.BaseConstants;
|
||||
|
||||
/**
|
||||
* TUI constants
|
||||
*/
|
||||
public final class TUIConstants {
|
||||
|
||||
public static final class GroupType {
|
||||
public static final String TYPE = "type";
|
||||
public static final String IS_GROUP = "isGroup";
|
||||
|
||||
public static final String TYPE_PRIVATE = "Private";
|
||||
public static final String TYPE_WORK = "Work";
|
||||
public static final String TYPE_PUBLIC = "Public";
|
||||
|
||||
public static final String TYPE_CHAT_ROOM = "ChatRoom";
|
||||
public static final String TYPE_MEETING = "Meeting";
|
||||
public static final String TYPE_COMMUNITY = "Community";
|
||||
}
|
||||
|
||||
public static final class Service {
|
||||
public static final String TUI_CHAT = "TUIChatService";
|
||||
public static final String TUI_CONVERSATION = "TUIConversationService";
|
||||
public static final String TUI_CONTACT = "TUIContactService";
|
||||
public static final String TUI_SEARCH = "TUISearchService";
|
||||
public static final String TUI_GROUP = "TUIGroupService";
|
||||
public static final String TUI_CALLING = "TUICallingService";
|
||||
public static final String TUI_LIVE = "TUILiveService";
|
||||
public static final String TUI_BEAUTY = "TUIBeauty";
|
||||
public static final String TUI_OFFLINEPUSH = "TUIOfflinePushService";
|
||||
public static final String TUI_COMMUNITY = "TUICommunityService";
|
||||
}
|
||||
|
||||
public static final class TUILogin {
|
||||
|
||||
// User login status change broadcast
|
||||
public static final String EVENT_LOGIN_STATE_CHANGED = "eventLoginStateChanged";
|
||||
// User kicked offline
|
||||
public static final String EVENT_SUB_KEY_USER_KICKED_OFFLINE = "eventSubKeyUserKickedOffline";
|
||||
// User ticket expired
|
||||
public static final String EVENT_SUB_KEY_USER_SIG_EXPIRED = "eventSubKeyUserSigExpired";
|
||||
// Changes in user personal information
|
||||
public static final String EVENT_SUB_KEY_USER_INFO_UPDATED = "eventSubKeyUserInfoUpdated";
|
||||
|
||||
// Imsdk initialize state change
|
||||
public static final String EVENT_IMSDK_INIT_STATE_CHANGED = "eventIMSDKInitStateChanged";
|
||||
// Init
|
||||
public static final String EVENT_SUB_KEY_START_INIT = "eventSubKeyStartInit";
|
||||
// Uint
|
||||
public static final String EVENT_SUB_KEY_START_UNINIT = "eventSubKeyStartUnInit";
|
||||
// Login success
|
||||
public static final String EVENT_SUB_KEY_USER_LOGIN_SUCCESS = "eventSubKeyUserLoginSuccess";
|
||||
// Logout success
|
||||
public static final String EVENT_SUB_KEY_USER_LOGOUT_SUCCESS = "eventSubKeyUserLogoutSuccess";
|
||||
|
||||
public static final String SELF_ID = "selfId";
|
||||
public static final String SELF_SIGNATURE = "selfSignature";
|
||||
public static final String SELF_FACE_URL = "selfFaceUrl";
|
||||
public static final String SELF_NICK_NAME = "selfNickName";
|
||||
public static final String SELF_LEVEL = "selfLevel";
|
||||
public static final String SELF_GENDER = "selfGender";
|
||||
public static final String SELF_ROLE = "selfRole";
|
||||
public static final String SELF_BIRTHDAY = "selfBirthday";
|
||||
public static final String SELF_ALLOW_TYPE = "selfAllowType";
|
||||
}
|
||||
|
||||
public static final class TUIChat {
|
||||
public static final String SERVICE_NAME = Service.TUI_CHAT;
|
||||
|
||||
// Send message
|
||||
public static final String METHOD_SEND_MESSAGE = "sendMessage";
|
||||
// Exit chat
|
||||
public static final String METHOD_EXIT_CHAT = "exitChat";
|
||||
// Get a message digest to display in the conversation list
|
||||
public static final String METHOD_GET_DISPLAY_STRING = "getDisplayString";
|
||||
// add message to chat list
|
||||
public static final String METHOD_ADD_MESSAGE_TO_CHAT = "addMessageToChat";
|
||||
// 处理完群申请 // Process the group application
|
||||
public static final String METHOD_GROUP_APPLICAITON_PROCESSED = "groupApplicationProcessed";
|
||||
|
||||
// More actions
|
||||
public static final String EXTENSION_INPUT_MORE_CUSTOM_MESSAGE = "inputMoreCustomMessage";
|
||||
public static final String EXTENSION_INPUT_MORE_LIVE = "inputMoreLive";
|
||||
public static final String EXTENSION_INPUT_MORE_VIDEO_CALL = "inputMoreVideoCall";
|
||||
public static final String EXTENSION_INPUT_MORE_AUDIO_CALL = "inputMoreAudioCall";
|
||||
|
||||
public static final String EVENT_KEY_RECEIVE_MESSAGE = "eventReceiveMessage";
|
||||
public static final String EVENT_SUB_KEY_CONVERSATION_ID = "eventConversationID";
|
||||
|
||||
public static final String EVENT_KEY_INPUT_MORE = "eventKeyInputMore";
|
||||
public static final String EVENT_SUB_KEY_ON_CLICK = "eventSubKeyOnClick";
|
||||
|
||||
public static final String EVENT_KEY_MESSAGE_EVENT = "eventKeyMessageEvent";
|
||||
public static final String EVENT_SUB_KEY_SEND_MESSAGE_SUCCESS = "eventSubKeySendMessageSuccess";
|
||||
public static final String EVENT_SUB_KEY_REPLY_MESSAGE_SUCCESS = "eventSubKeyReplyMessageSuccess";
|
||||
|
||||
public static final String C2C_CHAT_ACTIVITY_NAME = "TUIC2CChatActivity";
|
||||
public static final String GROUP_CHAT_ACTIVITY_NAME = "TUIGroupChatActivity";
|
||||
public static final String CHAT_ID = "chatId";
|
||||
public static final String CHAT_NAME = "chatName";
|
||||
public static final String CHAT_TYPE = "chatType";
|
||||
public static final String GROUP_NAME = "groupName";
|
||||
public static final String GROUP_TYPE = "groupType";
|
||||
public static final String DRAFT_TEXT = "draftText";
|
||||
public static final String DRAFT_TIME = "draftTime";
|
||||
public static final String IS_TOP_CHAT = "isTopChat";
|
||||
public static final String LOCATE_MESSAGE = "locateMessage";
|
||||
public static final String AT_INFO_LIST = "atInfoList";
|
||||
public static final String FACE_URL = "faceUrl";
|
||||
public static final String FACE_URL_LIST = "faceUrlList";
|
||||
public static final String JOIN_TYPE = "joinType";
|
||||
public static final String MEMBER_COUNT = "memberCount";
|
||||
public static final String RECEIVE_OPTION = "receiveOption";
|
||||
public static final String NOTICE = "notice";
|
||||
public static final String OWNER = "owner";
|
||||
public static final String MEMBER_DETAILS = "memberDetails";
|
||||
public static final String IS_GROUP_CHAT = "isGroupChat";
|
||||
public static final String V2TIMMESSAGE = "v2TIMMessage";
|
||||
public static final String MESSAGE_BEAN = "messageBean";
|
||||
public static final String GROUP_APPLY_NUM = "groupApplicaitonNumber";
|
||||
public static final String CONVERSATION_ID = "conversationID";
|
||||
public static final String IS_TYPING_MESSAGE = "isTypingMessage";
|
||||
public static final String ROOM_ID = "room_id";
|
||||
|
||||
|
||||
// Send custom message fields
|
||||
public static final String MESSAGE_CONTENT = "messageContent";
|
||||
public static final String MESSAGE_DESCRIPTION = "messageDescription";
|
||||
public static final String MESSAGE_EXTENSION = "messageExtension";
|
||||
|
||||
// More input button extension field
|
||||
public static final String CONTEXT = "context";
|
||||
public static final String INPUT_MORE_ICON = "icon";
|
||||
public static final String INPUT_MORE_TITLE = "title";
|
||||
public static final String INPUT_MORE_ACTION_ID = "actionId";
|
||||
public static final String INPUT_MORE_VIEW = "inputMoreView";
|
||||
|
||||
// Background
|
||||
public static final String CHAT_CONVERSATION_BACKGROUND_URL = "https://sdk-im-1252463788.file.myqcloud.com/download/tuikit-resource/conversation-backgroundImage/backgroundImage_%s_full.png";
|
||||
public static final String CHAT_CONVERSATION_BACKGROUND_THUMBNAIL_URL = "https://sdk-im-1252463788.file.myqcloud.com/download/tuikit-resource/conversation-backgroundImage/backgroundImage_%s.png";
|
||||
public static final int CHAT_CONVERSATION_BACKGROUND_COUNT = 7;
|
||||
public static final String CHAT_CONVERSATION_BACKGROUND_DEFAULT_URL = "chat/conversation/background/default/url";
|
||||
public static final int CHAT_REQUEST_BACKGROUND_CODE = 1001;
|
||||
public static final String METHOD_UPDATE_DATA_STORE_CHAT_URI = "updateDatastoreChatUri";
|
||||
public static final String CHAT_BACKGROUND_URI = "chatBackgroundUri";
|
||||
}
|
||||
|
||||
public static final class TUIConversation {
|
||||
public static final String SERVICE_NAME = Service.TUI_CONVERSATION;
|
||||
|
||||
|
||||
public static final String METHOD_IS_TOP_CONVERSATION = "isTopConversation";
|
||||
public static final String METHOD_SET_TOP_CONVERSATION = "setTopConversation";
|
||||
public static final String METHOD_GET_TOTAL_UNREAD_COUNT = "getTotalUnreadCount";
|
||||
public static final String METHOD_UPDATE_TOTAL_UNREAD_COUNT = "updateTotalUnreadCount";
|
||||
public static final String METHOD_DELETE_CONVERSATION = "deleteConversation";
|
||||
public static final String METHOD_CLEAR_CONVERSATION_MESSAGE = "clearConversationMessage";
|
||||
|
||||
public static final String EVENT_UNREAD = "eventTotalUnreadCount";
|
||||
public static final String EVENT_SUB_KEY_UNREAD_CHANGED = "unreadCountChanged";
|
||||
|
||||
public static final String EXTENSION_CLASSIC_SEARCH = "extensionClassicSearch";
|
||||
public static final String EXTENSION_MINIMALIST_SEARCH = "extensionMinimalistSearch";
|
||||
|
||||
public static final String CHAT_ID = "chatId";
|
||||
public static final String CONVERSATION_ID = "conversationId";
|
||||
public static final String IS_SET_TOP = "isSetTop";
|
||||
public static final String IS_TOP = "isTop";
|
||||
public static final String IS_GROUP = "isGroup";
|
||||
public static final String TOTAL_UNREAD_COUNT = "totalUnreadCount";
|
||||
public static final String CONTEXT = "context";
|
||||
public static final String SEARCH_VIEW = "searchView";
|
||||
|
||||
public static final String CONVERSATION_C2C_PREFIX = "c2c_";
|
||||
public static final String CONVERSATION_GROUP_PREFIX = "group_";
|
||||
|
||||
public static final String EVENT_KEY_MESSAGE_SEND_FOR_CONVERSATION = "eventKeyMessageSendForConversation";
|
||||
public static final String EVENT_SUB_KEY_MESSAGE_SEND_FOR_CONVERSATION = "eventSubKeyMessageSendForConversation";
|
||||
}
|
||||
|
||||
public static final class TUIContact {
|
||||
public static final String SERVICE_NAME = Service.TUI_CONTACT;
|
||||
|
||||
public static final String EVENT_FRIEND_STATE_CHANGED = "eventFriendStateChanged";
|
||||
public static final String EVENT_FRIEND_INFO_CHANGED = "eventFriendInfoChanged";
|
||||
public static final String EVENT_USER = "eventUser";
|
||||
public static final String EVENT_SUB_KEY_FRIEND_REMARK_CHANGED = "eventFriendRemarkChanged";
|
||||
public static final String EVENT_SUB_KEY_FRIEND_DELETE = "eventSubKeyFriendDelete";
|
||||
public static final String EVENT_SUB_KEY_CLEAR_MESSAGE = "eventSubKeyC2CClearMessage";
|
||||
|
||||
public static final String FRIEND_ID_LIST = "friendIdList";
|
||||
public static final String FRIEND_ID = "friendId";
|
||||
public static final String FRIEND_REMARK = "friendRemark";
|
||||
|
||||
public static final String GROUP_TYPE_KEY = "type";
|
||||
public static final String COMMUNITY_SUPPORT_TOPIC_KEY = "communitySupportTopic";
|
||||
|
||||
public static final int GROUP_TYPE_PRIVATE = 0;
|
||||
public static final int GROUP_TYPE_PUBLIC = 1;
|
||||
public static final int GROUP_TYPE_CHAT_ROOM = 2;
|
||||
public static final int GROUP_TYPE_COMMUNITY = 3;
|
||||
|
||||
public static final String GROUP_FACE_URL = "https://im.sdk.cloud.tencent.cn/download/tuikit-resource/group-avatar/group_avatar_%s.png";
|
||||
public static final int GROUP_FACE_COUNT = 24;
|
||||
}
|
||||
|
||||
public static final class TUICalling {
|
||||
public static final String SERVICE_NAME = Service.TUI_CALLING;
|
||||
|
||||
public static final String METHOD_NAME_CALL = "call";
|
||||
public static final String METHOD_NAME_RECEIVEAPNSCALLED = "receiveAPNSCalled";
|
||||
public static final String METHOD_NAME_ENABLE_FLOAT_WINDOW = "methodEnableFloatWindow";
|
||||
public static final String METHOD_NAME_ENABLE_MULTI_DEVICE = "methodEnableMultiDeviceAbility";
|
||||
|
||||
public static final String PARAM_NAME_TYPE = "type";
|
||||
public static final String PARAM_NAME_USERIDS = "userIDs";
|
||||
public static final String PARAM_NAME_GROUPID = "groupId";
|
||||
public static final String PARAM_NAME_CALLMODEL = "call_model_data";
|
||||
public static final String PARAM_NAME_ENABLE_FLOAT_WINDOW = "enableFloatWindow";
|
||||
public static final String PARAM_NAME_ENABLE_MULTI_DEVICE = "enableMultiDeviceAbility";
|
||||
|
||||
public static final String METHOD_START_CALL = "startCall";
|
||||
|
||||
public static final String CUSTOM_MESSAGE_BUSINESS_ID = "av_call";
|
||||
public static final Double CALL_TIMEOUT_BUSINESS_ID = 1.0;
|
||||
|
||||
public static final String CALL_ID = "callId";
|
||||
public static final String SENDER = "sender";
|
||||
public static final String GROUP_ID = "groupId";
|
||||
public static final String INVITED_LIST = "invitedList";
|
||||
public static final String DATA = "data";
|
||||
|
||||
public static final String TYPE_AUDIO = "audio";
|
||||
public static final String TYPE_VIDEO = "video";
|
||||
|
||||
public static final int ACTION_ID_AUDIO_CALL = 1;
|
||||
public static final int ACTION_ID_VIDEO_CALL = 2;
|
||||
|
||||
public static final String EVENT_KEY_CALLING = "calling";
|
||||
public static final String EVENT_KEY_NAME = "event_name";
|
||||
public static final String EVENT_ACTIVE_HANGUP = "active_hangup";
|
||||
}
|
||||
|
||||
public static final class TUILive {
|
||||
public static final String SERVICE_NAME = Service.TUI_LIVE;
|
||||
|
||||
|
||||
public static final String METHOD_LOGIN = "methodLogin";
|
||||
public static final String METHOD_LOGOUT = "methodLogout";
|
||||
public static final String METHOD_START_ANCHOR = "methodStartAnchor";
|
||||
public static final String METHOD_START_AUDIENCE = "methodStartAudience";
|
||||
|
||||
public static final String CUSTOM_MESSAGE_BUSINESS_ID = "group_live";
|
||||
public static final String SDK_APP_ID = "sdkAppId";
|
||||
public static final String USER_ID = "userId";
|
||||
public static final String USER_SIG = "userSig";
|
||||
|
||||
public static final String GROUP_ID = "groupId";
|
||||
public static final String ROOM_ID = "roomId";
|
||||
public static final String ROOM_NAME = "roomName";
|
||||
public static final String ROOM_STATUS = "roomStatus";
|
||||
public static final String ROOM_COVER = "roomCover";
|
||||
public static final String USE_CDN_PLAY = "use_cdn_play";
|
||||
public static final String ANCHOR_ID = "anchorId";
|
||||
public static final String ANCHOR_NAME = "anchorName";
|
||||
public static final String PUSHER_NAME = "pusherName";
|
||||
public static final String COVER_PIC = "coverPic";
|
||||
public static final String PUSHER_AVATAR = "pusherAvatar";
|
||||
|
||||
public static final int ACTION_ID_LIVE = 0;
|
||||
|
||||
}
|
||||
|
||||
public static final class TUIGroup {
|
||||
public static final String SERVICE_NAME = Service.TUI_GROUP;
|
||||
|
||||
|
||||
public static final String EVENT_GROUP = "eventGroup";
|
||||
public static final String EVENT_SUB_KEY_EXIT_GROUP = "eventExitGroup";
|
||||
public static final String EVENT_SUB_KEY_MEMBER_KICKED_GROUP = "eventMemberKickedGroup";
|
||||
public static final String EVENT_SUB_KEY_GROUP_RECYCLE = "eventMemberGroupRecycle";
|
||||
public static final String EVENT_SUB_KEY_GROUP_DISMISS = "eventMemberGroupDismiss";
|
||||
public static final String EVENT_SUB_KEY_JOIN_GROUP = "eventSubKeyJoinGroup";
|
||||
public static final String EVENT_SUB_KEY_INVITED_GROUP = "eventSubKeyInvitedGroup";
|
||||
public static final String EVENT_SUB_KEY_GROUP_INFO_CHANGED = "eventSubKeyGroupInfoChanged";
|
||||
public static final String EVENT_SUB_KEY_CLEAR_MESSAGE = "eventSubKeyGroupClearMessage";
|
||||
public static final String EVENT_SUB_KEY_GROUP_MEMBER_SELECTED = "eventSubKeyGroupMemberSelected";
|
||||
|
||||
public static final String GROUP_ID = "groupId";
|
||||
public static final String GROUP_NAME = "groupName";
|
||||
public static final String GROUP_FACE_URL = "groupFaceUrl";
|
||||
public static final String GROUP_OWNER = "groupOwner";
|
||||
public static final String GROUP_INTRODUCTION = "groupIntroduction";
|
||||
public static final String GROUP_NOTIFICATION = "groupNotification";
|
||||
public static final String GROUP_MEMBER_ID_LIST = "groupMemberIdList";
|
||||
|
||||
public static final String SELECT_FRIENDS = "select_friends";
|
||||
public static final String SELECT_FOR_CALL = "isSelectForCall";
|
||||
public static final String USER_DATA = "userData";
|
||||
public static final String IS_SELECT_MODE = "isSelectMode";
|
||||
public static final String EXCLUDE_LIST = "excludeList";
|
||||
public static final String SELECTED_LIST = "selectedList";
|
||||
public static final String CONTENT = "content";
|
||||
public static final String TYPE = "type";
|
||||
public static final String TITLE = "title";
|
||||
public static final String LIST = "list";
|
||||
public static final String LIMIT = "limit";
|
||||
public static final String FILTER = "filter";
|
||||
public static final String JOIN_TYPE_INDEX = "joinTypeIndex";
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static final class TUIBeauty {
|
||||
public static final String SERVICE_NAME = Service.TUI_BEAUTY;
|
||||
|
||||
public static final String PARAM_NAME_CONTEXT = "context";
|
||||
public static final String PARAM_NAME_LICENSE_KEY = "licenseKey";
|
||||
public static final String PARAM_NAME_LICENSE_URL = "licenseUrl";
|
||||
public static final String PARAM_NAME_FRAME_WIDTH = "frameWidth";
|
||||
public static final String PARAM_NAME_FRAME_HEIGHT = "frameHeight";
|
||||
public static final String PARAM_NAME_SRC_TEXTURE_ID = "srcTextureId";
|
||||
|
||||
public static final String METHOD_PROCESS_VIDEO_FRAME = "processVideoFrame";
|
||||
public static final String METHOD_INIT_XMAGIC = "setLicense";
|
||||
public static final String METHOD_DESTROY_XMAGIC = "destroy";
|
||||
}
|
||||
|
||||
public static final class TUIOfflinePush {
|
||||
public static final String SERVICE_NAME = Service.TUI_OFFLINEPUSH;
|
||||
public static final String METHOD_UNREGISTER_PUSH = "unRegiterPush";
|
||||
|
||||
public static final String EVENT_NOTIFY = "offlinePushNotifyEvent";
|
||||
public static final String EVENT_NOTIFY_NOTIFICATION = "notifyNotificationEvent";
|
||||
public static final String NOTIFICATION_INTENT_KEY = "notificationIntentKey";
|
||||
public static final String NOTIFICATION_EXT_KEY = "ext";
|
||||
|
||||
public static final String NOTIFICATION_BROADCAST_ACTION = "com.tencent.tuiofflinepush.BROADCAST_PUSH_RECEIVER";
|
||||
}
|
||||
|
||||
public static final class TUICommunity {
|
||||
public static final String SERVICE_NAME = Service.TUI_COMMUNITY;
|
||||
|
||||
public static final String TOPIC_ID = "topic_id";
|
||||
|
||||
public static final String EVENT_KEY_COMMUNITY_EXPERIENCE = "eventKeyCommunityExperience";
|
||||
public static final String EVENT_SUB_KEY_ADD_COMMUNITY = "eventSubKeyAddCommunity";
|
||||
public static final String EVENT_SUB_KEY_CREATE_COMMUNITY = "eventSubKeyCreateCommunity";
|
||||
public static final String EVENT_SUB_KEY_DISBAND_COMMUNITY = "eventSubKeyDisbandCommunity";
|
||||
public static final String EVENT_SUB_KEY_CREATE_TOPIC = "eventSubKeyCreateTopic";
|
||||
public static final String EVENT_SUB_KEY_DELETE_TOPIC = "eventSubKeyDeleteTopic";
|
||||
}
|
||||
|
||||
public static final class Message {
|
||||
public static final String CUSTOM_BUSINESS_ID_KEY = "businessID";
|
||||
public static final String CALLING_TYPE_KEY = "call_type";
|
||||
}
|
||||
|
||||
public static final class NetworkConnection {
|
||||
public static final String EVENT_CONNECTION_STATE_CHANGED = "eventConnectionStateChanged";
|
||||
public static final String EVENT_SUB_KEY_CONNECTING = "eventSubKeyConnecting";
|
||||
public static final String EVENT_SUB_KEY_CONNECT_SUCCESS = "eventSubKeyConnectSuccess";
|
||||
public static final String EVENT_SUB_KEY_CONNECT_FAILED = "eventSubKeyConnectFailed";
|
||||
}
|
||||
|
||||
|
||||
public static final class BuyingFeature {
|
||||
public static final int ERR_SDK_INTERFACE_NOT_SUPPORT = BaseConstants.ERR_SDK_INTERFACE_NOT_SUPPORT;
|
||||
public static final String BUYING_GUIDELINES_EN = "https://intl.cloud.tencent.com/document/product/1047/36021?lang=en&pg=#changing-configuration";
|
||||
public static final String BUYING_GUIDELINES = "https://cloud.tencent.com/document/product/269/32458";
|
||||
|
||||
public static final String BUYING_PRICE_DESC_EN = "https://www.tencentcloud.com/document/product/1047/34349#basic-services";
|
||||
public static final String BUYING_PRICE_DESC = "https://cloud.tencent.com/document/product/269/11673?from=17219#.E5.9F.BA.E7.A1.80.E6.9C.8D.E5.8A.A1.E8.AF.A6.E6.83.85";
|
||||
|
||||
|
||||
public static final String BUYING_FEATURE_MESSAGE_RECEIPT = "buying_chat_message_read_receipt";
|
||||
public static final String BUYING_FEATURE_COMMUNITY = "buying_community";
|
||||
public static final String BUYING_FEATURE_SEARCH = "buying_search";
|
||||
public static final String BUYING_FEATURE_ONLINE_STATUS = "buying_online_status";
|
||||
}
|
||||
|
||||
// localBroadcast
|
||||
public static final String CONVERSATION_UNREAD_COUNT_ACTION = "conversation_unread_count_action";
|
||||
public static final String UNREAD_COUNT_EXTRA = "unread_count_extra";
|
||||
}
|
||||
148
tuicore/src/main/java/com/tencent/qcloud/tuicore/TUICore.java
Normal file
@@ -0,0 +1,148 @@
|
||||
package com.tencent.qcloud.tuicore;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.tencent.qcloud.tuicore.interfaces.ITUIExtension;
|
||||
import com.tencent.qcloud.tuicore.interfaces.ITUINotification;
|
||||
import com.tencent.qcloud.tuicore.interfaces.ITUIService;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* TUI Plugin core class, mainly responsible for data transfer between TUI plugins, notification broadcast, function extension, etc.
|
||||
*/
|
||||
public class TUICore {
|
||||
private static final String TAG = TUICore.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* Register Service
|
||||
* @param serviceName service name
|
||||
* @param service service object
|
||||
*/
|
||||
public static void registerService(String serviceName, ITUIService service) {
|
||||
ServiceManager.getInstance().registerService(serviceName, service);
|
||||
}
|
||||
|
||||
/**
|
||||
* unregister Service
|
||||
*
|
||||
* @param serviceName service name
|
||||
*/
|
||||
public static void unregisterService(String serviceName) {
|
||||
ServiceManager.getInstance().unregisterService(serviceName);
|
||||
}
|
||||
|
||||
/**
|
||||
* get Service
|
||||
*
|
||||
* @param serviceName service name
|
||||
* @return service
|
||||
*/
|
||||
public static ITUIService getService(String serviceName) {
|
||||
return ServiceManager.getInstance().getService(serviceName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call Service
|
||||
*
|
||||
* @param serviceName service name
|
||||
* @param method method name
|
||||
* @param param pass parameters
|
||||
* @return object
|
||||
*/
|
||||
public static Object callService(String serviceName, String method, Map<String, Object> param) {
|
||||
return ServiceManager.getInstance().callService(serviceName, method, param);
|
||||
}
|
||||
|
||||
/**
|
||||
* start Activity
|
||||
* @param activityName activity name,such as "TUIGroupChatActivity"
|
||||
* @param param pass parameters
|
||||
*/
|
||||
public static void startActivity(String activityName, Bundle param) {
|
||||
startActivity(null, activityName, param, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* start Activity
|
||||
* @param starter Initiator, either {@link Context} or {@link Fragment}
|
||||
* @param activityName activity name,such as "TUIGroupChatActivity"
|
||||
* @param param pass parameters
|
||||
*/
|
||||
public static void startActivity(@Nullable Object starter, String activityName, Bundle param) {
|
||||
startActivity(starter, activityName, param, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* start Activity
|
||||
* @param starter Initiator, either {@link Context} or {@link Fragment}
|
||||
* @param activityName activity name,such as "TUIGroupChatActivity"
|
||||
* @param param pass parameters
|
||||
* @param requestCode The request value passed to the Activity, used to return the result in the initiator's
|
||||
* onActivityResult method when the Activity ends, greater than or equal to 0 is valid.
|
||||
*/
|
||||
public static void startActivity(@Nullable Object starter, String activityName, Bundle param, int requestCode) {
|
||||
TUIRouter.Navigation navigation = TUIRouter.getInstance().setDestination(activityName).putExtras(param);
|
||||
if (starter instanceof Fragment) {
|
||||
navigation.navigate((Fragment) starter, requestCode);
|
||||
} else if (starter instanceof Context) {
|
||||
navigation.navigate((Context) starter, requestCode);
|
||||
} else {
|
||||
navigation.navigate((Context) null, requestCode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register event
|
||||
*/
|
||||
public static void registerEvent(String key, String subKey, ITUINotification notification) {
|
||||
EventManager.getInstance().registerEvent(key, subKey, notification);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister event
|
||||
*/
|
||||
public static void unRegisterEvent(String key, String subKey, ITUINotification notification) {
|
||||
EventManager.getInstance().unRegisterEvent(key, subKey, notification);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all notifications for the specified notification object
|
||||
*/
|
||||
public static void unRegisterEvent(ITUINotification notification) {
|
||||
EventManager.getInstance().unRegisterEvent(notification);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify event
|
||||
*/
|
||||
public static void notifyEvent(String key, String subKey, Map<String, Object> param) {
|
||||
EventManager.getInstance().notifyEvent(key, subKey, param);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register extension
|
||||
*/
|
||||
public static void registerExtension(String key, ITUIExtension extension) {
|
||||
ExtensionManager.getInstance().registerExtension(key, extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister extension
|
||||
*/
|
||||
public static void unRegisterExtension(String key, ITUIExtension extension) {
|
||||
ExtensionManager.getInstance().unRegisterExtension(key, extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Extension
|
||||
*/
|
||||
public static Map<String, Object> getExtensionInfo(String key, Map<String, Object> param) {
|
||||
return ExtensionManager.getInstance().getExtensionInfo(key, param);
|
||||
}
|
||||
|
||||
}
|
||||
463
tuicore/src/main/java/com/tencent/qcloud/tuicore/TUILogin.java
Normal file
@@ -0,0 +1,463 @@
|
||||
package com.tencent.qcloud.tuicore;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.tencent.imsdk.v2.V2TIMCallback;
|
||||
import com.tencent.imsdk.v2.V2TIMLogListener;
|
||||
import com.tencent.imsdk.v2.V2TIMManager;
|
||||
import com.tencent.imsdk.v2.V2TIMSDKConfig;
|
||||
import com.tencent.imsdk.v2.V2TIMSDKListener;
|
||||
import com.tencent.imsdk.v2.V2TIMUserFullInfo;
|
||||
import com.tencent.imsdk.v2.V2TIMValueCallback;
|
||||
import com.tencent.qcloud.tuicore.interfaces.TUICallback;
|
||||
import com.tencent.qcloud.tuicore.interfaces.TUILogListener;
|
||||
import com.tencent.qcloud.tuicore.interfaces.TUILoginConfig;
|
||||
import com.tencent.qcloud.tuicore.interfaces.TUILoginListener;
|
||||
import com.tencent.qcloud.tuicore.util.ErrorMessageConverter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import static com.tencent.imsdk.v2.V2TIMManager.V2TIM_STATUS_LOGINED;
|
||||
|
||||
|
||||
/**
|
||||
* Login logic for IM and TRTC
|
||||
*/
|
||||
public class TUILogin {
|
||||
private static final String TAG = TUILogin.class.getSimpleName();
|
||||
|
||||
private static class TUILoginHolder {
|
||||
private static final TUILogin loginInstance = new TUILogin();
|
||||
}
|
||||
|
||||
public static TUILogin getInstance() {
|
||||
return TUILoginHolder.loginInstance;
|
||||
}
|
||||
|
||||
private Context appContext;
|
||||
private int sdkAppId = 0;
|
||||
private String userId;
|
||||
private String userSig;
|
||||
private boolean hasLoginSuccess = false;
|
||||
|
||||
private final List<TUILoginListener> listenerList = new CopyOnWriteArrayList<>();
|
||||
|
||||
private TUILogin() {}
|
||||
|
||||
private final V2TIMSDKListener imSdkListener = new V2TIMSDKListener() {
|
||||
@Override
|
||||
public void onConnecting() {
|
||||
for (TUILoginListener listener : listenerList) {
|
||||
listener.onConnecting();
|
||||
}
|
||||
TUICore.notifyEvent(TUIConstants.NetworkConnection.EVENT_CONNECTION_STATE_CHANGED,
|
||||
TUIConstants.NetworkConnection.EVENT_SUB_KEY_CONNECTING, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectSuccess() {
|
||||
for (TUILoginListener listener : listenerList) {
|
||||
listener.onConnectSuccess();
|
||||
}
|
||||
TUICore.notifyEvent(TUIConstants.NetworkConnection.EVENT_CONNECTION_STATE_CHANGED,
|
||||
TUIConstants.NetworkConnection.EVENT_SUB_KEY_CONNECT_SUCCESS, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectFailed(int code, String error) {
|
||||
for (TUILoginListener listener : listenerList) {
|
||||
listener.onConnectFailed(code, error);
|
||||
}
|
||||
TUICore.notifyEvent(TUIConstants.NetworkConnection.EVENT_CONNECTION_STATE_CHANGED,
|
||||
TUIConstants.NetworkConnection.EVENT_SUB_KEY_CONNECT_FAILED, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKickedOffline() {
|
||||
for (TUILoginListener listener : listenerList) {
|
||||
listener.onKickedOffline();
|
||||
}
|
||||
TUICore.notifyEvent(TUIConstants.TUILogin.EVENT_LOGIN_STATE_CHANGED,
|
||||
TUIConstants.TUILogin.EVENT_SUB_KEY_USER_KICKED_OFFLINE, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserSigExpired() {
|
||||
for (TUILoginListener listener : listenerList) {
|
||||
listener.onUserSigExpired();
|
||||
}
|
||||
TUICore.notifyEvent(TUIConstants.TUILogin.EVENT_LOGIN_STATE_CHANGED,
|
||||
TUIConstants.TUILogin.EVENT_SUB_KEY_USER_SIG_EXPIRED, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSelfInfoUpdated(V2TIMUserFullInfo info) {
|
||||
TUIConfig.setSelfInfo(info);
|
||||
notifyUserInfoChanged(info);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* IMSDK login
|
||||
*
|
||||
* @param context The context of the application, generally is ApplicationContext
|
||||
* @param sdkAppId Assigned when you register your app with Tencent Cloud
|
||||
* @param userId User ID
|
||||
* @param userSig Obtained from the business server
|
||||
* @param callback login callback
|
||||
*/
|
||||
public static void login(@NonNull Context context, int sdkAppId, String userId, String userSig, TUICallback callback) {
|
||||
getInstance().internalLogin(context, sdkAppId, userId, userSig, null, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* IMSDK login
|
||||
*
|
||||
* @param context The context of the application, generally is ApplicationContext
|
||||
* @param sdkAppId Assigned when you register your app with Tencent Cloud
|
||||
* @param userId User ID
|
||||
* @param userSig Obtained from the business server
|
||||
* @param config log related configs
|
||||
* @param callback login callback
|
||||
*/
|
||||
public static void login(@NonNull Context context, int sdkAppId, String userId, String userSig, TUILoginConfig config, TUICallback callback) {
|
||||
getInstance().internalLogin(context, sdkAppId, userId, userSig, config, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* IMSDK logout
|
||||
* @param callback logout callback
|
||||
*/
|
||||
public static void logout(TUICallback callback) {
|
||||
getInstance().internalLogout(callback);
|
||||
}
|
||||
|
||||
public static void addLoginListener(TUILoginListener listener) {
|
||||
getInstance().internalAddLoginListener(listener);
|
||||
}
|
||||
|
||||
public static void removeLoginListener(TUILoginListener listener) {
|
||||
getInstance().internalRemoveLoginListener(listener);
|
||||
}
|
||||
|
||||
private void internalLogin(Context context, final int sdkAppId, final String userId, final String userSig, TUILoginConfig config, TUICallback callback) {
|
||||
if (this.sdkAppId != 0 && sdkAppId != this.sdkAppId) {
|
||||
logout((TUICallback) null);
|
||||
}
|
||||
this.appContext = context.getApplicationContext();
|
||||
this.sdkAppId = sdkAppId;
|
||||
V2TIMManager.getInstance().addIMSDKListener(imSdkListener);
|
||||
// Notify init event
|
||||
TUICore.notifyEvent(TUIConstants.TUILogin.EVENT_IMSDK_INIT_STATE_CHANGED, TUIConstants.TUILogin.EVENT_SUB_KEY_START_INIT, null);
|
||||
// User operation initialization, the privacy agreement has been read by default
|
||||
|
||||
V2TIMSDKConfig v2TIMSDKConfig = null;
|
||||
if (config != null) {
|
||||
v2TIMSDKConfig = new V2TIMSDKConfig();
|
||||
v2TIMSDKConfig.setLogLevel(config.getLogLevel());
|
||||
TUILogListener logListener = config.getLogListener();
|
||||
if (logListener != null) {
|
||||
v2TIMSDKConfig.setLogListener(new V2TIMLogListener() {
|
||||
@Override
|
||||
public void onLog(int logLevel, String logContent) {
|
||||
logListener.onLog(logLevel, logContent);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
boolean initSuccess = V2TIMManager.getInstance().initSDK(context, sdkAppId, v2TIMSDKConfig);
|
||||
if (initSuccess) {
|
||||
this.userId = userId;
|
||||
this.userSig = userSig;
|
||||
if (TextUtils.equals(userId, V2TIMManager.getInstance().getLoginUser()) && !TextUtils.isEmpty(userId)) {
|
||||
TUICallback.onSuccess(callback);
|
||||
getUserInfo(userId);
|
||||
return;
|
||||
}
|
||||
|
||||
V2TIMManager.getInstance().login(userId, userSig, new V2TIMCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
hasLoginSuccess = true;
|
||||
getUserInfo(userId);
|
||||
TUICallback.onSuccess(callback);
|
||||
TUICore.notifyEvent(TUIConstants.TUILogin.EVENT_LOGIN_STATE_CHANGED, TUIConstants.TUILogin.EVENT_SUB_KEY_USER_LOGIN_SUCCESS, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUICallback.onError(callback, code, ErrorMessageConverter.convertIMError(code, desc));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
TUICallback.onError(callback, -1, "init failed");
|
||||
}
|
||||
}
|
||||
|
||||
private void internalLogout(TUICallback callback) {
|
||||
// Notify unit event
|
||||
TUICore.notifyEvent(TUIConstants.TUILogin.EVENT_IMSDK_INIT_STATE_CHANGED, TUIConstants.TUILogin.EVENT_SUB_KEY_START_UNINIT, null);
|
||||
V2TIMManager.getInstance().logout(new V2TIMCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
sdkAppId = 0;
|
||||
userId = null;
|
||||
userSig = null;
|
||||
V2TIMManager.getInstance().unInitSDK();
|
||||
TUIConfig.clearSelfInfo();
|
||||
TUICallback.onSuccess(callback);
|
||||
TUICore.notifyEvent(TUIConstants.TUILogin.EVENT_LOGIN_STATE_CHANGED, TUIConstants.TUILogin.EVENT_SUB_KEY_USER_LOGOUT_SUCCESS, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUICallback.onError(callback, code, desc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void internalAddLoginListener(TUILoginListener listener) {
|
||||
Log.i(TAG, "addLoginListener listener : " + listener);
|
||||
if (listener == null) {
|
||||
return;
|
||||
}
|
||||
if (!listenerList.contains(listener)) {
|
||||
listenerList.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
private void internalRemoveLoginListener(TUILoginListener listener) {
|
||||
Log.i(TAG, "removeLoginListener listener : " + listener);
|
||||
if (listener == null) {
|
||||
return;
|
||||
}
|
||||
listenerList.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* IMSDK init
|
||||
*
|
||||
* @param context The context of the application, generally is ApplicationContext
|
||||
* @param sdkAppId Assigned when you register your app with Tencent Cloud
|
||||
* @param config The related configuration items of IMSDK, generally use the default,
|
||||
* and need special configuration, please refer to the API documentation
|
||||
* @param listener Listener of IMSDK init
|
||||
* @return true:init success;false:init failed
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean init(@NonNull Context context, int sdkAppId, @Nullable V2TIMSDKConfig config, @Nullable V2TIMSDKListener listener) {
|
||||
if (getInstance().sdkAppId != 0 && sdkAppId != getInstance().sdkAppId) {
|
||||
logout((V2TIMCallback) null);
|
||||
unInit();
|
||||
}
|
||||
getInstance().appContext = context.getApplicationContext();
|
||||
getInstance().sdkAppId = sdkAppId;
|
||||
V2TIMManager.getInstance().addIMSDKListener(new V2TIMSDKListener() {
|
||||
@Override
|
||||
public void onConnecting() {
|
||||
if (listener != null) {
|
||||
listener.onConnecting();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectSuccess() {
|
||||
if (listener != null) {
|
||||
listener.onConnectSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectFailed(int code, String error) {
|
||||
if (listener != null) {
|
||||
listener.onConnectFailed(code, ErrorMessageConverter.convertIMError(code, error));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKickedOffline() {
|
||||
if (listener != null) {
|
||||
listener.onKickedOffline();
|
||||
}
|
||||
TUICore.notifyEvent(TUIConstants.TUILogin.EVENT_LOGIN_STATE_CHANGED,
|
||||
TUIConstants.TUILogin.EVENT_SUB_KEY_USER_KICKED_OFFLINE, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserSigExpired() {
|
||||
if (listener != null) {
|
||||
listener.onUserSigExpired();
|
||||
}
|
||||
TUICore.notifyEvent(TUIConstants.TUILogin.EVENT_LOGIN_STATE_CHANGED,
|
||||
TUIConstants.TUILogin.EVENT_SUB_KEY_USER_SIG_EXPIRED, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSelfInfoUpdated(V2TIMUserFullInfo info) {
|
||||
if (listener != null) {
|
||||
listener.onSelfInfoUpdated(info);
|
||||
}
|
||||
|
||||
TUIConfig.setSelfInfo(info);
|
||||
notifyUserInfoChanged(info);
|
||||
}
|
||||
});
|
||||
TUICore.notifyEvent(TUIConstants.TUILogin.EVENT_IMSDK_INIT_STATE_CHANGED, TUIConstants.TUILogin.EVENT_SUB_KEY_START_INIT, null);
|
||||
return V2TIMManager.getInstance().initSDK(context, sdkAppId, config);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void unInit() {
|
||||
getInstance().sdkAppId = 0;
|
||||
TUICore.notifyEvent(TUIConstants.TUILogin.EVENT_IMSDK_INIT_STATE_CHANGED, TUIConstants.TUILogin.EVENT_SUB_KEY_START_UNINIT, null);
|
||||
|
||||
V2TIMManager.getInstance().unInitSDK();
|
||||
TUIConfig.clearSelfInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* User Login
|
||||
*
|
||||
* @param userId User ID
|
||||
* @param userSig Obtained from the business server
|
||||
* @param callback login callback
|
||||
*/
|
||||
@Deprecated
|
||||
public static void login(@NonNull String userId, @NonNull String userSig, @Nullable V2TIMCallback callback) {
|
||||
getInstance().userId = userId;
|
||||
getInstance().userSig = userSig;
|
||||
if (TextUtils.equals(userId, V2TIMManager.getInstance().getLoginUser()) && !TextUtils.isEmpty(userId)) {
|
||||
if (callback != null) {
|
||||
callback.onSuccess();
|
||||
}
|
||||
getUserInfo(userId);
|
||||
return;
|
||||
}
|
||||
|
||||
V2TIMManager.getInstance().login(userId, userSig, new V2TIMCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
getInstance().hasLoginSuccess = true;
|
||||
if (callback != null) {
|
||||
callback.onSuccess();
|
||||
}
|
||||
getUserInfo(userId);
|
||||
TUICore.notifyEvent(TUIConstants.TUILogin.EVENT_LOGIN_STATE_CHANGED, TUIConstants.TUILogin.EVENT_SUB_KEY_USER_LOGIN_SUCCESS, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
if (callback != null) {
|
||||
callback.onError(code, ErrorMessageConverter.convertIMError(code, desc));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* User Logout
|
||||
*
|
||||
* @param callback Logout callback
|
||||
*/
|
||||
@Deprecated
|
||||
public static void logout(@Nullable V2TIMCallback callback) {
|
||||
V2TIMManager.getInstance().logout(new V2TIMCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
getInstance().userId = null;
|
||||
getInstance().userSig = null;
|
||||
if (callback != null) {
|
||||
callback.onSuccess();
|
||||
}
|
||||
TUIConfig.clearSelfInfo();
|
||||
|
||||
TUICore.notifyEvent(TUIConstants.TUILogin.EVENT_LOGIN_STATE_CHANGED, TUIConstants.TUILogin.EVENT_SUB_KEY_USER_LOGOUT_SUCCESS, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
if (callback != null) {
|
||||
callback.onError(code, ErrorMessageConverter.convertIMError(code, desc));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void getUserInfo(String userId) {
|
||||
List<String> userIdList = new ArrayList<>();
|
||||
userIdList.add(userId);
|
||||
V2TIMManager.getInstance().getUsersInfo(userIdList, new V2TIMValueCallback<List<V2TIMUserFullInfo>>() {
|
||||
@Override
|
||||
public void onSuccess(List<V2TIMUserFullInfo> v2TIMUserFullInfos) {
|
||||
if (v2TIMUserFullInfos.isEmpty()) {
|
||||
Log.e(TAG, "get logined userInfo failed. list is empty");
|
||||
return;
|
||||
}
|
||||
V2TIMUserFullInfo userFullInfo = v2TIMUserFullInfos.get(0);
|
||||
TUIConfig.setSelfInfo(userFullInfo);
|
||||
notifyUserInfoChanged(userFullInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
Log.e(TAG, "get logined userInfo failed. code : " + code + " desc : " + ErrorMessageConverter.convertIMError(code, desc));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void notifyUserInfoChanged(V2TIMUserFullInfo userFullInfo) {
|
||||
HashMap<String, Object> param = new HashMap<>();
|
||||
param.put(TUIConstants.TUILogin.SELF_ID, userFullInfo.getUserID());
|
||||
param.put(TUIConstants.TUILogin.SELF_SIGNATURE, userFullInfo.getSelfSignature());
|
||||
param.put(TUIConstants.TUILogin.SELF_NICK_NAME, userFullInfo.getNickName());
|
||||
param.put(TUIConstants.TUILogin.SELF_FACE_URL, userFullInfo.getFaceUrl());
|
||||
param.put(TUIConstants.TUILogin.SELF_BIRTHDAY, userFullInfo.getBirthday());
|
||||
param.put(TUIConstants.TUILogin.SELF_ROLE, userFullInfo.getRole());
|
||||
param.put(TUIConstants.TUILogin.SELF_GENDER, userFullInfo.getGender());
|
||||
param.put(TUIConstants.TUILogin.SELF_LEVEL, userFullInfo.getLevel());
|
||||
param.put(TUIConstants.TUILogin.SELF_ALLOW_TYPE, userFullInfo.getAllowType());
|
||||
TUICore.notifyEvent(TUIConstants.TUILogin.EVENT_LOGIN_STATE_CHANGED,
|
||||
TUIConstants.TUILogin.EVENT_SUB_KEY_USER_INFO_UPDATED, param);
|
||||
}
|
||||
|
||||
public static int getSdkAppId() {
|
||||
return getInstance().sdkAppId;
|
||||
}
|
||||
|
||||
public static String getUserId() {
|
||||
return getInstance().userId;
|
||||
}
|
||||
|
||||
public static String getUserSig() {
|
||||
return getInstance().userSig;
|
||||
}
|
||||
|
||||
public static String getNickName() {
|
||||
return TUIConfig.getSelfNickName();
|
||||
}
|
||||
|
||||
public static String getFaceUrl() {
|
||||
return TUIConfig.getSelfFaceUrl();
|
||||
}
|
||||
|
||||
public static Context getAppContext() {
|
||||
return getInstance().appContext;
|
||||
}
|
||||
|
||||
public static boolean isUserLogined() {
|
||||
return getInstance().hasLoginSuccess && V2TIMManager.getInstance().getLoginStatus() == V2TIM_STATUS_LOGINED;
|
||||
}
|
||||
|
||||
public static String getLoginUser() {
|
||||
return V2TIMManager.getInstance().getLoginUser();
|
||||
}
|
||||
}
|
||||
356
tuicore/src/main/java/com/tencent/qcloud/tuicore/TUIRouter.java
Normal file
@@ -0,0 +1,356 @@
|
||||
package com.tencent.qcloud.tuicore;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* For Activity routing jump, only used inside TUICore, not exposed to the outside
|
||||
*/
|
||||
class TUIRouter {
|
||||
private static final String TAG = TUIRouter.class.getSimpleName();
|
||||
|
||||
private static final TUIRouter router = new TUIRouter();
|
||||
|
||||
public static TUIRouter getInstance() {
|
||||
return router;
|
||||
}
|
||||
|
||||
private static final Map<String, String> routerMap = new HashMap<>();
|
||||
|
||||
private static Context context;
|
||||
|
||||
private static boolean initialized = false;
|
||||
|
||||
private TUIRouter() {
|
||||
}
|
||||
|
||||
public synchronized static void init(Context context) {
|
||||
if (initialized) {
|
||||
return;
|
||||
}
|
||||
TUIRouter.context = context;
|
||||
if (context == null) {
|
||||
Log.e(TAG, "init failed, context is null.");
|
||||
return;
|
||||
}
|
||||
initRouter(context);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
public Navigation setDestination(String path) {
|
||||
Navigation navigation = new Navigation();
|
||||
navigation.setDestination(path);
|
||||
return navigation;
|
||||
}
|
||||
|
||||
static class Navigation {
|
||||
String destination;
|
||||
Bundle options;
|
||||
Intent intent = new Intent();
|
||||
|
||||
public Navigation setOptions(Bundle options) {
|
||||
this.options = options;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, boolean value) {
|
||||
intent.putExtra(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, byte value) {
|
||||
intent.putExtra(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, char value) {
|
||||
intent.putExtra(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, short value) {
|
||||
intent.putExtra(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, int value) {
|
||||
intent.putExtra(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, long value) {
|
||||
intent.putExtra(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, float value) {
|
||||
intent.putExtra(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, double value) {
|
||||
intent.putExtra(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, String value) {
|
||||
if (value != null) {
|
||||
intent.putExtra(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, CharSequence value) {
|
||||
if (value != null) {
|
||||
intent.putExtra(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, Parcelable value) {
|
||||
if (value != null) {
|
||||
intent.putExtra(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, Parcelable[] value) {
|
||||
if (value != null) {
|
||||
intent.putExtra(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, Serializable value) {
|
||||
if (value != null) {
|
||||
intent.putExtra(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, boolean[] value) {
|
||||
if (value != null) {
|
||||
intent.putExtra(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, byte[] value) {
|
||||
if (value != null) {
|
||||
intent.putExtra(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, short[] value) {
|
||||
if (value != null) {
|
||||
intent.putExtra(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, char[] value) {
|
||||
if (value != null) {
|
||||
intent.putExtra(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, int[] value) {
|
||||
if (value != null) {
|
||||
intent.putExtra(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, long[] value) {
|
||||
if (value != null) {
|
||||
intent.putExtra(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, float[] value) {
|
||||
if (value != null) {
|
||||
intent.putExtra(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, double[] value) {
|
||||
if (value != null) {
|
||||
intent.putExtra(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, String[] value) {
|
||||
if (value != null) {
|
||||
intent.putExtra(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, CharSequence[] value) {
|
||||
if (value != null) {
|
||||
intent.putExtra(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtra(String key, Bundle value) {
|
||||
if (value != null) {
|
||||
intent.putExtra(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtras(Bundle bundle) {
|
||||
if (bundle != null) {
|
||||
intent.putExtras(bundle);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation putExtras(Intent src) {
|
||||
if (src != null) {
|
||||
intent.putExtras(src);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation setDestination(String path) {
|
||||
destination = routerMap.get(path);
|
||||
if (destination == null) {
|
||||
Log.e(TAG, "destination is null.");
|
||||
return this;
|
||||
}
|
||||
intent.setComponent(new ComponentName(TUIRouter.context, destination));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Navigation setIntent(Intent intent) {
|
||||
this.intent = intent;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Intent getIntent() {
|
||||
return this.intent;
|
||||
}
|
||||
|
||||
public void navigate() {
|
||||
navigate((Context) null);
|
||||
}
|
||||
|
||||
public void navigate(Context context) {
|
||||
navigate(context, -1);
|
||||
}
|
||||
|
||||
public void navigate(Fragment fragment) {
|
||||
navigate(fragment, -1);
|
||||
}
|
||||
|
||||
public void navigate(Fragment fragment, int requestCode) {
|
||||
if (!initialized) {
|
||||
Log.e(TAG, "have not initialized.");
|
||||
return;
|
||||
}
|
||||
if (intent == null) {
|
||||
Log.e(TAG, "intent is null.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (fragment != null) {
|
||||
if (requestCode >= 0) {
|
||||
fragment.startActivityForResult(intent, requestCode);
|
||||
} else {
|
||||
fragment.startActivity(intent, options);
|
||||
}
|
||||
} else {
|
||||
startActivity(null, requestCode);
|
||||
}
|
||||
} catch (ActivityNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void navigate(Context context, int requestCode) {
|
||||
if (!initialized) {
|
||||
Log.e(TAG, "have not initialized.");
|
||||
return;
|
||||
}
|
||||
if (intent == null) {
|
||||
Log.e(TAG, "intent is null.");
|
||||
return;
|
||||
}
|
||||
Context startContext = context;
|
||||
if (context == null) {
|
||||
startContext = TUIRouter.context;
|
||||
}
|
||||
startActivity(startContext, requestCode);
|
||||
}
|
||||
|
||||
private void startActivity(Context context, int requestCode) {
|
||||
if (context == null) {
|
||||
Log.e(TAG, "StartActivity failed, context is null.Please init");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (context instanceof Activity && requestCode >= 0) {
|
||||
ActivityCompat.startActivityForResult((Activity) context, intent, requestCode, options);
|
||||
} else {
|
||||
if (!(context instanceof Activity)) {
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
}
|
||||
ActivityCompat.startActivity(context, intent, options);
|
||||
}
|
||||
} catch (ActivityNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void initRouter(Context context) {
|
||||
ActivityInfo[] activityInfos = null;
|
||||
List<String> activityNames = new ArrayList<>();
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
try {
|
||||
PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), PackageManager.GET_ACTIVITIES);
|
||||
activityInfos = packageInfo.activities;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (activityInfos != null) {
|
||||
for (ActivityInfo activityInfo : activityInfos) {
|
||||
activityNames.add(activityInfo.name);
|
||||
}
|
||||
}
|
||||
for (String activityName : activityNames) {
|
||||
String[] splitStr = activityName.split("\\.");
|
||||
routerMap.put(splitStr[splitStr.length - 1], activityName);
|
||||
}
|
||||
}
|
||||
|
||||
public static Context getContext() {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
package com.tencent.qcloud.tuicore;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.webkit.WebView;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.tencent.qcloud.tuicore.util.SPUtils;
|
||||
import com.tencent.qcloud.tuicore.util.TUIBuild;
|
||||
import com.tencent.qcloud.tuicore.util.TUIUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Static skinning, language
|
||||
*/
|
||||
public class TUIThemeManager {
|
||||
private static final String TAG = TUIThemeManager.class.getSimpleName();
|
||||
|
||||
private static final String SP_THEME_AND_LANGUAGE_NAME = "TUIThemeAndLanguage";
|
||||
private static final String SP_KEY_LANGUAGE = "language";
|
||||
private static final String SP_KEY_THEME = "theme";
|
||||
|
||||
public static final int THEME_LIGHT = 0; // default
|
||||
public static final int THEME_LIVELY = 1;
|
||||
public static final int THEME_SERIOUS = 2;
|
||||
|
||||
public static final String LANGUAGE_ZH_CN = "zh";
|
||||
public static final String LANGUAGE_EN = "en";
|
||||
|
||||
private static final class ThemeManagerHolder {
|
||||
private static final TUIThemeManager instance = new TUIThemeManager();
|
||||
}
|
||||
|
||||
public static TUIThemeManager getInstance() {
|
||||
return ThemeManagerHolder.instance;
|
||||
}
|
||||
|
||||
private boolean isInit = false;
|
||||
|
||||
private final Map<Integer, List<Integer>> themeResIDMap = new HashMap<>();
|
||||
private final Map<String, Locale> languageMap = new HashMap<>();
|
||||
|
||||
private int currentThemeID = THEME_LIGHT;
|
||||
private String currentLanguage = "";
|
||||
private Locale defaultLocale = null;
|
||||
|
||||
private TUIThemeManager() {
|
||||
languageMap.put(LANGUAGE_ZH_CN, Locale.SIMPLIFIED_CHINESE);
|
||||
languageMap.put(LANGUAGE_EN, Locale.ENGLISH);
|
||||
}
|
||||
|
||||
public static void setTheme(Context context) {
|
||||
getInstance().setThemeInternal(context);
|
||||
}
|
||||
|
||||
private void setThemeInternal(Context context) {
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Context appContext = context.getApplicationContext();
|
||||
if (!isInit) {
|
||||
isInit = true;
|
||||
if (appContext instanceof Application) {
|
||||
((Application) appContext).registerActivityLifecycleCallbacks(new ThemeAndLanguageCallback());
|
||||
}
|
||||
|
||||
Locale defaultLocale = getLocale(appContext);
|
||||
SPUtils spUtils = SPUtils.getInstance(SP_THEME_AND_LANGUAGE_NAME);
|
||||
currentLanguage = spUtils.getString(SP_KEY_LANGUAGE, defaultLocale.getLanguage());
|
||||
currentThemeID = spUtils.getInt(SP_KEY_THEME, THEME_LIGHT);
|
||||
|
||||
// The language only needs to be initialized once
|
||||
applyLanguage(appContext);
|
||||
}
|
||||
// The theme needs to be updated multiple times
|
||||
applyTheme(appContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Solve the problem that WebView on Android 7 and above causes failure to switch languages.
|
||||
* Solve the problem of using WebView Crash for multiple processes above Android 9.
|
||||
*/
|
||||
public static void setWebViewLanguage(Context appContext) {
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
WebView.setDataDirectorySuffix(TUIUtil.getProcessName());
|
||||
}
|
||||
new WebView(appContext).destroy();
|
||||
} catch (Throwable throwable) {
|
||||
Log.e("TUIThemeManager", "init language settings failed, " + throwable.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void setDefaultLocale(Locale defaultLocale) {
|
||||
this.defaultLocale = defaultLocale;
|
||||
}
|
||||
|
||||
public static void addTheme(int themeID, int resID) {
|
||||
if (resID == 0) {
|
||||
Log.e(TAG, "addTheme failed, theme resID is zero");
|
||||
return;
|
||||
}
|
||||
Log.i(TAG, "addTheme themeID=" + themeID + " resID=" + resID);
|
||||
List<Integer> themeResIDList = getInstance().themeResIDMap.get(themeID);
|
||||
if (themeResIDList == null) {
|
||||
themeResIDList = new ArrayList<>();
|
||||
getInstance().themeResIDMap.put(themeID, themeResIDList);
|
||||
}
|
||||
if (themeResIDList.contains(resID)) {
|
||||
return;
|
||||
}
|
||||
themeResIDList.add(resID);
|
||||
TUIThemeManager.getInstance().applyTheme(ServiceInitializer.getAppContext());
|
||||
}
|
||||
|
||||
public static void addLightTheme(int resId) {
|
||||
addTheme(THEME_LIGHT, resId);
|
||||
}
|
||||
|
||||
public static void addLivelyTheme(int resId) {
|
||||
addTheme(THEME_LIVELY, resId);
|
||||
}
|
||||
public static void addSeriousTheme(int resId) {
|
||||
addTheme(THEME_SERIOUS, resId);
|
||||
}
|
||||
|
||||
public int getCurrentTheme() {
|
||||
return currentThemeID;
|
||||
}
|
||||
|
||||
private void mergeTheme(Resources.Theme theme) {
|
||||
if (theme == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<Integer> currentThemeResIDList = themeResIDMap.get(currentThemeID);
|
||||
if (currentThemeResIDList == null) {
|
||||
return;
|
||||
}
|
||||
for (Integer resId : currentThemeResIDList) {
|
||||
theme.applyStyle(resId, true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void addLanguage(String language, Locale locale) {
|
||||
Log.i(TAG, "addLanguage language=" + language + " locale=" + locale);
|
||||
getInstance().languageMap.put(language, locale);
|
||||
}
|
||||
|
||||
public void changeLanguage(Context context, String language) {
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (TextUtils.equals(language, currentLanguage)) {
|
||||
return;
|
||||
}
|
||||
currentLanguage = language;
|
||||
SPUtils spUtils = SPUtils.getInstance(SP_THEME_AND_LANGUAGE_NAME);
|
||||
spUtils.put(SP_KEY_LANGUAGE, language, true);
|
||||
|
||||
applyLanguage(context.getApplicationContext());
|
||||
applyLanguage(context);
|
||||
}
|
||||
|
||||
public void applyLanguage(Context context) {
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
Locale locale = languageMap.get(currentLanguage);
|
||||
if (locale == null) {
|
||||
if (defaultLocale != null) {
|
||||
locale = defaultLocale;
|
||||
} else {
|
||||
locale = getLocale(context);
|
||||
}
|
||||
}
|
||||
|
||||
Resources resources = context.getResources();
|
||||
Configuration configuration = resources.getConfiguration();
|
||||
configuration.locale = locale;
|
||||
if (TUIBuild.getVersionInt() >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
configuration.setLocale(locale);
|
||||
}
|
||||
resources.updateConfiguration(configuration, null);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 25) {
|
||||
context = context.createConfigurationContext(configuration);
|
||||
context.getResources().updateConfiguration(configuration,
|
||||
resources.getDisplayMetrics());
|
||||
}
|
||||
}
|
||||
|
||||
public String getCurrentLanguage() {
|
||||
return currentLanguage;
|
||||
}
|
||||
|
||||
public Locale getLocale(Context context) {
|
||||
Locale locale;
|
||||
|
||||
if (TUIBuild.getVersionInt() < Build.VERSION_CODES.N) {
|
||||
locale = context.getResources().getConfiguration().locale;
|
||||
} else {
|
||||
locale = context.getResources().getConfiguration().getLocales().get(0);
|
||||
}
|
||||
return locale;
|
||||
}
|
||||
|
||||
public void changeTheme(Context context, int themeId) {
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (themeId == currentThemeID) {
|
||||
return;
|
||||
}
|
||||
currentThemeID = themeId;
|
||||
|
||||
SPUtils spUtils = SPUtils.getInstance(SP_THEME_AND_LANGUAGE_NAME);
|
||||
spUtils.put(SP_KEY_THEME, themeId, true);
|
||||
|
||||
applyTheme(context.getApplicationContext());
|
||||
applyTheme(context);
|
||||
}
|
||||
|
||||
private void applyTheme(Context context) {
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
Resources.Theme theme = context.getTheme();
|
||||
if (theme == null) {
|
||||
context.setTheme(R.style.TUIBaseTheme);
|
||||
theme = context.getTheme();
|
||||
}
|
||||
mergeTheme(theme);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resources for skinning
|
||||
*
|
||||
* @param context context
|
||||
* @param attrId custom attribute
|
||||
* @return resources for skinning
|
||||
*/
|
||||
public static int getAttrResId(Context context, int attrId) {
|
||||
if (context == null || attrId == 0) {
|
||||
return 0;
|
||||
}
|
||||
TypedValue typedValue = new TypedValue();
|
||||
context.getTheme().resolveAttribute(attrId, typedValue, true);
|
||||
return typedValue.resourceId;
|
||||
}
|
||||
|
||||
static class ThemeAndLanguageCallback implements Application.ActivityLifecycleCallbacks {
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
|
||||
TUIThemeManager.getInstance().applyTheme(activity);
|
||||
TUIThemeManager.getInstance().applyLanguage(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStarted(@NonNull Activity activity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResumed(@NonNull Activity activity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityPaused(@NonNull Activity activity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStopped(@NonNull Activity activity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityDestroyed(@NonNull Activity activity) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.tencent.qcloud.tuicore.component;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* https://stackoverflow.com/questions/30458640/recyclerview-java-lang-indexoutofboundsexception-inconsistency-detected-inval
|
||||
*/
|
||||
public class CustomLinearLayoutManager extends LinearLayoutManager {
|
||||
|
||||
public CustomLinearLayoutManager(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public CustomLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
|
||||
super(context, orientation, reverseLayout);
|
||||
}
|
||||
|
||||
public CustomLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
|
||||
try {
|
||||
super.onLayoutChildren(recycler, state);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
Log.w("CustomLinearLayoutManager", e.getLocalizedMessage());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package com.tencent.qcloud.tuicore.component;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
import com.tencent.qcloud.tuicore.util.ScreenUtil;
|
||||
|
||||
/**
|
||||
* Custom LineControllerView
|
||||
*/
|
||||
public class LineControllerView extends LinearLayout {
|
||||
|
||||
private String mName;
|
||||
private boolean mIsBottom;
|
||||
private boolean mIsTop;
|
||||
private String mContent;
|
||||
private boolean mIsJump;
|
||||
private boolean mIsSwitch;
|
||||
|
||||
private TextView mNameText;
|
||||
private TextView mContentText;
|
||||
private ImageView mNavArrowView;
|
||||
private Switch mSwitchView;
|
||||
private View mMask;
|
||||
|
||||
public LineControllerView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
LayoutInflater.from(context).inflate(R.layout.line_controller_view, this);
|
||||
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.LineControllerView, 0, 0);
|
||||
try {
|
||||
mName = ta.getString(R.styleable.LineControllerView_name);
|
||||
mContent = ta.getString(R.styleable.LineControllerView_subject);
|
||||
mIsBottom = ta.getBoolean(R.styleable.LineControllerView_isBottom, false);
|
||||
mIsTop = ta.getBoolean(R.styleable.LineControllerView_isTop, false);
|
||||
mIsJump = ta.getBoolean(R.styleable.LineControllerView_canNav, false);
|
||||
mIsSwitch = ta.getBoolean(R.styleable.LineControllerView_isSwitch, false);
|
||||
setUpView();
|
||||
} finally {
|
||||
ta.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpView() {
|
||||
mNameText = findViewById(R.id.name);
|
||||
mNameText.setText(mName);
|
||||
mContentText = findViewById(R.id.content);
|
||||
mContentText.setText(mContent);
|
||||
View bottomLine = findViewById(R.id.bottom_line);
|
||||
View topLine = findViewById(R.id.top_line);
|
||||
bottomLine.setVisibility(mIsBottom ? VISIBLE : GONE);
|
||||
topLine.setVisibility(mIsTop ? VISIBLE : GONE);
|
||||
mNavArrowView = findViewById(R.id.rightArrow);
|
||||
mNavArrowView.setVisibility(mIsJump ? VISIBLE : GONE);
|
||||
RelativeLayout contentLayout = findViewById(R.id.contentText);
|
||||
contentLayout.setVisibility(mIsSwitch ? GONE : VISIBLE);
|
||||
mSwitchView = findViewById(R.id.btnSwitch);
|
||||
mSwitchView.setVisibility(mIsSwitch ? VISIBLE : GONE);
|
||||
mMask = findViewById(R.id.disable_mask);
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return mContentText.getText().toString();
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.mContent = content;
|
||||
mContentText.setText(content);
|
||||
}
|
||||
|
||||
public void setSingleLine(boolean singleLine) {
|
||||
mContentText.setSingleLine(singleLine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to jump
|
||||
*
|
||||
* @param canNav
|
||||
*/
|
||||
public void setCanNav(boolean canNav) {
|
||||
this.mIsJump = canNav;
|
||||
mNavArrowView.setVisibility(canNav ? VISIBLE : GONE);
|
||||
if (canNav) {
|
||||
ViewGroup.LayoutParams params = mContentText.getLayoutParams();
|
||||
params.width = ScreenUtil.getPxByDp(120);
|
||||
params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
mContentText.setLayoutParams(params);
|
||||
mContentText.setTextIsSelectable(false);
|
||||
} else {
|
||||
ViewGroup.LayoutParams params = mContentText.getLayoutParams();
|
||||
params.width = ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
mContentText.setLayoutParams(params);
|
||||
mContentText.setTextIsSelectable(true);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isChecked() {
|
||||
return mSwitchView.isChecked();
|
||||
}
|
||||
|
||||
public void setChecked(boolean on) {
|
||||
mSwitchView.setChecked(on);
|
||||
}
|
||||
|
||||
public void setCheckListener(CompoundButton.OnCheckedChangeListener listener) {
|
||||
mSwitchView.setOnCheckedChangeListener(listener);
|
||||
}
|
||||
|
||||
public void setMask(boolean enableMask) {
|
||||
if (enableMask) {
|
||||
mMask.setVisibility(View.VISIBLE);
|
||||
mSwitchView.setEnabled(false);
|
||||
} else {
|
||||
mMask.setVisibility(View.GONE);
|
||||
mSwitchView.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.tencent.qcloud.tuicore.component;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PaintFlagsDrawFilter;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.RectF;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.AppCompatImageView;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
|
||||
public class RoundCornerImageView extends AppCompatImageView {
|
||||
private final Path path = new Path();
|
||||
private final RectF rectF = new RectF();
|
||||
private final PaintFlagsDrawFilter aliasFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
|
||||
private int radius;
|
||||
private int leftTopRadius;
|
||||
private int rightTopRadius;
|
||||
private int rightBottomRadius;
|
||||
private int leftBottomRadius;
|
||||
|
||||
public RoundCornerImageView(@NonNull Context context) {
|
||||
super(context);
|
||||
init(context, null);
|
||||
}
|
||||
|
||||
public RoundCornerImageView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context, attrs);
|
||||
}
|
||||
|
||||
public RoundCornerImageView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
private void init(Context context, AttributeSet attrs) {
|
||||
setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
||||
int defaultRadius = 0;
|
||||
if (attrs != null) {
|
||||
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.RoundCornerImageView);
|
||||
radius = array.getDimensionPixelOffset(R.styleable.RoundCornerImageView_corner_radius, defaultRadius);
|
||||
leftTopRadius = array.getDimensionPixelOffset(R.styleable.RoundCornerImageView_left_top_corner_radius, defaultRadius);
|
||||
rightTopRadius = array.getDimensionPixelOffset(R.styleable.RoundCornerImageView_right_top_corner_radius, defaultRadius);
|
||||
rightBottomRadius = array.getDimensionPixelOffset(R.styleable.RoundCornerImageView_right_bottom_corner_radius, defaultRadius);
|
||||
leftBottomRadius = array.getDimensionPixelOffset(R.styleable.RoundCornerImageView_left_bottom_corner_radius, defaultRadius);
|
||||
array.recycle();
|
||||
}
|
||||
|
||||
if (defaultRadius == leftTopRadius) {
|
||||
leftTopRadius = radius;
|
||||
}
|
||||
if (defaultRadius == rightTopRadius) {
|
||||
rightTopRadius = radius;
|
||||
}
|
||||
if (defaultRadius == rightBottomRadius) {
|
||||
rightBottomRadius = radius;
|
||||
}
|
||||
if (defaultRadius == leftBottomRadius) {
|
||||
leftBottomRadius = radius;
|
||||
}
|
||||
}
|
||||
|
||||
public void setLeftBottomRadius(int leftBottomRadius) {
|
||||
this.leftBottomRadius = leftBottomRadius;
|
||||
}
|
||||
|
||||
public void setLeftTopRadius(int leftTopRadius) {
|
||||
this.leftTopRadius = leftTopRadius;
|
||||
}
|
||||
|
||||
public void setRadius(int radius) {
|
||||
this.radius = radius;
|
||||
leftBottomRadius = radius;
|
||||
rightBottomRadius = radius;
|
||||
rightTopRadius = radius;
|
||||
leftTopRadius = radius;
|
||||
}
|
||||
|
||||
public void setRightBottomRadius(int rightBottomRadius) {
|
||||
this.rightBottomRadius = rightBottomRadius;
|
||||
}
|
||||
|
||||
public void setRightTopRadius(int rightTopRadius) {
|
||||
this.rightTopRadius = rightTopRadius;
|
||||
}
|
||||
|
||||
public int getLeftBottomRadius() {
|
||||
return leftBottomRadius;
|
||||
}
|
||||
|
||||
public int getLeftTopRadius() {
|
||||
return leftTopRadius;
|
||||
}
|
||||
|
||||
public int getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
public int getRightBottomRadius() {
|
||||
return rightBottomRadius;
|
||||
}
|
||||
|
||||
public int getRightTopRadius() {
|
||||
return rightTopRadius;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
path.reset();
|
||||
canvas.setDrawFilter(aliasFilter);
|
||||
rectF.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
|
||||
// left-top -> right-top -> right-bottom -> left-bottom
|
||||
float[] radius = {leftTopRadius, leftTopRadius, rightTopRadius, rightTopRadius,
|
||||
rightBottomRadius, rightBottomRadius, leftBottomRadius, leftBottomRadius};
|
||||
path.addRoundRect(rectF, radius, Path.Direction.CW);
|
||||
canvas.clipPath(path);
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.tencent.qcloud.tuicore.component;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PaintFlagsDrawFilter;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.RectF;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
|
||||
public class RoundFrameLayout extends FrameLayout {
|
||||
|
||||
private final Path path = new Path();
|
||||
private final RectF rectF = new RectF();
|
||||
private final PaintFlagsDrawFilter aliasFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
|
||||
private int radius;
|
||||
private int leftTopRadius;
|
||||
private int rightTopRadius;
|
||||
private int rightBottomRadius;
|
||||
private int leftBottomRadius;
|
||||
|
||||
public RoundFrameLayout(@NonNull Context context) {
|
||||
super(context);
|
||||
init(context, null);
|
||||
}
|
||||
|
||||
public RoundFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context, attrs);
|
||||
}
|
||||
|
||||
public RoundFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
private void init(Context context, AttributeSet attrs) {
|
||||
setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
||||
int defaultRadius = 0;
|
||||
if (attrs != null) {
|
||||
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.RoundFrameLayout);
|
||||
radius = array.getDimensionPixelOffset(R.styleable.RoundFrameLayout_corner_radius, defaultRadius);
|
||||
leftTopRadius = array.getDimensionPixelOffset(R.styleable.RoundFrameLayout_left_top_corner_radius, defaultRadius);
|
||||
rightTopRadius = array.getDimensionPixelOffset(R.styleable.RoundFrameLayout_right_top_corner_radius, defaultRadius);
|
||||
rightBottomRadius = array.getDimensionPixelOffset(R.styleable.RoundFrameLayout_right_bottom_corner_radius, defaultRadius);
|
||||
leftBottomRadius = array.getDimensionPixelOffset(R.styleable.RoundFrameLayout_left_bottom_corner_radius, defaultRadius);
|
||||
array.recycle();
|
||||
}
|
||||
|
||||
if (defaultRadius == leftTopRadius) {
|
||||
leftTopRadius = radius;
|
||||
}
|
||||
if (defaultRadius == rightTopRadius) {
|
||||
rightTopRadius = radius;
|
||||
}
|
||||
if (defaultRadius == rightBottomRadius) {
|
||||
rightBottomRadius = radius;
|
||||
}
|
||||
if (defaultRadius == leftBottomRadius) {
|
||||
leftBottomRadius = radius;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
path.reset();
|
||||
canvas.setDrawFilter(aliasFilter);
|
||||
rectF.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
|
||||
// left-top -> right-top -> right-bottom -> left-bottom
|
||||
float[] radius = {leftTopRadius, leftTopRadius, rightTopRadius, rightTopRadius,
|
||||
rightBottomRadius, rightBottomRadius, leftBottomRadius, leftBottomRadius};
|
||||
path.addRoundRect(rectF, radius, Path.Direction.CW);
|
||||
canvas.clipPath(path);
|
||||
super.dispatchDraw(canvas);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
package com.tencent.qcloud.tuicore.component;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
import com.tencent.qcloud.tuicore.TUIThemeManager;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.ITitleBarLayout;
|
||||
import com.tencent.qcloud.tuicore.util.ScreenUtil;
|
||||
|
||||
public class TitleBarLayout extends LinearLayout implements ITitleBarLayout {
|
||||
|
||||
private LinearLayout mLeftGroup;
|
||||
private LinearLayout mRightGroup;
|
||||
private TextView mLeftTitle;
|
||||
private TextView mCenterTitle;
|
||||
private TextView mRightTitle;
|
||||
private ImageView mLeftIcon;
|
||||
private ImageView mRightIcon;
|
||||
private RelativeLayout mTitleLayout;
|
||||
private UnreadCountTextView unreadCountTextView;
|
||||
private TextView mRightFollow;
|
||||
|
||||
public TitleBarLayout(Context context) {
|
||||
super(context);
|
||||
init(context, null);
|
||||
}
|
||||
|
||||
public TitleBarLayout(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context, attrs);
|
||||
}
|
||||
|
||||
public TitleBarLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(context, attrs);
|
||||
}
|
||||
|
||||
private void init(Context context, @Nullable AttributeSet attrs) {
|
||||
String middleTitle = null;
|
||||
boolean canReturn = false;
|
||||
if (attrs != null) {
|
||||
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.TitleBarLayout);
|
||||
middleTitle = array.getString(R.styleable.TitleBarLayout_title_bar_middle_title);
|
||||
canReturn = array.getBoolean(R.styleable.TitleBarLayout_title_bar_can_return, false);
|
||||
array.recycle();
|
||||
}
|
||||
inflate(context, R.layout.title_bar_layout, this);
|
||||
mTitleLayout = findViewById(R.id.page_title_layout);
|
||||
mLeftGroup = findViewById(R.id.page_title_left_group);
|
||||
mRightGroup = findViewById(R.id.page_title_right_group);
|
||||
mLeftTitle = findViewById(R.id.page_title_left_text);
|
||||
mRightTitle = findViewById(R.id.page_title_right_text);
|
||||
mCenterTitle = findViewById(R.id.page_title);
|
||||
mLeftIcon = findViewById(R.id.page_title_left_icon);
|
||||
mRightIcon = findViewById(R.id.page_title_right_icon);
|
||||
unreadCountTextView = findViewById(R.id.new_message_total_unread);
|
||||
mRightFollow = findViewById(R.id.page_title_follow_text);
|
||||
LayoutParams params = (LayoutParams) mTitleLayout.getLayoutParams();
|
||||
params.height = ScreenUtil.getPxByDp(50);
|
||||
mTitleLayout.setLayoutParams(params);
|
||||
// setBackgroundResource(TUIThemeManager.getAttrResId(getContext(), R.attr.core_title_bar_bg));
|
||||
|
||||
int iconSize = ScreenUtil.dip2px(20);
|
||||
ViewGroup.LayoutParams iconParams = mLeftIcon.getLayoutParams();
|
||||
iconParams.width = iconSize;
|
||||
iconParams.height = iconSize;
|
||||
mLeftIcon.setLayoutParams(iconParams);
|
||||
iconParams = mRightIcon.getLayoutParams();
|
||||
iconParams.width = iconSize;
|
||||
iconParams.height = iconSize;
|
||||
|
||||
mRightIcon.setLayoutParams(iconParams);
|
||||
|
||||
if (canReturn) {
|
||||
mLeftGroup.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (context instanceof Activity) {
|
||||
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.hideSoftInputFromWindow(TitleBarLayout.this.getWindowToken(), 0);
|
||||
((Activity) context).finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!TextUtils.isEmpty(middleTitle)) {
|
||||
mCenterTitle.setText(middleTitle);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnLeftClickListener(OnClickListener listener) {
|
||||
mLeftGroup.setOnClickListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnRightClickListener(OnClickListener listener) {
|
||||
mRightGroup.setOnClickListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTitle(String title, Position position) {
|
||||
switch (position) {
|
||||
case LEFT:
|
||||
mLeftTitle.setText(title);
|
||||
break;
|
||||
case RIGHT:
|
||||
mRightTitle.setText(title);
|
||||
break;
|
||||
case MIDDLE:
|
||||
mCenterTitle.setText(title);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinearLayout getLeftGroup() {
|
||||
return mLeftGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinearLayout getRightGroup() {
|
||||
return mRightGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageView getLeftIcon() {
|
||||
return mLeftIcon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLeftIcon(int resId) {
|
||||
mLeftIcon.setBackgroundResource(resId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageView getRightIcon() {
|
||||
return mRightIcon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRightIcon(int resId) {
|
||||
mRightIcon.setBackgroundResource(resId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextView getLeftTitle() {
|
||||
return mLeftTitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextView getMiddleTitle() {
|
||||
return mCenterTitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextView getRightTitle() {
|
||||
return mRightTitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextView getRightFollow() {
|
||||
return mRightFollow;
|
||||
}
|
||||
|
||||
public UnreadCountTextView getUnreadCountTextView() {
|
||||
return unreadCountTextView;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.tencent.qcloud.tuicore.component;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import androidx.appcompat.widget.AppCompatTextView;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
|
||||
|
||||
public class UnreadCountTextView extends AppCompatTextView {
|
||||
|
||||
private int mNormalSize;
|
||||
private Paint mPaint;
|
||||
|
||||
public UnreadCountTextView(Context context) {
|
||||
super(context);
|
||||
init(context, null);
|
||||
}
|
||||
|
||||
public UnreadCountTextView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context, attrs);
|
||||
}
|
||||
|
||||
public UnreadCountTextView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(context, attrs);
|
||||
}
|
||||
|
||||
private void init(Context context, AttributeSet attrs) {
|
||||
mNormalSize = dp2px(18.4f);
|
||||
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.UnreadCountTextView);
|
||||
int paintColor = typedArray.getColor(R.styleable.UnreadCountTextView_paint_color, getResources().getColor(R.color.read_dot_bg));
|
||||
typedArray.recycle();
|
||||
|
||||
mPaint = new Paint();
|
||||
mPaint.setColor(paintColor);
|
||||
mPaint.setAntiAlias(true);
|
||||
}
|
||||
|
||||
public void setPaintColor(int color) {
|
||||
if (mPaint != null) {
|
||||
mPaint.setColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
if (getText().length() == 0) {
|
||||
int l = (getMeasuredWidth() - dp2px(6)) / 2;
|
||||
int t = l;
|
||||
int r = getMeasuredWidth() - l;
|
||||
int b = r;
|
||||
canvas.drawOval(new RectF(l, t, r, b), mPaint);
|
||||
} else if (getText().length() == 1) {
|
||||
canvas.drawOval(new RectF(0, 0, mNormalSize, mNormalSize), mPaint);
|
||||
} else if (getText().length() > 1) {
|
||||
canvas.drawRoundRect(new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight()), getMeasuredHeight() / 2, getMeasuredHeight() / 2, mPaint);
|
||||
}
|
||||
super.onDraw(canvas);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int width = mNormalSize;
|
||||
int height = mNormalSize;
|
||||
if (getText().length() > 1) {
|
||||
width = mNormalSize + dp2px((getText().length() - 1) * 10);
|
||||
}
|
||||
setMeasuredDimension(width, height);
|
||||
}
|
||||
|
||||
private int dp2px(float dp) {
|
||||
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
|
||||
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.tencent.qcloud.tuicore.component.action;
|
||||
|
||||
|
||||
public interface PopActionClickListener {
|
||||
void onActionClick(int index, Object data);
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.tencent.qcloud.tuicore.component.action;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
import com.tencent.qcloud.tuicore.TUIConfig;
|
||||
import com.tencent.qcloud.tuicore.util.BackgroundTasks;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PopDialogAdapter extends BaseAdapter {
|
||||
|
||||
private List<PopMenuAction> dataSource = new ArrayList<>();
|
||||
|
||||
public void setDataSource(final List datas) {
|
||||
dataSource = datas;
|
||||
BackgroundTasks.getInstance().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return dataSource.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
return dataSource.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||
|
||||
ViewHolder holder;
|
||||
if (convertView == null) {
|
||||
convertView = LayoutInflater.from(TUIConfig.getAppContext()).inflate(R.layout.pop_dialog_adapter, parent, false);
|
||||
holder = new ViewHolder();
|
||||
holder.text = convertView.findViewById(R.id.pop_dialog_text);
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
PopMenuAction action = (PopMenuAction) getItem(position);
|
||||
holder.text.setText(action.getActionName());
|
||||
return convertView;
|
||||
}
|
||||
|
||||
static class ViewHolder {
|
||||
TextView text;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.tencent.qcloud.tuicore.component.action;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
public class PopMenuAction {
|
||||
|
||||
private String actionName;
|
||||
private Bitmap icon;
|
||||
private int iconResId;
|
||||
private PopActionClickListener actionClickListener;
|
||||
|
||||
public String getActionName() {
|
||||
return actionName;
|
||||
}
|
||||
|
||||
public void setActionName(String actionName) {
|
||||
this.actionName = actionName;
|
||||
}
|
||||
|
||||
public Bitmap getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public void setIcon(Bitmap mIcon) {
|
||||
this.icon = mIcon;
|
||||
}
|
||||
|
||||
|
||||
public int getIconResId() {
|
||||
return iconResId;
|
||||
}
|
||||
|
||||
public void setIconResId(int iconResId) {
|
||||
this.iconResId = iconResId;
|
||||
}
|
||||
|
||||
public PopActionClickListener getActionClickListener() {
|
||||
return actionClickListener;
|
||||
}
|
||||
|
||||
public void setActionClickListener(PopActionClickListener actionClickListener) {
|
||||
this.actionClickListener = actionClickListener;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package com.tencent.qcloud.tuicore.component.action;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
import com.tencent.qcloud.tuicore.TUIConfig;
|
||||
import com.tencent.qcloud.tuicore.util.BackgroundTasks;
|
||||
import com.tencent.qcloud.tuicore.util.ScreenUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PopMenuAdapter extends BaseAdapter {
|
||||
|
||||
private List<PopMenuAction> dataSource = new ArrayList<>();
|
||||
|
||||
public PopMenuAdapter() {
|
||||
|
||||
}
|
||||
|
||||
public void setDataSource(final List datas) {
|
||||
dataSource = datas;
|
||||
BackgroundTasks.getInstance().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return dataSource.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
return dataSource.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||
|
||||
ViewHolder holder;
|
||||
if (convertView == null) {
|
||||
convertView = LayoutInflater.from(TUIConfig.getAppContext()).inflate(R.layout.pop_menu_adapter, parent, false);
|
||||
holder = new ViewHolder();
|
||||
holder.menu_icon = convertView.findViewById(R.id.pop_menu_icon);
|
||||
|
||||
int iconSize = convertView.getResources().getDimensionPixelSize(R.dimen.core_pop_menu_icon_size);
|
||||
ViewGroup.LayoutParams params = holder.menu_icon.getLayoutParams();
|
||||
params.width = iconSize;
|
||||
params.height = iconSize;
|
||||
holder.menu_icon.setLayoutParams(params);
|
||||
|
||||
holder.menu_lable = convertView.findViewById(R.id.pop_menu_label);
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
PopMenuAction action = (PopMenuAction) getItem(position);
|
||||
holder.menu_icon.setVisibility(View.VISIBLE);
|
||||
if (action.getIcon() != null) {
|
||||
holder.menu_icon.setImageBitmap(action.getIcon());
|
||||
} else if (action.getIconResId() > 0) {
|
||||
holder.menu_icon.setImageResource(action.getIconResId());
|
||||
} else {
|
||||
holder.menu_icon.setVisibility(View.GONE);
|
||||
}
|
||||
holder.menu_lable.setText(action.getActionName());
|
||||
return convertView;
|
||||
}
|
||||
|
||||
static class ViewHolder {
|
||||
TextView menu_lable;
|
||||
ImageView menu_icon;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.tencent.qcloud.tuicore.component.activities;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
import com.tencent.qcloud.tuicore.TUIThemeManager;
|
||||
|
||||
|
||||
public class BaseLightActivity extends AppCompatActivity {
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
|
||||
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
getWindow().setStatusBarColor(getResources().getColor(TUIThemeManager.getAttrResId(this, R.attr.core_header_start_color)));
|
||||
getWindow().setNavigationBarColor(getResources().getColor(R.color.navigation_bar_color));
|
||||
int vis = getWindow().getDecorView().getSystemUiVisibility();
|
||||
vis |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
|
||||
vis |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
|
||||
getWindow().getDecorView().setSystemUiVisibility(vis);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
hideSoftInput();
|
||||
super.finish();
|
||||
}
|
||||
|
||||
public void hideSoftInput() {
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
Window window = getWindow();
|
||||
if (window != null) {
|
||||
imm.hideSoftInputFromWindow(window.getDecorView().getWindowToken(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.tencent.qcloud.tuicore.component.activities;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
import com.tencent.qcloud.tuicore.TUIThemeManager;
|
||||
|
||||
|
||||
public class BaseMinimalistLightActivity extends AppCompatActivity {
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
getWindow().setStatusBarColor(0xFFFFFFFF);
|
||||
getWindow().setNavigationBarColor(0xFFFFFFFF);
|
||||
int vis = getWindow().getDecorView().getSystemUiVisibility();
|
||||
vis |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
|
||||
vis |= View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
|
||||
getWindow().getDecorView().setSystemUiVisibility(vis);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
hideSoftInput();
|
||||
super.finish();
|
||||
}
|
||||
|
||||
public void hideSoftInput() {
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
Window window = getWindow();
|
||||
if (window != null) {
|
||||
imm.hideSoftInputFromWindow(window.getDecorView().getWindowToken(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,444 @@
|
||||
package com.tencent.qcloud.tuicore.component.activities;
|
||||
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
import com.bumptech.glide.load.engine.GlideException;
|
||||
import com.bumptech.glide.request.RequestListener;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUIThemeManager;
|
||||
import com.tencent.qcloud.tuicore.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuicore.component.gatherimage.SynthesizedImageView;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.ITitleBarLayout;
|
||||
import com.tencent.qcloud.tuicore.util.ScreenUtil;
|
||||
import com.tencent.qcloud.tuicore.util.ToastUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class ImageSelectActivity extends BaseLightActivity {
|
||||
private static final String TAG = ImageSelectActivity.class.getSimpleName();
|
||||
|
||||
public static final int RESULT_CODE_ERROR = -1;
|
||||
public static final int RESULT_CODE_SUCCESS = 0;
|
||||
public static final String TITLE = "title";
|
||||
public static final String SPAN_COUNT = "spanCount";
|
||||
public static final String DATA = "data";
|
||||
public static final String ITEM_HEIGHT = "itemHeight";
|
||||
public static final String ITEM_WIDTH = "itemWidth";
|
||||
public static final String SELECTED = "selected";
|
||||
public static final String PLACEHOLDER = "placeholder";
|
||||
public static final String NEED_DOWLOAD_LOCAL = "needdowmload";
|
||||
|
||||
private int defaultSpacing;
|
||||
|
||||
private List<ImageBean> data;
|
||||
private ImageBean selected;
|
||||
private int placeHolder;
|
||||
private int columnNum;
|
||||
private RecyclerView imageGrid;
|
||||
private GridLayoutManager gridLayoutManager;
|
||||
private ImageGridAdapter gridAdapter;
|
||||
private TitleBarLayout titleBarLayout;
|
||||
private int itemHeight;
|
||||
private int itemWidth;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
defaultSpacing = ScreenUtil.dip2px(12);
|
||||
setContentView(R.layout.core_activity_image_select_layout);
|
||||
Intent intent = getIntent();
|
||||
String title = intent.getStringExtra(TITLE);
|
||||
boolean needDownload = intent.getBooleanExtra(NEED_DOWLOAD_LOCAL, false);
|
||||
titleBarLayout = findViewById(R.id.image_select_title);
|
||||
titleBarLayout.setTitle(title, ITitleBarLayout.Position.MIDDLE);
|
||||
titleBarLayout.setTitle(getString(R.string.sure), ITitleBarLayout.Position.RIGHT);
|
||||
titleBarLayout.getRightIcon().setVisibility(View.GONE);
|
||||
titleBarLayout.getRightTitle().setTextColor(0xFF006EFF);
|
||||
titleBarLayout.setOnLeftClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setResult(RESULT_CODE_ERROR);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
titleBarLayout.setOnRightClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (selected == null) {
|
||||
return;
|
||||
}
|
||||
if (needDownload) {
|
||||
DownloadUrl();
|
||||
} else {
|
||||
Intent resultIntent = new Intent();
|
||||
resultIntent.putExtra(DATA, (Serializable) selected);
|
||||
setResult(RESULT_CODE_SUCCESS, resultIntent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
data = (List<ImageBean>) intent.getSerializableExtra(DATA);
|
||||
selected = (ImageBean) intent.getSerializableExtra(SELECTED);
|
||||
placeHolder = intent.getIntExtra(PLACEHOLDER, 0);
|
||||
itemHeight = intent.getIntExtra(ITEM_HEIGHT, 0);
|
||||
itemWidth = intent.getIntExtra(ITEM_WIDTH, 0);
|
||||
columnNum = intent.getIntExtra(SPAN_COUNT, 2);
|
||||
gridLayoutManager = new GridLayoutManager(this, columnNum);
|
||||
imageGrid = findViewById(R.id.image_select_grid);
|
||||
imageGrid.addItemDecoration(new GridDecoration(columnNum, defaultSpacing, defaultSpacing));
|
||||
imageGrid.setLayoutManager(gridLayoutManager);
|
||||
imageGrid.setItemAnimator(null);
|
||||
gridAdapter = new ImageGridAdapter();
|
||||
gridAdapter.setPlaceHolder(placeHolder);
|
||||
gridAdapter.setSelected(selected);
|
||||
gridAdapter.setOnItemClickListener(new OnItemClickListener() {
|
||||
@Override
|
||||
public void onClick(ImageBean obj) {
|
||||
selected = obj;
|
||||
setSelectedStatus();
|
||||
}
|
||||
});
|
||||
gridAdapter.setItemWidth(itemWidth);
|
||||
gridAdapter.setItemHeight(itemHeight);
|
||||
imageGrid.setAdapter(gridAdapter);
|
||||
gridAdapter.setData(data);
|
||||
setSelectedStatus();
|
||||
gridAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void DownloadUrl() {
|
||||
if (selected == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (selected.isDefault()) {
|
||||
selected.setLocalPath(TUIConstants.TUIChat.CHAT_CONVERSATION_BACKGROUND_DEFAULT_URL);
|
||||
setResult(selected);
|
||||
ToastUtil.toastShortMessage(getResources().getString(R.string.setting_success));
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
String url = selected.getImageUri();
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
Log.d(TAG, "DownloadUrl is null");
|
||||
return;
|
||||
}
|
||||
|
||||
final ProgressDialog dialog = new ProgressDialog(this);
|
||||
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
|
||||
dialog.setCancelable(false);
|
||||
dialog.setCanceledOnTouchOutside(false);
|
||||
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
// TODO Auto-generated method stub
|
||||
finish();
|
||||
}
|
||||
});
|
||||
dialog.setMessage(getResources().getString(R.string.setting));
|
||||
dialog.show();
|
||||
|
||||
ImageBean finalBean = selected;
|
||||
Glide.with(this)
|
||||
.downloadOnly()
|
||||
.load(url)
|
||||
.listener(new RequestListener<File>() {
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<File> target, boolean isFirstResource) {
|
||||
dialog.cancel();
|
||||
Log.e(TAG, "DownloadUrl onLoadFailed e = " + e);
|
||||
ToastUtil.toastShortMessage(getResources().getString(R.string.setting_fail));
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onResourceReady(File resource, Object model, Target<File> target, DataSource dataSource, boolean isFirstResource) {
|
||||
dialog.cancel();
|
||||
String path = resource.getAbsolutePath();
|
||||
Log.e(TAG, "DownloadUrl resource path = " + path);
|
||||
finalBean.setLocalPath(path);
|
||||
setResult(finalBean);
|
||||
ToastUtil.toastShortMessage(getResources().getString(R.string.setting_success));
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.preload();
|
||||
}
|
||||
|
||||
private void setResult(ImageBean bean) {
|
||||
Intent resultIntent = new Intent();
|
||||
resultIntent.putExtra(DATA, (Serializable) bean);
|
||||
setResult(RESULT_CODE_SUCCESS, resultIntent);
|
||||
finish();
|
||||
}
|
||||
|
||||
private void setSelectedStatus() {
|
||||
if (selected != null && data != null && data.contains(selected)) {
|
||||
titleBarLayout.getRightTitle().setEnabled(true);
|
||||
titleBarLayout.getRightTitle().setTextColor(getResources().getColor(TUIThemeManager.getAttrResId(this, R.attr.core_primary_color)));
|
||||
} else {
|
||||
titleBarLayout.getRightTitle().setEnabled(false);
|
||||
titleBarLayout.getRightTitle().setTextColor(0xFF666666);
|
||||
}
|
||||
gridAdapter.setSelected(selected);
|
||||
}
|
||||
|
||||
public static class ImageGridAdapter extends RecyclerView.Adapter<ImageGridAdapter.ImageViewHolder> {
|
||||
private int itemWidth;
|
||||
private int itemHeight;
|
||||
|
||||
private List<ImageBean> data;
|
||||
private ImageBean selected;
|
||||
private int placeHolder;
|
||||
private OnItemClickListener onItemClickListener;
|
||||
|
||||
public void setData(List<ImageBean> data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public void setSelected(ImageBean selected) {
|
||||
if (data == null || data.isEmpty()) {
|
||||
this.selected = selected;
|
||||
} else {
|
||||
this.selected = selected;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void setPlaceHolder(int placeHolder) {
|
||||
this.placeHolder = placeHolder;
|
||||
}
|
||||
|
||||
public void setItemHeight(int itemHeight) {
|
||||
this.itemHeight = itemHeight;
|
||||
}
|
||||
|
||||
public void setItemWidth(int itemWidth) {
|
||||
this.itemWidth = itemWidth;
|
||||
}
|
||||
|
||||
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
|
||||
this.onItemClickListener = onItemClickListener;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ImageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.core_select_image_item_layout, parent, false);
|
||||
return new ImageViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ImageViewHolder holder, int position) {
|
||||
ImageView imageView = holder.imageView;
|
||||
setItemLayoutParams(holder);
|
||||
ImageBean imageBean = data.get(position);
|
||||
if (selected != null && imageBean != null && TextUtils.equals(selected.getThumbnailUri(), imageBean.getThumbnailUri())) {
|
||||
holder.selectBorderLayout.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.selectBorderLayout.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (imageBean.getGroupGridAvatar() != null) {
|
||||
holder.defaultLayout.setVisibility(View.GONE);
|
||||
if (imageView instanceof SynthesizedImageView) {
|
||||
SynthesizedImageView synthesizedImageView = ((SynthesizedImageView) (imageView));
|
||||
String imageId = imageBean.getImageId();
|
||||
synthesizedImageView.setImageId(imageId);
|
||||
synthesizedImageView.displayImage(imageBean.getGroupGridAvatar()).load(imageId);
|
||||
}
|
||||
} else if (imageBean.isDefault()) {
|
||||
holder.defaultLayout.setVisibility(View.VISIBLE);
|
||||
imageView.setImageResource(android.R.color.transparent);
|
||||
} else {
|
||||
holder.defaultLayout.setVisibility(View.GONE);
|
||||
Glide.with(holder.itemView.getContext()).asBitmap()
|
||||
.load(imageBean.getThumbnailUri())
|
||||
.placeholder(placeHolder)
|
||||
.apply(new RequestOptions().error(placeHolder))
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (onItemClickListener != null) {
|
||||
onItemClickListener.onClick(imageBean);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setItemLayoutParams(ImageViewHolder holder) {
|
||||
if (itemHeight > 0 && itemWidth > 0) {
|
||||
ViewGroup.LayoutParams params = holder.imageView.getLayoutParams();
|
||||
params.width = itemWidth;
|
||||
params.height = itemHeight;
|
||||
holder.imageView.setLayoutParams(params);
|
||||
|
||||
ViewGroup.LayoutParams borderLayoutParams = holder.selectBorderLayout.getLayoutParams();
|
||||
borderLayoutParams.width = itemWidth;
|
||||
borderLayoutParams.height = itemHeight;
|
||||
holder.selectBorderLayout.setLayoutParams(borderLayoutParams);
|
||||
|
||||
ViewGroup.LayoutParams borderParams = holder.selectedBorder.getLayoutParams();
|
||||
borderParams.width = itemWidth;
|
||||
borderParams.height = itemHeight;
|
||||
holder.selectedBorder.setLayoutParams(borderParams);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
if (data == null || data.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
return data.size();
|
||||
}
|
||||
|
||||
public static class ImageViewHolder extends RecyclerView.ViewHolder {
|
||||
private final ImageView imageView;
|
||||
private final ImageView selectedBorder;
|
||||
private final RelativeLayout selectBorderLayout;
|
||||
private final Button defaultLayout;
|
||||
|
||||
public ImageViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
imageView = itemView.findViewById(R.id.content_image);
|
||||
selectedBorder = itemView.findViewById(R.id.select_border);
|
||||
selectBorderLayout = itemView.findViewById(R.id.selected_border_area);
|
||||
defaultLayout = itemView.findViewById(R.id.default_image_layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add spacing
|
||||
*/
|
||||
public static class GridDecoration extends RecyclerView.ItemDecoration {
|
||||
|
||||
private final int columnNum; // span count
|
||||
private final int leftRightSpace; // vertical spacing
|
||||
private final int topBottomSpace; // horizontal spacing
|
||||
|
||||
public GridDecoration(int columnNum, int leftRightSpace, int topBottomSpace) {
|
||||
this.columnNum = columnNum;
|
||||
this.leftRightSpace = leftRightSpace;
|
||||
this.topBottomSpace = topBottomSpace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
|
||||
int position = parent.getChildAdapterPosition(view);
|
||||
int column = position % columnNum;
|
||||
|
||||
outRect.left = column * leftRightSpace / columnNum;
|
||||
outRect.right = leftRightSpace * (columnNum - 1 - column) / columnNum;
|
||||
|
||||
// add top spacing
|
||||
if (position >= columnNum) {
|
||||
outRect.top = topBottomSpace;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onClick(ImageBean obj);
|
||||
}
|
||||
|
||||
public static class ImageBean implements Serializable{
|
||||
String thumbnailUri; // for display
|
||||
String imageUri; // for download
|
||||
String localPath; // for local path
|
||||
boolean isDefault = false; // for default display
|
||||
List<Object> groupGridAvatar = null; // for group grid avatar
|
||||
String imageId;
|
||||
|
||||
public ImageBean() {
|
||||
|
||||
}
|
||||
|
||||
public ImageBean(String thumbnailUri, String imageUri, boolean isDefault) {
|
||||
this.thumbnailUri = thumbnailUri;
|
||||
this.imageUri = imageUri;
|
||||
this.isDefault = isDefault;
|
||||
}
|
||||
|
||||
public String getImageUri() {
|
||||
return imageUri;
|
||||
}
|
||||
|
||||
public String getThumbnailUri() {
|
||||
return thumbnailUri;
|
||||
}
|
||||
|
||||
public void setImageUri(String imageUri) {
|
||||
this.imageUri = imageUri;
|
||||
}
|
||||
|
||||
public void setThumbnailUri(String thumbnailUri) {
|
||||
this.thumbnailUri = thumbnailUri;
|
||||
}
|
||||
|
||||
public String getLocalPath() {
|
||||
return localPath;
|
||||
}
|
||||
|
||||
public void setLocalPath(String localPath) {
|
||||
this.localPath = localPath;
|
||||
}
|
||||
|
||||
public boolean isDefault() {
|
||||
return isDefault;
|
||||
}
|
||||
|
||||
public void setDefault(boolean aDefault) {
|
||||
isDefault = aDefault;
|
||||
}
|
||||
|
||||
public List<Object> getGroupGridAvatar() {
|
||||
return groupGridAvatar;
|
||||
}
|
||||
|
||||
public void setGroupGridAvatar(List<Object> groupGridAvatar) {
|
||||
this.groupGridAvatar = groupGridAvatar;
|
||||
}
|
||||
|
||||
public String getImageId() {
|
||||
return imageId;
|
||||
}
|
||||
|
||||
public void setImageId(String imageId) {
|
||||
this.imageId = imageId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
package com.tencent.qcloud.tuicore.component.activities;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.InputFilter;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
import com.tencent.qcloud.tuicore.component.CustomLinearLayoutManager;
|
||||
import com.tencent.qcloud.tuicore.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuicore.component.interfaces.ITitleBarLayout;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class SelectionActivity extends BaseLightActivity {
|
||||
|
||||
private static OnResultReturnListener sOnResultReturnListener;
|
||||
|
||||
private RecyclerView selectListView;
|
||||
private SelectAdapter selectListAdapter;
|
||||
private EditText input;
|
||||
private int mSelectionType;
|
||||
private ArrayList<String> selectList = new ArrayList<>();
|
||||
private int selectedItem = -1;
|
||||
private OnItemClickListener onItemClickListener;
|
||||
private boolean needConfirm = true;
|
||||
private boolean returnNow = true;
|
||||
|
||||
public static void startTextSelection(Context context, Bundle bundle, OnResultReturnListener listener) {
|
||||
bundle.putInt(Selection.TYPE, Selection.TYPE_TEXT);
|
||||
startSelection(context, bundle, listener);
|
||||
}
|
||||
|
||||
public static void startListSelection(Context context, Bundle bundle, OnResultReturnListener listener) {
|
||||
bundle.putInt(Selection.TYPE, Selection.TYPE_LIST);
|
||||
startSelection(context, bundle, listener);
|
||||
}
|
||||
|
||||
private static void startSelection(Context context, Bundle bundle, OnResultReturnListener listener) {
|
||||
Intent intent = new Intent(context, SelectionActivity.class);
|
||||
intent.putExtra(Selection.CONTENT, bundle);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
sOnResultReturnListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.tuicore_selection_activity);
|
||||
final TitleBarLayout titleBar = findViewById(R.id.edit_title_bar);
|
||||
selectListView = findViewById(R.id.select_list);
|
||||
selectListAdapter = new SelectAdapter();
|
||||
selectListView.setAdapter(selectListAdapter);
|
||||
selectListView.setLayoutManager(new CustomLinearLayoutManager(this));
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
|
||||
dividerItemDecoration.setDrawable(getResources().getDrawable(R.drawable.core_list_divider));
|
||||
selectListView.addItemDecoration(dividerItemDecoration);
|
||||
onItemClickListener = new OnItemClickListener() {
|
||||
@Override
|
||||
public void onClick(int position) {
|
||||
selectedItem = position;
|
||||
selectListAdapter.setSelectedItem(position);
|
||||
selectListAdapter.notifyDataSetChanged();
|
||||
if (!needConfirm) {
|
||||
echoClick();
|
||||
}
|
||||
}
|
||||
};
|
||||
input = findViewById(R.id.edit_content_et);
|
||||
|
||||
Bundle bundle = getIntent().getBundleExtra(Selection.CONTENT);
|
||||
switch (bundle.getInt(Selection.TYPE)) {
|
||||
case Selection.TYPE_TEXT:
|
||||
selectListView.setVisibility(View.GONE);
|
||||
String defaultString = bundle.getString(Selection.INIT_CONTENT);
|
||||
int limit = bundle.getInt(Selection.LIMIT);
|
||||
if (!TextUtils.isEmpty(defaultString)) {
|
||||
input.setText(defaultString);
|
||||
input.setSelection(defaultString.length());
|
||||
}
|
||||
if (limit > 0) {
|
||||
input.setFilters(new InputFilter[]{new InputFilter.LengthFilter(limit)});
|
||||
}
|
||||
break;
|
||||
case Selection.TYPE_LIST:
|
||||
input.setVisibility(View.GONE);
|
||||
ArrayList<String> list = bundle.getStringArrayList(Selection.LIST);
|
||||
selectedItem = bundle.getInt(Selection.DEFAULT_SELECT_ITEM_INDEX);
|
||||
if (list == null || list.size() == 0) {
|
||||
return;
|
||||
}
|
||||
selectList.clear();
|
||||
selectList.addAll(list);
|
||||
selectListAdapter.setSelectedItem(selectedItem);
|
||||
selectListAdapter.setData(selectList);
|
||||
selectListAdapter.notifyDataSetChanged();
|
||||
|
||||
break;
|
||||
default:
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
mSelectionType = bundle.getInt(Selection.TYPE);
|
||||
|
||||
final String title = bundle.getString(Selection.TITLE);
|
||||
|
||||
needConfirm = bundle.getBoolean(Selection.NEED_CONFIRM, true);
|
||||
returnNow = bundle.getBoolean(Selection.RETURN_NOW, true);
|
||||
|
||||
titleBar.setTitle(title, ITitleBarLayout.Position.MIDDLE);
|
||||
titleBar.setOnLeftClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
titleBar.getRightIcon().setVisibility(View.GONE);
|
||||
if (needConfirm) {
|
||||
titleBar.getRightTitle().setText(getResources().getString(R.string.sure));
|
||||
titleBar.setOnRightClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
echoClick();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
titleBar.getRightGroup().setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void echoClick() {
|
||||
switch (mSelectionType) {
|
||||
case Selection.TYPE_TEXT:
|
||||
if (sOnResultReturnListener != null) {
|
||||
sOnResultReturnListener.onReturn(input.getText().toString());
|
||||
}
|
||||
break;
|
||||
case Selection.TYPE_LIST:
|
||||
if (sOnResultReturnListener != null) {
|
||||
sOnResultReturnListener.onReturn(selectedItem);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (returnNow) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
sOnResultReturnListener = null;
|
||||
}
|
||||
|
||||
class SelectAdapter extends RecyclerView.Adapter<SelectAdapter.SelectViewHolder> {
|
||||
int selectedItem = -1;
|
||||
ArrayList<String> data = new ArrayList<>();
|
||||
|
||||
public void setData(ArrayList<String> data) {
|
||||
this.data.clear();
|
||||
this.data.addAll(data);
|
||||
}
|
||||
|
||||
public void setSelectedItem(int selectedItem) {
|
||||
this.selectedItem = selectedItem;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public SelectViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(SelectionActivity.this).inflate(R.layout.core_select_item_layout,parent, false);
|
||||
return new SelectViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull SelectViewHolder holder, int position) {
|
||||
String nameStr = data.get(position);
|
||||
holder.name.setText(nameStr);
|
||||
if (selectedItem == position) {
|
||||
holder.selectedIcon.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.selectedIcon.setVisibility(View.GONE);
|
||||
}
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onItemClickListener.onClick(position);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return data.size();
|
||||
}
|
||||
|
||||
class SelectViewHolder extends RecyclerView.ViewHolder{
|
||||
TextView name;
|
||||
ImageView selectedIcon;
|
||||
public SelectViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
name = itemView.findViewById(R.id.name);
|
||||
selectedIcon = itemView.findViewById(R.id.selected_icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnResultReturnListener {
|
||||
void onReturn(Object res);
|
||||
}
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onClick(int position);
|
||||
}
|
||||
|
||||
public static class Selection {
|
||||
public static final String SELECT_ALL = "select_all";
|
||||
public static final String CONTENT = "content";
|
||||
public static final String TYPE = "type";
|
||||
public static final String TITLE = "title";
|
||||
public static final String INIT_CONTENT = "init_content";
|
||||
public static final String DEFAULT_SELECT_ITEM_INDEX = "default_select_item_index";
|
||||
public static final String LIST = "list";
|
||||
public static final String LIMIT = "limit";
|
||||
public static final String NEED_CONFIRM = "needConfirm";
|
||||
public static final String RETURN_NOW = "returnNow";
|
||||
public static final int TYPE_TEXT = 1;
|
||||
public static final int TYPE_LIST = 2;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
package com.tencent.qcloud.tuicore.component.dialog;
|
||||
|
||||
import static com.tencent.qcloud.tuicore.TUIConfig.TUICORE_SETTINGS_SP_NAME;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.text.method.MovementMethod;
|
||||
import android.view.Display;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.LinearLayout.LayoutParams;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.tencent.qcloud.tuicore.BuildConfig;
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
import com.tencent.qcloud.tuicore.TUIConfig;
|
||||
import com.tencent.qcloud.tuicore.util.SPUtils;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class TUIKitDialog {
|
||||
|
||||
private Context mContext;
|
||||
protected Dialog dialog;
|
||||
private LinearLayout mBackgroundLayout;
|
||||
private LinearLayout mMainLayout;
|
||||
protected TextView mTitleTv;
|
||||
private Button mCancelButton;
|
||||
private Button mSureButton;
|
||||
private ImageView mLineImg;
|
||||
private Display mDisplay;
|
||||
|
||||
private boolean showTitle = false;
|
||||
private boolean showPosBtn = false;
|
||||
private boolean showNegBtn = false;
|
||||
|
||||
private float dialogWidth = 0.7f;
|
||||
|
||||
|
||||
public TUIKitDialog(Context context) {
|
||||
this.mContext = context;
|
||||
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
mDisplay = windowManager.getDefaultDisplay();
|
||||
}
|
||||
|
||||
public TUIKitDialog builder() {
|
||||
View view = LayoutInflater.from(mContext).inflate(R.layout.view_dialog, null);
|
||||
mBackgroundLayout = (LinearLayout) view.findViewById(R.id.ll_background);
|
||||
mMainLayout = (LinearLayout) view.findViewById(R.id.ll_alert);
|
||||
mMainLayout.setVerticalGravity(View.GONE);
|
||||
mTitleTv = (TextView) view.findViewById(R.id.tv_title);
|
||||
mTitleTv.setVisibility(View.GONE);
|
||||
mCancelButton = (Button) view.findViewById(R.id.btn_neg);
|
||||
mCancelButton.setVisibility(View.GONE);
|
||||
mSureButton = (Button) view.findViewById(R.id.btn_pos);
|
||||
mSureButton.setVisibility(View.GONE);
|
||||
mLineImg = (ImageView) view.findViewById(R.id.img_line);
|
||||
mLineImg.setVisibility(View.GONE);
|
||||
|
||||
dialog = new Dialog(mContext, R.style.TUIKit_AlertDialogStyle);
|
||||
dialog.setContentView(view);
|
||||
|
||||
mBackgroundLayout.setLayoutParams(new FrameLayout.LayoutParams((int) (mDisplay.getWidth() * dialogWidth), LayoutParams.WRAP_CONTENT));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public TUIKitDialog setTitle(@NonNull CharSequence title) {
|
||||
showTitle = true;
|
||||
mTitleTv.setText(title);
|
||||
return this;
|
||||
}
|
||||
|
||||
/***
|
||||
* Whether to click back to cancel
|
||||
* @param cancel
|
||||
* @return
|
||||
*/
|
||||
public TUIKitDialog setCancelable(boolean cancel) {
|
||||
dialog.setCancelable(cancel);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the setting can be canceled
|
||||
*
|
||||
* @param isCancelOutside
|
||||
* @return
|
||||
*/
|
||||
public TUIKitDialog setCancelOutside(boolean isCancelOutside) {
|
||||
dialog.setCanceledOnTouchOutside(isCancelOutside);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TUIKitDialog setPositiveButton(CharSequence text,
|
||||
final OnClickListener listener) {
|
||||
showPosBtn = true;
|
||||
mSureButton.setText(text);
|
||||
mSureButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
listener.onClick(v);
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setTitleGravity(int gravity) {
|
||||
mTitleTv.setGravity(gravity);
|
||||
}
|
||||
|
||||
public TUIKitDialog setPositiveButton(final OnClickListener listener) {
|
||||
setPositiveButton(TUIConfig.getAppContext().getString(R.string.sure), listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TUIKitDialog setNegativeButton(CharSequence text,
|
||||
final OnClickListener listener) {
|
||||
showNegBtn = true;
|
||||
mCancelButton.setText(text);
|
||||
mCancelButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
listener.onClick(v);
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
public TUIKitDialog setNegativeButton(final OnClickListener listener) {
|
||||
setNegativeButton(TUIConfig.getAppContext().getString(R.string.cancel), listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
private void setLayout() {
|
||||
if (!showTitle) {
|
||||
mTitleTv.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (showTitle) {
|
||||
mTitleTv.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (!showPosBtn && !showNegBtn) {
|
||||
mSureButton.setVisibility(View.GONE);
|
||||
mSureButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (showPosBtn && showNegBtn) {
|
||||
mSureButton.setVisibility(View.VISIBLE);
|
||||
mCancelButton.setVisibility(View.VISIBLE);
|
||||
mLineImg.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (showPosBtn && !showNegBtn) {
|
||||
mSureButton.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (!showPosBtn && showNegBtn) {
|
||||
mCancelButton.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
public void show() {
|
||||
setLayout();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public void dismiss() {
|
||||
if (dialog != null && dialog.isShowing()) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isShowing() {
|
||||
return dialog != null && dialog.isShowing();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置dialog 宽度
|
||||
*
|
||||
* @param dialogWidth
|
||||
* @return
|
||||
*/
|
||||
public TUIKitDialog setDialogWidth(float dialogWidth) {
|
||||
if (mBackgroundLayout != null) {
|
||||
mBackgroundLayout.setLayoutParams(new FrameLayout.LayoutParams((int) (mDisplay.getWidth() * dialogWidth), LayoutParams.WRAP_CONTENT));
|
||||
}
|
||||
this.dialogWidth = dialogWidth;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static class TUIIMUpdateDialog {
|
||||
|
||||
private static final class TUIIMUpdateDialogHolder {
|
||||
private static final TUIIMUpdateDialog instance = new TUIIMUpdateDialog();
|
||||
}
|
||||
|
||||
public static final String KEY_NEVER_SHOW = "neverShow";
|
||||
|
||||
private boolean isNeverShow;
|
||||
private boolean isShowOnlyDebug = false;
|
||||
private String dialogFeatureName;
|
||||
|
||||
private WeakReference<TUIKitDialog> tuiKitDialog;
|
||||
|
||||
public static TUIIMUpdateDialog getInstance() {
|
||||
return TUIIMUpdateDialogHolder.instance;
|
||||
}
|
||||
|
||||
private TUIIMUpdateDialog() {
|
||||
isNeverShow = SPUtils.getInstance(TUICORE_SETTINGS_SP_NAME).getBoolean(getDialogFeatureName(), false);
|
||||
}
|
||||
|
||||
public TUIIMUpdateDialog createDialog(Context context) {
|
||||
tuiKitDialog = new WeakReference<>(new TUIKitDialog(context));
|
||||
tuiKitDialog.get().builder();
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setNeverShow(boolean neverShowAlert) {
|
||||
this.isNeverShow = neverShowAlert;
|
||||
SPUtils.getInstance(TUICORE_SETTINGS_SP_NAME).put(getDialogFeatureName(), neverShowAlert);
|
||||
}
|
||||
|
||||
public TUIIMUpdateDialog setShowOnlyDebug(boolean isShowOnlyDebug) {
|
||||
this.isShowOnlyDebug = isShowOnlyDebug;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TUIIMUpdateDialog setMovementMethod(MovementMethod movementMethod) {
|
||||
if (tuiKitDialog != null && tuiKitDialog.get() != null) {
|
||||
tuiKitDialog.get().mTitleTv.setMovementMethod(movementMethod);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TUIIMUpdateDialog setHighlightColor(int color) {
|
||||
if (tuiKitDialog != null && tuiKitDialog.get() != null) {
|
||||
tuiKitDialog.get().mTitleTv.setHighlightColor(color);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TUIIMUpdateDialog setCancelable(boolean cancelable) {
|
||||
if (tuiKitDialog != null && tuiKitDialog.get() != null) {
|
||||
tuiKitDialog.get().setCancelable(cancelable);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TUIIMUpdateDialog setCancelOutside(boolean cancelOutside) {
|
||||
if (tuiKitDialog != null && tuiKitDialog.get() != null) {
|
||||
tuiKitDialog.get().setCancelOutside(cancelOutside);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TUIIMUpdateDialog setTitle(CharSequence charSequence) {
|
||||
if (tuiKitDialog != null && tuiKitDialog.get() != null) {
|
||||
tuiKitDialog.get().setTitle(charSequence);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TUIIMUpdateDialog setDialogWidth(float dialogWidth) {
|
||||
if (tuiKitDialog != null && tuiKitDialog.get() != null) {
|
||||
tuiKitDialog.get().setDialogWidth(dialogWidth);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TUIIMUpdateDialog setPositiveButton(CharSequence text, OnClickListener clickListener) {
|
||||
if (tuiKitDialog != null && tuiKitDialog.get() != null) {
|
||||
tuiKitDialog.get().setPositiveButton(text, clickListener);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TUIIMUpdateDialog setNegativeButton(CharSequence text, OnClickListener clickListener) {
|
||||
if (tuiKitDialog != null && tuiKitDialog.get() != null) {
|
||||
tuiKitDialog.get().setNegativeButton(text, clickListener);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TUIIMUpdateDialog setDialogFeatureName(String featureName) {
|
||||
this.dialogFeatureName = featureName;
|
||||
return this;
|
||||
}
|
||||
|
||||
private String getDialogFeatureName() {
|
||||
return dialogFeatureName;
|
||||
}
|
||||
|
||||
public void show() {
|
||||
if (tuiKitDialog == null || tuiKitDialog.get() == null) {
|
||||
return;
|
||||
}
|
||||
isNeverShow = SPUtils.getInstance(TUICORE_SETTINGS_SP_NAME).getBoolean(getDialogFeatureName(), false);
|
||||
Dialog dialog = tuiKitDialog.get().dialog;
|
||||
if (dialog == null || dialog.isShowing()) {
|
||||
return;
|
||||
}
|
||||
if (isNeverShow) {
|
||||
return;
|
||||
}
|
||||
if (isShowOnlyDebug && !BuildConfig.DEBUG) {
|
||||
return;
|
||||
}
|
||||
tuiKitDialog.get().show();
|
||||
}
|
||||
|
||||
public void dismiss() {
|
||||
if (tuiKitDialog == null || tuiKitDialog.get() == null) {
|
||||
return;
|
||||
}
|
||||
tuiKitDialog.get().dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.tencent.qcloud.tuicore.component.fragments;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
public class BaseFragment extends Fragment {
|
||||
|
||||
public void forward(Fragment fragment, boolean hide) {
|
||||
forward(getId(), fragment, null, hide);
|
||||
}
|
||||
|
||||
public void forward(int viewId, Fragment fragment, String name, boolean hide) {
|
||||
if (getFragmentManager() == null){
|
||||
return;
|
||||
}
|
||||
FragmentTransaction trans = getFragmentManager().beginTransaction();
|
||||
if (hide) {
|
||||
trans.hide(this);
|
||||
trans.add(viewId, fragment);
|
||||
} else {
|
||||
trans.replace(viewId, fragment);
|
||||
}
|
||||
|
||||
trans.addToBackStack(name);
|
||||
trans.commitAllowingStateLoss();
|
||||
}
|
||||
|
||||
public void backward() {
|
||||
if (getFragmentManager() == null){
|
||||
return;
|
||||
}
|
||||
getFragmentManager().popBackStack();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package com.tencent.qcloud.tuicore.component.gatherimage;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Multiple image data
|
||||
*/
|
||||
|
||||
public class MultiImageData implements Cloneable{
|
||||
final static int maxSize = 9;
|
||||
List<Object> imageUrls;
|
||||
int defaultImageResId;
|
||||
Map<Integer, Bitmap> bitmapMap;
|
||||
int bgColor = Color.parseColor("#cfd3d8");
|
||||
|
||||
|
||||
int targetImageSize;
|
||||
int maxWidth, maxHeight;
|
||||
int rowCount;
|
||||
int columnCount;
|
||||
int gap = 6;
|
||||
|
||||
public MultiImageData() {
|
||||
}
|
||||
|
||||
public MultiImageData(int defaultImageResId) {
|
||||
this.defaultImageResId = defaultImageResId;
|
||||
}
|
||||
|
||||
public MultiImageData(List<Object> imageUrls, int defaultImageResId) {
|
||||
this.imageUrls = imageUrls;
|
||||
this.defaultImageResId = defaultImageResId;
|
||||
}
|
||||
|
||||
public int getDefaultImageResId() {
|
||||
return defaultImageResId;
|
||||
}
|
||||
|
||||
public void setDefaultImageResId(int defaultImageResId) {
|
||||
this.defaultImageResId = defaultImageResId;
|
||||
}
|
||||
|
||||
public List<Object> getImageUrls() {
|
||||
return imageUrls;
|
||||
}
|
||||
|
||||
public void setImageUrls(List<Object> imageUrls) {
|
||||
this.imageUrls = imageUrls;
|
||||
}
|
||||
|
||||
public void putBitmap(Bitmap bitmap, int position) {
|
||||
if (null != bitmapMap) {
|
||||
synchronized (bitmapMap) {
|
||||
bitmapMap.put(position, bitmap);
|
||||
}
|
||||
} else {
|
||||
bitmapMap = new HashMap<>();
|
||||
synchronized (bitmapMap) {
|
||||
bitmapMap.put(position, bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Bitmap getBitmap(int position) {
|
||||
if (null != bitmapMap) {
|
||||
synchronized (bitmapMap) {
|
||||
return bitmapMap.get(position);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
if (null != imageUrls) {
|
||||
return imageUrls.size() > maxSize ? maxSize : imageUrls.size();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MultiImageData clone() throws CloneNotSupportedException {
|
||||
MultiImageData multiImageData = (MultiImageData) super.clone();
|
||||
if (imageUrls != null) {
|
||||
multiImageData.imageUrls = new ArrayList<>(imageUrls.size());
|
||||
multiImageData.imageUrls.addAll(imageUrls);
|
||||
}
|
||||
if (bitmapMap != null) {
|
||||
multiImageData.bitmapMap = new HashMap<>();
|
||||
multiImageData.bitmapMap.putAll(bitmapMap);
|
||||
}
|
||||
return multiImageData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.tencent.qcloud.tuicore.component.gatherimage;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.SparseArray;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
import com.tencent.qcloud.tuicore.util.ScreenUtil;
|
||||
|
||||
@SuppressLint("AppCompatCustomView")
|
||||
public class ShadeImageView extends ImageView {
|
||||
|
||||
private static SparseArray<Bitmap> sRoundBitmapArray = new SparseArray();
|
||||
private Paint mShadePaint = new Paint();
|
||||
private Bitmap mRoundBitmap;
|
||||
private int radius;
|
||||
|
||||
public ShadeImageView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ShadeImageView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context, attrs);
|
||||
}
|
||||
|
||||
public ShadeImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(context, attrs);
|
||||
}
|
||||
|
||||
private void init(Context context, AttributeSet attrs) {
|
||||
radius = (int) ScreenUtil.dp2px(4.0f, getResources().getDisplayMetrics());
|
||||
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.core_round_rect_image_style);
|
||||
radius = array.getDimensionPixelSize(R.styleable.core_round_rect_image_style_round_radius, radius);
|
||||
array.recycle();
|
||||
setLayerType(LAYER_TYPE_HARDWARE, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
mShadePaint.setColor(Color.RED);
|
||||
mShadePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
|
||||
mRoundBitmap = sRoundBitmapArray.get(getMeasuredWidth() + radius);
|
||||
if (mRoundBitmap == null) {
|
||||
mRoundBitmap = getRoundBitmap();
|
||||
sRoundBitmapArray.put(getMeasuredWidth() + radius, mRoundBitmap);
|
||||
}
|
||||
canvas.drawBitmap(mRoundBitmap, 0, 0, mShadePaint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rounded rectangle
|
||||
*
|
||||
* @return Bitmap
|
||||
*/
|
||||
private Bitmap getRoundBitmap() {
|
||||
Bitmap output = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(output);
|
||||
final int color = Color.parseColor("#cfd3d8");
|
||||
final Rect rect = new Rect(0, 0, getMeasuredWidth(), getMeasuredHeight());
|
||||
final RectF rectF = new RectF(rect);
|
||||
Paint paint = new Paint();
|
||||
paint.setAntiAlias(true);
|
||||
canvas.drawARGB(0, 0, 0, 0);
|
||||
paint.setColor(color);
|
||||
canvas.drawRoundRect(rectF, radius, radius, paint);
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
public int getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
public void setRadius(int radius) {
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.tencent.qcloud.tuicore.component.gatherimage;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class SynthesizedImageView extends ShadeImageView {
|
||||
/**
|
||||
* 群聊头像合成器
|
||||
*
|
||||
* Group Chat Avatar Synthesizer
|
||||
*/
|
||||
TeamHeadSynthesizer teamHeadSynthesizer;
|
||||
int imageSize = 100;
|
||||
int synthesizedBg = Color.parseColor("#cfd3d8");
|
||||
int defaultImageResId = 0;
|
||||
int imageGap = 6;
|
||||
|
||||
public SynthesizedImageView(Context context) {
|
||||
super(context);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public SynthesizedImageView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initAttrs(attrs);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public SynthesizedImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
initAttrs(attrs);
|
||||
init(context);
|
||||
}
|
||||
|
||||
private void initAttrs(AttributeSet attributeSet) {
|
||||
TypedArray ta = getContext().obtainStyledAttributes(attributeSet, R.styleable.SynthesizedImageView);
|
||||
if (null != ta) {
|
||||
synthesizedBg = ta.getColor(R.styleable.SynthesizedImageView_synthesized_image_bg, synthesizedBg);
|
||||
defaultImageResId = ta.getResourceId(R.styleable.SynthesizedImageView_synthesized_default_image, defaultImageResId);
|
||||
imageSize = ta.getDimensionPixelSize(R.styleable.SynthesizedImageView_synthesized_image_size, imageSize);
|
||||
imageGap = ta.getDimensionPixelSize(R.styleable.SynthesizedImageView_synthesized_image_gap, imageGap);
|
||||
ta.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
private void init(Context context) {
|
||||
teamHeadSynthesizer = new TeamHeadSynthesizer(context, this);
|
||||
teamHeadSynthesizer.setMaxWidthHeight(imageSize, imageSize);
|
||||
teamHeadSynthesizer.setDefaultImage(defaultImageResId);
|
||||
teamHeadSynthesizer.setBgColor(synthesizedBg);
|
||||
teamHeadSynthesizer.setGap(imageGap);
|
||||
}
|
||||
|
||||
public SynthesizedImageView displayImage(List<Object> imageUrls) {
|
||||
teamHeadSynthesizer.getMultiImageData().setImageUrls(imageUrls);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SynthesizedImageView defaultImage(int defaultImage) {
|
||||
teamHeadSynthesizer.setDefaultImage(defaultImage);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SynthesizedImageView synthesizedWidthHeight(int maxWidth, int maxHeight) {
|
||||
teamHeadSynthesizer.setMaxWidthHeight(maxWidth, maxHeight);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setImageId(String id) {
|
||||
teamHeadSynthesizer.setImageId(id);
|
||||
}
|
||||
|
||||
public void load(String imageId) {
|
||||
teamHeadSynthesizer.load(imageId);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
teamHeadSynthesizer.clearImage();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.tencent.qcloud.tuicore.component.gatherimage;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
|
||||
|
||||
public interface Synthesizer {
|
||||
|
||||
Bitmap synthesizeImageList(MultiImageData imageData);
|
||||
|
||||
boolean asyncLoadImageList(MultiImageData imageData);
|
||||
|
||||
void drawDrawable(Canvas canvas, MultiImageData imageData);
|
||||
}
|
||||
@@ -0,0 +1,332 @@
|
||||
package com.tencent.qcloud.tuicore.component.gatherimage;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
import com.tencent.qcloud.tuicore.TUIConfig;
|
||||
import com.tencent.qcloud.tuicore.TUIThemeManager;
|
||||
import com.tencent.qcloud.tuicore.component.imageEngine.impl.GlideEngine;
|
||||
import com.tencent.qcloud.tuicore.util.BackgroundTasks;
|
||||
import com.tencent.qcloud.tuicore.util.ImageUtil;
|
||||
import com.tencent.qcloud.tuicore.util.ThreadHelper;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
|
||||
public class TeamHeadSynthesizer implements Synthesizer {
|
||||
|
||||
MultiImageData multiImageData;
|
||||
Context mContext;
|
||||
|
||||
ImageView imageView;
|
||||
|
||||
// It is safe to set and get only in the main thread
|
||||
private String currentImageId = "";
|
||||
Callback callback = new Callback() {
|
||||
@Override
|
||||
public void onCall(Bitmap bitmap, String targetID) {
|
||||
if (!TextUtils.equals(getImageId(), targetID)) {
|
||||
return;
|
||||
}
|
||||
GlideEngine.loadUserIcon(imageView, bitmap);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public TeamHeadSynthesizer(Context mContext, ImageView imageView) {
|
||||
this.mContext = mContext;
|
||||
this.imageView = imageView;
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
multiImageData = new MultiImageData();
|
||||
}
|
||||
|
||||
public void setMaxWidthHeight(int maxWidth, int maxHeight) {
|
||||
multiImageData.maxWidth = maxWidth;
|
||||
multiImageData.maxHeight = maxHeight;
|
||||
}
|
||||
|
||||
public MultiImageData getMultiImageData() {
|
||||
return multiImageData;
|
||||
}
|
||||
|
||||
public int getDefaultImage() {
|
||||
return multiImageData.getDefaultImageResId();
|
||||
}
|
||||
|
||||
public void setDefaultImage(int defaultImageResId) {
|
||||
multiImageData.setDefaultImageResId(defaultImageResId);
|
||||
}
|
||||
|
||||
public void setBgColor(int bgColor) {
|
||||
multiImageData.bgColor = bgColor;
|
||||
}
|
||||
|
||||
public void setGap(int gap) {
|
||||
multiImageData.gap = gap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Grid params
|
||||
*
|
||||
* @param imagesSize Number of pictures
|
||||
* @return gridParam[0] Rows gridParam[1] columns
|
||||
*/
|
||||
protected int[] calculateGridParam(int imagesSize) {
|
||||
int[] gridParam = new int[2];
|
||||
if (imagesSize < 3) {
|
||||
gridParam[0] = 1;
|
||||
gridParam[1] = imagesSize;
|
||||
} else if (imagesSize <= 4) {
|
||||
gridParam[0] = 2;
|
||||
gridParam[1] = 2;
|
||||
} else {
|
||||
gridParam[0] = imagesSize / 3 + (imagesSize % 3 == 0 ? 0 : 1);
|
||||
gridParam[1] = 3;
|
||||
}
|
||||
return gridParam;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bitmap synthesizeImageList(MultiImageData imageData) {
|
||||
Bitmap mergeBitmap = Bitmap.createBitmap(imageData.maxWidth, imageData.maxHeight, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(mergeBitmap);
|
||||
drawDrawable(canvas, imageData);
|
||||
canvas.save();
|
||||
canvas.restore();
|
||||
return mergeBitmap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncLoadImageList(MultiImageData imageData) {
|
||||
boolean loadSuccess = true;
|
||||
List<Object> imageUrls = imageData.getImageUrls();
|
||||
for (int i = 0; i < imageUrls.size(); i++) {
|
||||
Bitmap defaultIcon = BitmapFactory.decodeResource(mContext.getResources(), TUIConfig.getDefaultAvatarImage());
|
||||
try {
|
||||
Bitmap bitmap = asyncLoadImage(imageUrls.get(i), imageData.targetImageSize);
|
||||
imageData.putBitmap(bitmap, i);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
imageData.putBitmap(defaultIcon, i);
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
imageData.putBitmap(defaultIcon, i);
|
||||
}
|
||||
}
|
||||
return loadSuccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawDrawable(Canvas canvas, MultiImageData imageData) {
|
||||
canvas.drawColor(imageData.bgColor);
|
||||
int size = imageData.size();
|
||||
int t_center = (imageData.maxHeight + imageData.gap) / 2;
|
||||
int b_center = (imageData.maxHeight - imageData.gap) / 2;
|
||||
int l_center = (imageData.maxWidth + imageData.gap) / 2;
|
||||
int r_center = (imageData.maxWidth - imageData.gap) / 2;
|
||||
int center = (imageData.maxHeight - imageData.targetImageSize) / 2;
|
||||
for (int i = 0; i < size; i++) {
|
||||
int rowNum = i / imageData.columnCount;
|
||||
int columnNum = i % imageData.columnCount;
|
||||
|
||||
int left = ((int) (imageData.targetImageSize * (imageData.columnCount == 1 ? columnNum + 0.5 : columnNum) + imageData.gap * (columnNum + 1)));
|
||||
int top = ((int) (imageData.targetImageSize * (imageData.columnCount == 1 ? rowNum + 0.5 : rowNum) + imageData.gap * (rowNum + 1)));
|
||||
int right = left + imageData.targetImageSize;
|
||||
int bottom = top + imageData.targetImageSize;
|
||||
|
||||
Bitmap bitmap = imageData.getBitmap(i);
|
||||
if (size == 1) {
|
||||
drawBitmapAtPosition(canvas, left, top, right, bottom, bitmap);
|
||||
} else if (size == 2) {
|
||||
drawBitmapAtPosition(canvas, left, center, right, center + imageData.targetImageSize, bitmap);
|
||||
} else if (size == 3) {
|
||||
if (i == 0) {
|
||||
drawBitmapAtPosition(canvas, center, top, center + imageData.targetImageSize, bottom, bitmap);
|
||||
} else {
|
||||
drawBitmapAtPosition(canvas, imageData.gap * i + imageData.targetImageSize * (i - 1), t_center, imageData.gap * i + imageData.targetImageSize * i, t_center + imageData.targetImageSize, bitmap);
|
||||
}
|
||||
} else if (size == 4) {
|
||||
drawBitmapAtPosition(canvas, left, top, right, bottom, bitmap);
|
||||
} else if (size == 5) {
|
||||
if (i == 0) {
|
||||
drawBitmapAtPosition(canvas, r_center - imageData.targetImageSize, r_center - imageData.targetImageSize, r_center, r_center, bitmap);
|
||||
} else if (i == 1) {
|
||||
drawBitmapAtPosition(canvas, l_center, r_center - imageData.targetImageSize, l_center + imageData.targetImageSize, r_center, bitmap);
|
||||
} else {
|
||||
drawBitmapAtPosition(canvas, imageData.gap * (i - 1) + imageData.targetImageSize * (i - 2), t_center, imageData.gap * (i - 1) + imageData.targetImageSize * (i - 1), t_center +
|
||||
imageData.targetImageSize, bitmap);
|
||||
}
|
||||
} else if (size == 6) {
|
||||
if (i < 3) {
|
||||
drawBitmapAtPosition(canvas, imageData.gap * (i + 1) + imageData.targetImageSize * i, b_center - imageData.targetImageSize, imageData.gap * (i + 1) + imageData.targetImageSize * (i + 1), b_center, bitmap);
|
||||
} else {
|
||||
drawBitmapAtPosition(canvas, imageData.gap * (i - 2) + imageData.targetImageSize * (i - 3), t_center, imageData.gap * (i - 2) + imageData.targetImageSize * (i - 2), t_center +
|
||||
imageData.targetImageSize, bitmap);
|
||||
}
|
||||
} else if (size == 7) {
|
||||
if (i == 0) {
|
||||
drawBitmapAtPosition(canvas, center, imageData.gap, center + imageData.targetImageSize, imageData.gap + imageData.targetImageSize, bitmap);
|
||||
} else if (i > 0 && i < 4) {
|
||||
drawBitmapAtPosition(canvas, imageData.gap * i + imageData.targetImageSize * (i - 1), center, imageData.gap * i + imageData.targetImageSize * i, center + imageData.targetImageSize, bitmap);
|
||||
} else {
|
||||
drawBitmapAtPosition(canvas, imageData.gap * (i - 3) + imageData.targetImageSize * (i - 4), t_center + imageData.targetImageSize / 2, imageData.gap * (i - 3) + imageData.targetImageSize * (i - 3), t_center + imageData.targetImageSize / 2 + imageData.targetImageSize, bitmap);
|
||||
}
|
||||
} else if (size == 8) {
|
||||
if (i == 0) {
|
||||
drawBitmapAtPosition(canvas, r_center - imageData.targetImageSize, imageData.gap, r_center, imageData.gap + imageData.targetImageSize, bitmap);
|
||||
} else if (i == 1) {
|
||||
drawBitmapAtPosition(canvas, l_center, imageData.gap, l_center + imageData.targetImageSize, imageData.gap + imageData.targetImageSize, bitmap);
|
||||
} else if (i > 1 && i < 5) {
|
||||
drawBitmapAtPosition(canvas, imageData.gap * (i - 1) + imageData.targetImageSize * (i - 2), center, imageData.gap * (i - 1) + imageData.targetImageSize * (i - 1), center + imageData.targetImageSize, bitmap);
|
||||
} else {
|
||||
drawBitmapAtPosition(canvas, imageData.gap * (i - 4) + imageData.targetImageSize * (i - 5), t_center + imageData.targetImageSize / 2, imageData.gap * (i - 4) + imageData.targetImageSize * (i - 4), t_center + imageData.targetImageSize / 2 + imageData.targetImageSize, bitmap);
|
||||
}
|
||||
} else if (size == 9) {
|
||||
drawBitmapAtPosition(canvas, left, top, right, bottom, bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DrawBitmap
|
||||
*
|
||||
* @param canvas
|
||||
* @param left
|
||||
* @param top
|
||||
* @param right
|
||||
* @param bottom
|
||||
* @param bitmap
|
||||
*/
|
||||
public void drawBitmapAtPosition(Canvas canvas, int left, int top, int right, int bottom, Bitmap bitmap) {
|
||||
if (null == bitmap) {
|
||||
if (multiImageData.getDefaultImageResId() > 0) {
|
||||
bitmap = BitmapFactory.decodeResource(mContext.getResources(), multiImageData.getDefaultImageResId());
|
||||
}
|
||||
}
|
||||
if (null != bitmap) {
|
||||
Rect rect = new Rect(left, top, right, bottom);
|
||||
canvas.drawBitmap(bitmap, null, rect, null);
|
||||
}
|
||||
}
|
||||
|
||||
private Bitmap asyncLoadImage(Object imageUrl, int targetImageSize) throws ExecutionException, InterruptedException {
|
||||
return GlideEngine.loadBitmap(imageUrl, targetImageSize);
|
||||
}
|
||||
|
||||
public void setImageId(String id) {
|
||||
currentImageId = id;
|
||||
}
|
||||
|
||||
public String getImageId() {
|
||||
return currentImageId;
|
||||
}
|
||||
|
||||
public void load(String imageId) {
|
||||
if (multiImageData.size() == 0) {
|
||||
// 发起请求时的图片 id 和当前图片 id 不一致,说明发生了复用,此时不应该再设置图像
|
||||
// The image id when the request is initiated is inconsistent with the current image id,
|
||||
// indicating that multiplexing has occurred, and the image should not be set at this time.
|
||||
if (imageId != null && !TextUtils.equals(imageId, currentImageId)) {
|
||||
return;
|
||||
}
|
||||
GlideEngine.loadUserIcon(imageView, getDefaultImage());
|
||||
return;
|
||||
}
|
||||
|
||||
if (multiImageData.size() == 1) {
|
||||
// 发起请求时的图片 id 和当前图片 id 不一致,说明发生了复用,此时不应该再设置图像
|
||||
// The image id when the request is initiated is inconsistent with the current image id,
|
||||
// indicating that multiplexing has occurred, and the image should not be set at this time.
|
||||
if (imageId != null && !TextUtils.equals(imageId, currentImageId)) {
|
||||
return;
|
||||
}
|
||||
GlideEngine.loadUserIcon(imageView, multiImageData.getImageUrls().get(0));
|
||||
return;
|
||||
}
|
||||
|
||||
// 异步加载图像前先清空内容,避免闪烁
|
||||
// Clear the content before loading images asynchronously to avoid flickering
|
||||
clearImage();
|
||||
|
||||
// 初始化图片信息,由于是异步加载和合成头像,这里需要传给合成线程一个局部对象,只在异步加载线程中使用
|
||||
// 这样在图片被复用时外部线程再次设置 url 就不会覆盖此局部对象
|
||||
// Initialize the image information. Since it is asynchronous loading and synthesizing the avatar,
|
||||
// a local object needs to be passed to the synthesis thread, which is only used in the asynchronous
|
||||
// loading thread, so that when the image is reused, the external thread will not overwrite the local
|
||||
// object by setting the url again.
|
||||
MultiImageData copyMultiImageData;
|
||||
try {
|
||||
copyMultiImageData = multiImageData.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
e.printStackTrace();
|
||||
List urlList = new ArrayList();
|
||||
if (multiImageData.imageUrls != null) {
|
||||
urlList.addAll(multiImageData.imageUrls);
|
||||
}
|
||||
copyMultiImageData = new MultiImageData(urlList, multiImageData.defaultImageResId);
|
||||
}
|
||||
int[] gridParam = calculateGridParam(multiImageData.size());
|
||||
copyMultiImageData.rowCount = gridParam[0];
|
||||
copyMultiImageData.columnCount = gridParam[1];
|
||||
copyMultiImageData.targetImageSize = (copyMultiImageData.maxWidth - (copyMultiImageData.columnCount + 1)
|
||||
* copyMultiImageData.gap) / (copyMultiImageData.columnCount == 1 ? 2 : copyMultiImageData.columnCount);
|
||||
final String finalImageId = imageId;
|
||||
final MultiImageData finalCopyMultiImageData = copyMultiImageData;
|
||||
ThreadHelper.INST.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final File file = new File(TUIConfig.getImageBaseDir() + finalImageId);
|
||||
boolean cacheBitmapExists = false;
|
||||
Bitmap existsBitmap = null;
|
||||
if (file.exists() && file.isFile()) {
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
existsBitmap = BitmapFactory.decodeFile(file.getPath(), options);
|
||||
if (options.outWidth > 0 && options.outHeight > 0) {
|
||||
cacheBitmapExists = true;
|
||||
}
|
||||
}
|
||||
if (!cacheBitmapExists) {
|
||||
asyncLoadImageList(finalCopyMultiImageData);
|
||||
final Bitmap bitmap = synthesizeImageList(finalCopyMultiImageData);
|
||||
ImageUtil.storeBitmap(file, bitmap);
|
||||
ImageUtil.setGroupConversationAvatar(finalImageId, file.getAbsolutePath());
|
||||
BackgroundTasks.getInstance().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
callback.onCall(bitmap, finalImageId);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
final Bitmap finalExistsBitmap = existsBitmap;
|
||||
BackgroundTasks.getInstance().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
callback.onCall(finalExistsBitmap, finalImageId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void clearImage() {
|
||||
GlideEngine.clear(imageView);
|
||||
}
|
||||
|
||||
interface Callback {
|
||||
void onCall(Bitmap bitmap, String targetID);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.tencent.qcloud.tuicore.component.gatherimage;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserIconView extends RelativeLayout {
|
||||
|
||||
private SynthesizedImageView mIconView;
|
||||
private int mDefaultImageResId;
|
||||
private int mIconRadius;
|
||||
|
||||
public UserIconView(Context context) {
|
||||
super(context);
|
||||
init(null);
|
||||
}
|
||||
|
||||
public UserIconView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(attrs);
|
||||
}
|
||||
|
||||
public UserIconView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(attrs);
|
||||
}
|
||||
|
||||
private void init(AttributeSet attributeSet) {
|
||||
inflate(getContext(), R.layout.profile_icon_view, this);
|
||||
if (attributeSet != null) {
|
||||
TypedArray ta = getContext().obtainStyledAttributes(attributeSet, R.styleable.UserIconView);
|
||||
if (null != ta) {
|
||||
mDefaultImageResId = ta.getResourceId(R.styleable.UserIconView_default_image, mDefaultImageResId);
|
||||
mIconRadius = ta.getDimensionPixelSize(R.styleable.UserIconView_image_radius, mIconRadius);
|
||||
ta.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
mIconView = findViewById(R.id.profile_icon);
|
||||
if (mDefaultImageResId > 0) {
|
||||
mIconView.defaultImage(mDefaultImageResId);
|
||||
}
|
||||
if (mIconRadius > 0) {
|
||||
mIconView.setRadius(mIconRadius);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDefaultImageResId(int resId) {
|
||||
mDefaultImageResId = resId;
|
||||
mIconView.defaultImage(resId);
|
||||
}
|
||||
|
||||
public void setRadius(int radius) {
|
||||
mIconRadius = radius;
|
||||
mIconView.setRadius(mIconRadius);
|
||||
}
|
||||
|
||||
public void setIconUrls(List<Object> iconUrls) {
|
||||
mIconView.displayImage(iconUrls).load(null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package com.tencent.qcloud.tuicore.component.imageEngine.impl;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapShader;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.Transformation;
|
||||
import com.bumptech.glide.load.engine.Resource;
|
||||
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
|
||||
import com.bumptech.glide.load.resource.bitmap.BitmapResource;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
|
||||
public class CornerTransform implements Transformation<Bitmap> {
|
||||
|
||||
private BitmapPool mBitmapPool;
|
||||
private float radius;
|
||||
private boolean exceptLeftTop, exceptRightTop, exceptLeftBottom, exceptRightBottom;
|
||||
|
||||
public CornerTransform(Context context, float radius) {
|
||||
this.mBitmapPool = Glide.get(context).getBitmapPool();
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
public void setExceptCorner(boolean leftTop, boolean rightTop, boolean leftBottom, boolean rightBottom) {
|
||||
this.exceptLeftTop = leftTop;
|
||||
this.exceptRightTop = rightTop;
|
||||
this.exceptLeftBottom = leftBottom;
|
||||
this.exceptRightBottom = rightBottom;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Resource<Bitmap> transform(@NonNull Context context, @NonNull Resource<Bitmap> resource, int outWidth, int outHeight) {
|
||||
Bitmap source = resource.get();
|
||||
int finalWidth, finalHeight;
|
||||
// 输出目标的宽高或高宽比例
|
||||
// The width-height or height-width ratio of the output target
|
||||
float ratio;
|
||||
if (outWidth > outHeight) {
|
||||
// 输出宽度>输出高度,求高宽比
|
||||
// output width > output height, find the aspect ratio
|
||||
ratio = (float) outHeight / (float) outWidth;
|
||||
finalWidth = source.getWidth();
|
||||
// 固定原图宽度,求最终高度
|
||||
// Fix the width of the original image and find the final height
|
||||
finalHeight = (int) ((float) source.getWidth() * ratio);
|
||||
if (finalHeight > source.getHeight()) {
|
||||
// 求出的最终高度>原图高度,求宽高比
|
||||
// Find the final height > the original image height, find the aspect ratio
|
||||
ratio = (float) outWidth / (float) outHeight;
|
||||
finalHeight = source.getHeight();
|
||||
// 固定原图高度,求最终宽度
|
||||
// Fix the width of the original image and find the final width
|
||||
finalWidth = (int) ((float) source.getHeight() * ratio);
|
||||
}
|
||||
} else if (outWidth < outHeight) {
|
||||
// 输出宽度 < 输出高度,求宽高比
|
||||
// output width < output height, find the aspect ratio
|
||||
ratio = (float) outWidth / (float) outHeight;
|
||||
finalHeight = source.getHeight();
|
||||
// 固定原图高度,求最终宽度
|
||||
// Fix the width of the original image and find the final width
|
||||
finalWidth = (int) ((float) source.getHeight() * ratio);
|
||||
if (finalWidth > source.getWidth()) {
|
||||
// 求出的最终宽度 > 原图宽度,求高宽比
|
||||
// Find the final width > the original image width, find the aspect ratio
|
||||
ratio = (float) outHeight / (float) outWidth;
|
||||
finalWidth = source.getWidth();
|
||||
finalHeight = (int) ((float) source.getWidth() * ratio);
|
||||
}
|
||||
} else {
|
||||
// 输出宽度=输出高度
|
||||
// output width = output height
|
||||
finalHeight = source.getHeight();
|
||||
finalWidth = finalHeight;
|
||||
}
|
||||
|
||||
// 修正圆角
|
||||
// Correct rounded corners
|
||||
this.radius *= (float) finalHeight / (float) outHeight;
|
||||
Bitmap outBitmap = this.mBitmapPool.get(finalWidth, finalHeight, Bitmap.Config.ARGB_8888);
|
||||
if (outBitmap == null) {
|
||||
outBitmap = Bitmap.createBitmap(finalWidth, finalHeight, Bitmap.Config.ARGB_8888);
|
||||
}
|
||||
|
||||
Canvas canvas = new Canvas(outBitmap);
|
||||
Paint paint = new Paint();
|
||||
BitmapShader shader = new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
|
||||
// 计算中心位置,进行偏移
|
||||
// Calculate the center position and offset it
|
||||
int width = (source.getWidth() - finalWidth) / 2;
|
||||
int height = (source.getHeight() - finalHeight) / 2;
|
||||
if (width != 0 || height != 0) {
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.setTranslate((float) (-width), (float) (-height));
|
||||
shader.setLocalMatrix(matrix);
|
||||
}
|
||||
|
||||
paint.setShader(shader);
|
||||
paint.setAntiAlias(true);
|
||||
RectF rectF = new RectF(0.0F, 0.0F, (float) canvas.getWidth(), (float) canvas.getHeight());
|
||||
canvas.drawRoundRect(rectF, this.radius, this.radius, paint);
|
||||
|
||||
if (exceptLeftTop) {
|
||||
canvas.drawRect(0, 0, radius, radius, paint);
|
||||
}
|
||||
if (exceptRightTop) {
|
||||
canvas.drawRect(canvas.getWidth() - radius, 0, radius, radius, paint);
|
||||
}
|
||||
|
||||
if (exceptLeftBottom) {
|
||||
canvas.drawRect(0, canvas.getHeight() - radius, radius, canvas.getHeight(), paint);
|
||||
}
|
||||
|
||||
if (exceptRightBottom) {
|
||||
canvas.drawRect(canvas.getWidth() - radius, canvas.getHeight() - radius, canvas.getWidth(), canvas.getHeight(), paint);
|
||||
}
|
||||
|
||||
return BitmapResource.obtain(outBitmap, this.mBitmapPool);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
package com.tencent.qcloud.tuicore.component.imageEngine.impl;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.Priority;
|
||||
import com.bumptech.glide.RequestBuilder;
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
||||
import com.bumptech.glide.request.RequestListener;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
import com.tencent.qcloud.tuicore.TUILogin;
|
||||
import com.tencent.qcloud.tuicore.TUIThemeManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class GlideEngine {
|
||||
|
||||
public static void loadCornerImageWithoutPlaceHolder(ImageView imageView, String filePath, RequestListener listener, float radius) {
|
||||
RoundedCorners transform = null;
|
||||
if ((int) radius > 0) {
|
||||
transform = new RoundedCorners((int) radius);
|
||||
}
|
||||
|
||||
RequestOptions options = new RequestOptions()
|
||||
.centerCrop();
|
||||
if (transform != null) {
|
||||
options = options.transform(transform);
|
||||
}
|
||||
Glide.with(TUILogin.getAppContext())
|
||||
.load(filePath)
|
||||
.apply(options)
|
||||
.listener(listener)
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
public static void loadImage(ImageView imageView, String filePath, RequestListener listener) {
|
||||
Glide.with(TUILogin.getAppContext())
|
||||
.load(filePath)
|
||||
.listener(listener)
|
||||
.apply(new RequestOptions().error(TUIThemeManager.getAttrResId(TUILogin.getAppContext(), R.attr.core_default_user_icon)))
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
public static void loadImage(ImageView imageView, String filePath) {
|
||||
Glide.with(TUILogin.getAppContext())
|
||||
.load(filePath)
|
||||
.apply(new RequestOptions().error(TUIThemeManager.getAttrResId(TUILogin.getAppContext(), R.attr.core_default_user_icon)))
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
public static void clear(ImageView imageView) {
|
||||
Glide.with(TUILogin.getAppContext()).clear(imageView);
|
||||
}
|
||||
|
||||
public static void loadImage(ImageView imageView, Uri uri) {
|
||||
if (uri == null) {
|
||||
return;
|
||||
}
|
||||
Glide.with(TUILogin.getAppContext())
|
||||
.load(uri)
|
||||
.apply(new RequestOptions().error(TUIThemeManager.getAttrResId(TUILogin.getAppContext(), R.attr.core_default_user_icon)))
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
public static void loadImage(String filePath, String url) {
|
||||
try {
|
||||
File file = Glide.with(TUILogin.getAppContext()).asFile().load(url).submit().get();
|
||||
File destFile = new File(filePath);
|
||||
file.renameTo(destFile);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadImage(ImageView imageView, Object uri) {
|
||||
if (uri == null) {
|
||||
return;
|
||||
}
|
||||
Glide.with(TUILogin.getAppContext())
|
||||
.load(uri)
|
||||
.apply(new RequestOptions().error(TUIThemeManager.getAttrResId(TUILogin.getAppContext(), R.attr.core_default_user_icon)))
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
public static void loadUserIcon(ImageView imageView, Object uri) {
|
||||
loadUserIcon(imageView, uri, 0);
|
||||
}
|
||||
|
||||
public static void loadUserIcon(ImageView imageView, Object uri, int radius) {
|
||||
Glide.with(TUILogin.getAppContext())
|
||||
.load(uri)
|
||||
.placeholder(TUIThemeManager.getAttrResId(TUILogin.getAppContext(), R.attr.core_default_user_icon))
|
||||
.apply(new RequestOptions().centerCrop().error(TUIThemeManager.getAttrResId(TUILogin.getAppContext(), R.attr.core_default_user_icon)))
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
public static void loadUserIcon(ImageView imageView, Object uri, int defaultResId, int radius) {
|
||||
Glide.with(TUILogin.getAppContext())
|
||||
.load(uri)
|
||||
.placeholder(defaultResId)
|
||||
.apply(new RequestOptions().centerCrop().error(defaultResId))
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
public static Bitmap loadBitmap(Object imageUrl, int targetImageSize) throws InterruptedException, ExecutionException {
|
||||
if (imageUrl == null) {
|
||||
return null;
|
||||
}
|
||||
return Glide.with(TUILogin.getAppContext()).asBitmap()
|
||||
.load(imageUrl)
|
||||
.apply(new RequestOptions().error(TUIThemeManager.getAttrResId(TUILogin.getAppContext(), R.attr.core_default_user_icon)))
|
||||
.into(targetImageSize, targetImageSize)
|
||||
.get();
|
||||
}
|
||||
|
||||
public static Bitmap loadBitmap(Object imageUrl, int width, int height) throws InterruptedException, ExecutionException {
|
||||
if (imageUrl == null) {
|
||||
return null;
|
||||
}
|
||||
return Glide.with(TUILogin.getAppContext()).asBitmap()
|
||||
.load(imageUrl)
|
||||
.apply(new RequestOptions().error(TUIThemeManager.getAttrResId(TUILogin.getAppContext(), R.attr.core_default_user_icon)))
|
||||
.into(width, height)
|
||||
.get();
|
||||
}
|
||||
|
||||
|
||||
public void loadImage(Context context, int resizeX, int resizeY, ImageView imageView, Uri uri) {
|
||||
Glide.with(context)
|
||||
.load(uri)
|
||||
.apply(new RequestOptions()
|
||||
.override(resizeX, resizeY)
|
||||
.priority(Priority.HIGH)
|
||||
.fitCenter())
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
public static void loadImageSetDefault(ImageView imageView, Object uri, int defaultResId) {
|
||||
Glide.with(TUILogin.getAppContext())
|
||||
.load(uri)
|
||||
.placeholder(defaultResId)
|
||||
.apply(new RequestOptions().centerCrop().error(defaultResId))
|
||||
.into(imageView);
|
||||
}
|
||||
private static GlideEngine instance;
|
||||
|
||||
public static GlideEngine createGlideEngine() {
|
||||
if (null == instance) {
|
||||
synchronized (GlideEngine.class) {
|
||||
if (null == instance) {
|
||||
instance = new GlideEngine();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.tencent.qcloud.tuicore.component.interfaces;
|
||||
|
||||
import com.tencent.qcloud.tuicore.component.TitleBarLayout;
|
||||
|
||||
public interface ILayout {
|
||||
|
||||
/**
|
||||
* get title bar
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
TitleBarLayout getTitleBar();
|
||||
|
||||
/**
|
||||
* Set the parent container of this Layout
|
||||
*
|
||||
* @param parent
|
||||
*/
|
||||
void setParentLayout(Object parent);
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
package com.tencent.qcloud.tuicore.component.interfaces;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* 会话列表窗口 {@link ConversationLayout}、聊天窗口 {@link ChatLayout} 等都自带标题栏,<br>
|
||||
* 标题栏设计为左中右三部分标题,左边可为图片+文字,中间为文字,右边也可为图片+文字,这些区域返回的都是标准的<br>
|
||||
* Android View,可以根据业务需要对这些 View 进行交互响应处理。
|
||||
* <p>
|
||||
* Conversation list window {@link ConversationLayout}、chat window {@link ChatLayout} have title bar,
|
||||
* The title bar is designed as a three-part title on the left, middle and right. The left can be
|
||||
* picture + text, the middle is text, and the right can also be picture + text. These areas return the
|
||||
* standard Android View,These Views can be interactively processed according to business needs。
|
||||
*/
|
||||
public interface ITitleBarLayout {
|
||||
|
||||
/**
|
||||
* 设置左边标题的点击事件
|
||||
* <p>
|
||||
* Set the click event of the left header
|
||||
*
|
||||
* @param listener
|
||||
*/
|
||||
void setOnLeftClickListener(View.OnClickListener listener);
|
||||
|
||||
/**
|
||||
* 设置右边标题的点击事件
|
||||
* <p>
|
||||
* Set the click event of the right title
|
||||
*
|
||||
* @param listener
|
||||
*/
|
||||
void setOnRightClickListener(View.OnClickListener listener);
|
||||
|
||||
/**
|
||||
* 设置标题
|
||||
* <p>
|
||||
* set Title
|
||||
*/
|
||||
void setTitle(String title, Position position);
|
||||
|
||||
/**
|
||||
* 返回左边标题区域
|
||||
* <p>
|
||||
* Return to the left header area
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
LinearLayout getLeftGroup();
|
||||
|
||||
/**
|
||||
* 返回右边标题区域
|
||||
* <p>
|
||||
* Return to the right header area
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
LinearLayout getRightGroup();
|
||||
|
||||
/**
|
||||
* 返回左边标题的图片
|
||||
* <p>
|
||||
* Returns the image for the left header
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
ImageView getLeftIcon();
|
||||
|
||||
/**
|
||||
* 设置左边标题的图片
|
||||
* <p>
|
||||
* Set the image for the left header
|
||||
*
|
||||
* @param resId
|
||||
*/
|
||||
void setLeftIcon(int resId);
|
||||
|
||||
/**
|
||||
* 返回右边标题的图片
|
||||
* <p>
|
||||
* Returns the image with the right header
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
ImageView getRightIcon();
|
||||
|
||||
/**
|
||||
* 设置右边标题的图片
|
||||
* <p>
|
||||
* Set the image for the title on the right
|
||||
*
|
||||
* @param resId
|
||||
*/
|
||||
void setRightIcon(int resId);
|
||||
|
||||
/**
|
||||
* 返回左边标题的文字
|
||||
* <p>
|
||||
* Returns the text of the left header
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
TextView getLeftTitle();
|
||||
|
||||
/**
|
||||
* 返回中间标题的文字
|
||||
* <p>
|
||||
* Returns the text of the middle title
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
TextView getMiddleTitle();
|
||||
|
||||
/**
|
||||
* 返回右边标题的文字
|
||||
* <p>
|
||||
* Returns the text of the title on the right
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
TextView getRightTitle();
|
||||
|
||||
|
||||
/**
|
||||
* 返回右边关注
|
||||
*/
|
||||
TextView getRightFollow();
|
||||
|
||||
|
||||
/**
|
||||
* 标题区域的枚举值
|
||||
* <p>
|
||||
* enumeration value of the header area
|
||||
*/
|
||||
enum Position {
|
||||
/**
|
||||
* 左边标题
|
||||
* <p>
|
||||
* left title
|
||||
*/
|
||||
LEFT,
|
||||
/**
|
||||
* 中间标题
|
||||
* <p>
|
||||
* middle title
|
||||
*/
|
||||
MIDDLE,
|
||||
/**
|
||||
* 右边标题
|
||||
* <p>
|
||||
* right title
|
||||
*/
|
||||
RIGHT
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.tencent.qcloud.tuicore.component.interfaces;
|
||||
|
||||
public abstract class IUIKitCallback<T> {
|
||||
|
||||
public void onSuccess(T data) {};
|
||||
|
||||
public void onError(String module, int errCode, String errMsg) {}
|
||||
|
||||
public void onError(int errCode, String errMsg, T data) {}
|
||||
|
||||
public void onProgress(Object data) {}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
package com.tencent.qcloud.tuicore.component.popupcard;
|
||||
|
||||
import android.animation.ValueAnimator;
|
||||
import android.app.Activity;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.text.Editable;
|
||||
import android.text.InputFilter;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
import com.tencent.qcloud.tuicore.util.SoftKeyBoardUtil;
|
||||
import com.tencent.qcloud.tuicore.util.ToastUtil;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class PopupInputCard {
|
||||
private PopupWindow popupWindow;
|
||||
|
||||
private TextView titleTv;
|
||||
private EditText editText;
|
||||
private TextView descriptionTv;
|
||||
private Button positiveBtn;
|
||||
private View closeBtn;
|
||||
private OnClickListener positiveOnClickListener;
|
||||
private OnTextExceedListener textExceedListener;
|
||||
|
||||
private int minLimit = 0;
|
||||
private int maxLimit = Integer.MAX_VALUE;
|
||||
private String rule;
|
||||
private String notMachRuleTip;
|
||||
private ByteLengthFilter lengthFilter = new ByteLengthFilter();
|
||||
public PopupInputCard(Activity activity) {
|
||||
View popupView = LayoutInflater.from(activity).inflate(R.layout.layout_popup_card, null);
|
||||
titleTv = popupView.findViewById(R.id.popup_card_title);
|
||||
editText = popupView.findViewById(R.id.popup_card_edit);
|
||||
descriptionTv = popupView.findViewById(R.id.popup_card_description);
|
||||
positiveBtn = popupView.findViewById(R.id.popup_card_positive_btn);
|
||||
closeBtn = popupView.findViewById(R.id.close_btn);
|
||||
|
||||
popupWindow = new PopupWindow(popupView, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT, true) {
|
||||
@Override
|
||||
public void showAtLocation(View anchor, int gravity, int x, int y) {
|
||||
if (activity != null && !activity.isFinishing()) {
|
||||
Window dialogWindow = activity.getWindow();
|
||||
startAnimation(dialogWindow, true);
|
||||
}
|
||||
editText.requestFocus();
|
||||
if (activity.getWindow() != null) {
|
||||
SoftKeyBoardUtil.showKeyBoard(activity.getWindow());
|
||||
}
|
||||
super.showAtLocation(anchor, gravity, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismiss() {
|
||||
if (activity != null && !activity.isFinishing()) {
|
||||
Window dialogWindow = activity.getWindow();
|
||||
startAnimation(dialogWindow, false);
|
||||
}
|
||||
|
||||
super.dismiss();
|
||||
}
|
||||
};
|
||||
popupWindow.setBackgroundDrawable(new ColorDrawable());
|
||||
popupWindow.setTouchable(true);
|
||||
popupWindow.setOutsideTouchable(false);
|
||||
popupWindow.setAnimationStyle(R.style.PopupInputCardAnim);
|
||||
|
||||
popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss() {
|
||||
if (activity.getWindow() != null) {
|
||||
SoftKeyBoardUtil.hideKeyBoard(activity.getWindow());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
positiveBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
String result = editText.getText().toString();
|
||||
|
||||
if (result.length() < minLimit || result.length() > maxLimit) {
|
||||
ToastUtil.toastShortMessage(notMachRuleTip);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(rule) && !Pattern.matches(rule, result)) {
|
||||
ToastUtil.toastShortMessage(notMachRuleTip);
|
||||
return;
|
||||
}
|
||||
|
||||
if (positiveOnClickListener != null) {
|
||||
positiveOnClickListener.onClick(editText.getText().toString());
|
||||
}
|
||||
popupWindow.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
closeBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
popupWindow.dismiss();
|
||||
}
|
||||
});
|
||||
editText.setFilters(new InputFilter[] {lengthFilter});
|
||||
editText.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
if (!TextUtils.isEmpty(rule)) {
|
||||
if (!Pattern.matches(rule, s.toString())) {
|
||||
positiveBtn.setEnabled(false);
|
||||
} else {
|
||||
positiveBtn.setEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
private void startAnimation(Window window, boolean isShow) {
|
||||
LinearInterpolator interpolator = new LinearInterpolator();
|
||||
ValueAnimator animator;
|
||||
if (isShow) {
|
||||
animator = ValueAnimator.ofFloat(1.0f, 0.5f);
|
||||
} else {
|
||||
animator = ValueAnimator.ofFloat(0.5f, 1.0f);
|
||||
}
|
||||
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
WindowManager.LayoutParams lp = window.getAttributes();
|
||||
lp.alpha = (float) animation.getAnimatedValue();
|
||||
window.setAttributes(lp);
|
||||
}
|
||||
});
|
||||
|
||||
animator.setDuration(200);
|
||||
animator.setInterpolator(interpolator);
|
||||
animator.start();
|
||||
}
|
||||
|
||||
public void show(View rootView, int gravity) {
|
||||
if (popupWindow != null) {
|
||||
popupWindow.showAtLocation(rootView, gravity, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
titleTv.setText(title);
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
if (!TextUtils.isEmpty(description)) {
|
||||
descriptionTv.setVisibility(View.VISIBLE);
|
||||
descriptionTv.setText(description);
|
||||
}
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
editText.setText(content);
|
||||
}
|
||||
|
||||
public void setOnPositive(OnClickListener clickListener) {
|
||||
positiveOnClickListener = clickListener;
|
||||
}
|
||||
|
||||
public void setTextExceedListener(OnTextExceedListener textExceedListener) {
|
||||
this.textExceedListener = textExceedListener;
|
||||
}
|
||||
|
||||
public void setSingleLine(boolean isSingleLine) {
|
||||
editText.setSingleLine(isSingleLine);
|
||||
}
|
||||
|
||||
public void setMaxLimit(int maxLimit) {
|
||||
this.maxLimit = maxLimit;
|
||||
lengthFilter.setLength(maxLimit);
|
||||
}
|
||||
|
||||
public void setMinLimit(int minLimit) {
|
||||
this.minLimit = minLimit;
|
||||
}
|
||||
|
||||
public void setRule(String rule) {
|
||||
if (TextUtils.isEmpty(rule)) {
|
||||
this.rule = "";
|
||||
} else {
|
||||
this.rule = rule;
|
||||
}
|
||||
}
|
||||
|
||||
public void setNotMachRuleTip(String notMachRuleTip) {
|
||||
this.notMachRuleTip = notMachRuleTip;
|
||||
}
|
||||
|
||||
class ByteLengthFilter implements InputFilter {
|
||||
private int length = Integer.MAX_VALUE;
|
||||
public ByteLengthFilter() {
|
||||
}
|
||||
|
||||
public void setLength(int length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
|
||||
int destLength = 0;
|
||||
int destReplaceLength = 0;
|
||||
int sourceLength = 0;
|
||||
if (!TextUtils.isEmpty(dest)) {
|
||||
destLength = dest.toString().getBytes().length;
|
||||
destReplaceLength= dest.subSequence(dstart, dend).toString().getBytes().length;
|
||||
}
|
||||
if (!TextUtils.isEmpty(source)) {
|
||||
sourceLength = source.subSequence(start, end).toString().getBytes().length;
|
||||
}
|
||||
int keepBytesLength = length - (destLength - destReplaceLength);
|
||||
if (keepBytesLength <= 0) {
|
||||
if (textExceedListener != null) {
|
||||
textExceedListener.onTextExceedMax();
|
||||
}
|
||||
return "";
|
||||
} else if (keepBytesLength >= sourceLength) {
|
||||
return null;
|
||||
} else {
|
||||
if (textExceedListener != null) {
|
||||
textExceedListener.onTextExceedMax();
|
||||
}
|
||||
return getSource(source, start, keepBytesLength);
|
||||
}
|
||||
}
|
||||
|
||||
private CharSequence getSource(CharSequence sequence, int start, int keepLength) {
|
||||
int sequenceLength = sequence.length();
|
||||
int end = 0;
|
||||
for (int i = 1; i <= sequenceLength; i++) {
|
||||
if (sequence.subSequence(0, i).toString().getBytes().length <= keepLength) {
|
||||
end = i;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (end > 0 && Character.isHighSurrogate(sequence.charAt(end - 1))) {
|
||||
--end;
|
||||
if (end == start) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
return sequence.subSequence(start, end);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface OnClickListener {
|
||||
void onClick(String result);
|
||||
}
|
||||
|
||||
public interface OnTextExceedListener {
|
||||
void onTextExceedMax();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.tencent.qcloud.tuicore.interfaces;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface ITUIExtension {
|
||||
Map<String, Object> onGetExtensionInfo(String key, Map<String, Object> param);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.tencent.qcloud.tuicore.interfaces;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface ITUINotification {
|
||||
void onNotifyEvent(String key, String subKey, Map<String, Object> param);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.tencent.qcloud.tuicore.interfaces;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface ITUIService {
|
||||
Object onCall(String method, Map<String, Object> param);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.tencent.qcloud.tuicore.interfaces;
|
||||
|
||||
public abstract class TUICallback {
|
||||
public abstract void onSuccess();
|
||||
|
||||
public abstract void onError(int errorCode, String errorMessage);
|
||||
|
||||
public static void onSuccess(TUICallback callback) {
|
||||
if (callback != null) {
|
||||
callback.onSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
public static void onError(TUICallback callback, int errorCode, String errorMessage) {
|
||||
if (callback != null) {
|
||||
callback.onError(errorCode, errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.tencent.qcloud.tuicore.interfaces;
|
||||
|
||||
public abstract class TUILogListener {
|
||||
public void onLog(int logLevel, String logContent) {}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.tencent.qcloud.tuicore.interfaces;
|
||||
|
||||
public class TUILoginConfig {
|
||||
/**
|
||||
* ## Do not output any SDK logs
|
||||
*/
|
||||
public static final int TUI_LOG_NONE = 0;
|
||||
/**
|
||||
* ## Output logs at the DEBUG, INFO, WARNING, and ERROR levels
|
||||
*/
|
||||
public static final int TUI_LOG_DEBUG = 3;
|
||||
/**
|
||||
* ## Output logs at the INFO, WARNING, and ERROR levels
|
||||
*/
|
||||
public static final int TUI_LOG_INFO = 4;
|
||||
/**
|
||||
* ## Output logs at the WARNING and ERROR levels
|
||||
*/
|
||||
public static final int TUI_LOG_WARN = 5;
|
||||
/**
|
||||
* ## Output logs at the ERROR level
|
||||
*/
|
||||
public static final int TUI_LOG_ERROR = 6;
|
||||
|
||||
// Log level
|
||||
private int logLevel = TUI_LOG_INFO;
|
||||
|
||||
// Log callback
|
||||
private TUILogListener tuiLogListener;
|
||||
|
||||
/**
|
||||
* Configuration class constructor
|
||||
*/
|
||||
public TUILoginConfig() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the write log level. This operation must be performed before IM SDK initialization. Otherwise, the setting does not take effect.
|
||||
*
|
||||
* @param logLevel Log level
|
||||
*/
|
||||
public void setLogLevel(int logLevel) {
|
||||
this.logLevel = logLevel;
|
||||
}
|
||||
|
||||
public int getLogLevel() {
|
||||
return this.logLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current log callback listener
|
||||
*/
|
||||
public TUILogListener getLogListener() {
|
||||
return tuiLogListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current log callback listener. This operation must be performed before IM SDK initialization.
|
||||
* @note The callback is in the main thread. Log callbacks can be quite frequent, so be careful not to synchronize too many time-consuming tasks in the callback, which may block the main thread.
|
||||
*/
|
||||
public void setLogListener(TUILogListener logListener) {
|
||||
this.tuiLogListener = logListener;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.tencent.qcloud.tuicore.interfaces;
|
||||
|
||||
public abstract class TUILoginListener {
|
||||
/**
|
||||
* SDK 正在连接到腾讯云服务器
|
||||
*
|
||||
* The SDK is connecting to the CVM instance
|
||||
*/
|
||||
public void onConnecting() {
|
||||
}
|
||||
|
||||
/**
|
||||
* SDK 已经成功连接到腾讯云服务器
|
||||
*
|
||||
* The SDK is successfully connected to the CVM instance
|
||||
*/
|
||||
public void onConnectSuccess() {
|
||||
}
|
||||
|
||||
/**
|
||||
* SDK 连接腾讯云服务器失败
|
||||
*
|
||||
* The SDK failed to connect to the CVM instance
|
||||
*/
|
||||
public void onConnectFailed(int code, String error) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前用户被踢下线,此时可以 UI 提示用户,并再次调用 TUILogin 的 login() 函数重新登录。
|
||||
*
|
||||
* The current user is kicked offline: the SDK notifies the user on the UI, and the user can choose to call the login() function of V2TIMManager to log in again.
|
||||
*/
|
||||
public void onKickedOffline() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 在线时票据过期:此时您需要生成新的 userSig 并再次调用 TUILogin 的 login() 函数重新登录。
|
||||
*
|
||||
* The ticket expires when the user is online: the user needs to generate a new userSig and call the login() function of V2TIMManager to log in again.
|
||||
*/
|
||||
public void onUserSigExpired() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.tencent.qcloud.tuicore.util;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
|
||||
public class BackgroundTasks {
|
||||
|
||||
private static final BackgroundTasks instance = new BackgroundTasks();
|
||||
private final Handler handler = new Handler(Looper.getMainLooper());
|
||||
|
||||
public static BackgroundTasks getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private BackgroundTasks() {}
|
||||
|
||||
public void runOnUiThread(Runnable runnable) {
|
||||
handler.post(runnable);
|
||||
}
|
||||
|
||||
public boolean postDelayed(Runnable r, long delayMillis) {
|
||||
return handler.postDelayed(r, delayMillis);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
package com.tencent.qcloud.tuicore.util;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
import com.tencent.qcloud.tuicore.TUIConfig;
|
||||
import com.tencent.qcloud.tuicore.TUIThemeManager;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
public class DateTimeUtil {
|
||||
|
||||
private final static long minute = 60 * 1000;
|
||||
private final static long hour = 60 * minute;
|
||||
private final static long day = 24 * hour;
|
||||
private final static long week = 7 * day;
|
||||
private final static long month = 31 * day;
|
||||
private final static long year = 12 * month;
|
||||
|
||||
/**
|
||||
* return format text for time
|
||||
* you can see https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html
|
||||
* today:HH:MM
|
||||
* this week:Sunday, Friday ..
|
||||
* this year:MM/DD
|
||||
* before this year:YYYY/MM/DD
|
||||
* @param date current time
|
||||
* @return format text
|
||||
*/
|
||||
public static String getTimeFormatText(Date date) {
|
||||
if (date == null) {
|
||||
return "";
|
||||
}
|
||||
Context context = TUIConfig.getAppContext();
|
||||
Locale locale;
|
||||
if (context == null) {
|
||||
locale = Locale.getDefault();
|
||||
} else {
|
||||
locale = TUIThemeManager.getInstance().getLocale(context);
|
||||
}
|
||||
String timeText;
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
long dayStartTimeInMillis = calendar.getTimeInMillis();
|
||||
calendar = Calendar.getInstance();
|
||||
calendar.set(Calendar.DAY_OF_WEEK, 1);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
long weekStartTimeInMillis = calendar.getTimeInMillis();
|
||||
calendar = Calendar.getInstance();
|
||||
calendar.set(Calendar.DAY_OF_YEAR, 1);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
long yearStartTimeInMillis = calendar.getTimeInMillis();
|
||||
long outTimeMillis = date.getTime();
|
||||
if (outTimeMillis < yearStartTimeInMillis) {
|
||||
timeText = String.format(locale, "%tD", date);
|
||||
} else if (outTimeMillis < weekStartTimeInMillis) {
|
||||
timeText = String.format(locale, "%1$tm/%1$td", date);
|
||||
} else if (outTimeMillis < dayStartTimeInMillis) {
|
||||
timeText = String.format(locale, "%tA", date);
|
||||
} else {
|
||||
timeText = String.format(locale, "%tR", date);
|
||||
}
|
||||
return timeText;
|
||||
}
|
||||
|
||||
/**
|
||||
* HH:MM
|
||||
* @param date current time
|
||||
* @return format text e.g. "12:12"
|
||||
*/
|
||||
public static String getHMTimeString(Date date) {
|
||||
if (date == null) {
|
||||
return "";
|
||||
}
|
||||
Context context = TUIConfig.getAppContext();
|
||||
Locale locale;
|
||||
if (context == null) {
|
||||
locale = Locale.getDefault();
|
||||
} else {
|
||||
locale = TUIThemeManager.getInstance().getLocale(context);
|
||||
}
|
||||
return String.format(locale, "%tR", date);
|
||||
}
|
||||
|
||||
public static String formatSeconds(long seconds) {
|
||||
Context context = TUIConfig.getAppContext();
|
||||
String timeStr = seconds + context.getString(R.string.date_second_short);
|
||||
if (seconds > 60) {
|
||||
long second = seconds % 60;
|
||||
long min = seconds / 60;
|
||||
timeStr = min + context.getString(R.string.date_minute_short) + second + context.getString(R.string.date_second_short);
|
||||
if (min > 60) {
|
||||
min = (seconds / 60) % 60;
|
||||
long hour = (seconds / 60) / 60;
|
||||
timeStr = hour + context.getString(R.string.date_hour_short) + min + context.getString(R.string.date_minute_short) + second + context.getString(R.string.date_second_short);
|
||||
if (hour % 24 == 0) {
|
||||
long day = (((seconds / 60) / 60) / 24);
|
||||
timeStr = day + context.getString(R.string.date_day_short);
|
||||
} else if (hour > 24) {
|
||||
hour = ((seconds / 60) / 60) % 24;
|
||||
long day = (((seconds / 60) / 60) / 24);
|
||||
timeStr = day + context.getString(R.string.date_day_short) + hour + context.getString(R.string.date_hour_short) + min + context.getString(R.string.date_minute_short) + second + context.getString(R.string.date_second_short);
|
||||
}
|
||||
}
|
||||
}
|
||||
return timeStr;
|
||||
}
|
||||
|
||||
public static String formatSecondsTo00(int timeSeconds) {
|
||||
int second = timeSeconds % 60;
|
||||
int minuteTemp = timeSeconds / 60;
|
||||
if (minuteTemp > 0) {
|
||||
int minute = minuteTemp % 60;
|
||||
int hour = minuteTemp / 60;
|
||||
if (hour > 0) {
|
||||
return (hour >= 10 ? (hour + "") : ("0" + hour)) + ":" + (minute >= 10 ? (minute + "") : ("0" + minute))
|
||||
+ ":" + (second >= 10 ? (second + "") : ("0" + second));
|
||||
} else {
|
||||
return (minute >= 10 ? (minute + "") : ("0" + minute)) + ":"
|
||||
+ (second >= 10 ? (second + "") : ("0" + second));
|
||||
}
|
||||
} else {
|
||||
return "00:" + (second >= 10 ? (second + "") : ("0" + second));
|
||||
}
|
||||
}
|
||||
|
||||
public static long getStringToDate(String dateString, String pattern) {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
|
||||
Date date = new Date();
|
||||
try{
|
||||
date = dateFormat.parse(dateString);
|
||||
} catch(ParseException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return date.getTime();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,733 @@
|
||||
package com.tencent.qcloud.tuicore.util;
|
||||
|
||||
import com.tencent.imsdk.BaseConstants;
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
import com.tencent.qcloud.tuicore.TUIConfig;
|
||||
|
||||
public class ErrorMessageConverter {
|
||||
|
||||
public static String convertIMError(int code, String msg) {
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (一)IM SDK 的错误码
|
||||
// IM SDK error codes
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
switch (code) {
|
||||
// 通用错误码
|
||||
// Common error codes
|
||||
case BaseConstants.ERR_IN_PROGESS:
|
||||
return getLocalizedString(R.string.TUIKitErrorInProcess);
|
||||
case BaseConstants.ERR_INVALID_PARAMETERS:
|
||||
return getLocalizedString(R.string.TUIKitErrorInvalidParameters);
|
||||
case BaseConstants.ERR_IO_OPERATION_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorIOOperateFaild);
|
||||
case BaseConstants.ERR_INVALID_JSON:
|
||||
return getLocalizedString(R.string.TUIKitErrorInvalidJson);
|
||||
case BaseConstants.ERR_OUT_OF_MEMORY:
|
||||
return getLocalizedString(R.string.TUIKitErrorOutOfMemory);
|
||||
case BaseConstants.ERR_PARSE_RESPONSE_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorParseResponseFaild);
|
||||
case BaseConstants.ERR_SERIALIZE_REQ_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSerializeReqFaild);
|
||||
case BaseConstants.ERR_SDK_NOT_INITIALIZED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKNotInit);
|
||||
case BaseConstants.ERR_LOADMSG_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorLoadMsgFailed);
|
||||
case BaseConstants.ERR_DATABASE_OPERATE_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorDatabaseOperateFailed);
|
||||
case BaseConstants.ERR_SDK_COMM_CROSS_THREAD:
|
||||
return getLocalizedString(R.string.TUIKitErrorCrossThread);
|
||||
case BaseConstants.ERR_SDK_COMM_TINYID_EMPTY:
|
||||
return getLocalizedString(R.string.TUIKitErrorTinyIdEmpty);
|
||||
case BaseConstants.ERR_SDK_COMM_INVALID_IDENTIFIER:
|
||||
return getLocalizedString(R.string.TUIKitErrorInvalidIdentifier);
|
||||
case BaseConstants.ERR_SDK_COMM_FILE_NOT_FOUND:
|
||||
return getLocalizedString(R.string.TUIKitErrorFileNotFound);
|
||||
case BaseConstants.ERR_SDK_COMM_FILE_TOO_LARGE:
|
||||
return getLocalizedString(R.string.TUIKitErrorFileTooLarge);
|
||||
case BaseConstants.ERR_SDK_COMM_FILE_SIZE_EMPTY:
|
||||
return getLocalizedString(R.string.TUIKitErrorEmptyFile);
|
||||
case BaseConstants.ERR_SDK_COMM_FILE_OPEN_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorFileOpenFailed);
|
||||
|
||||
// 帐号错误码
|
||||
// Account error codes
|
||||
case BaseConstants.ERR_SDK_NOT_LOGGED_IN:
|
||||
return getLocalizedString(R.string.TUIKitErrorNotLogin);
|
||||
case BaseConstants.ERR_NO_PREVIOUS_LOGIN:
|
||||
return getLocalizedString(R.string.TUIKitErrorNoPreviousLogin);
|
||||
case BaseConstants.ERR_USER_SIG_EXPIRED:
|
||||
return getLocalizedString(R.string.TUIKitErrorUserSigExpired);
|
||||
case BaseConstants.ERR_LOGIN_KICKED_OFF_BY_OTHER:
|
||||
return getLocalizedString(R.string.TUIKitErrorLoginKickedOffByOther);
|
||||
// case BaseConstants.ERR_LOGIN_IN_PROCESS:
|
||||
// return @"登录正在执行中";
|
||||
// case BaseConstants.ERR_LOGOUT_IN_PROCESS:
|
||||
// return @"登出正在执行中";
|
||||
case BaseConstants.ERR_SDK_ACCOUNT_TLS_INIT_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorTLSSDKInit);
|
||||
case BaseConstants.ERR_SDK_ACCOUNT_TLS_NOT_INITIALIZED:
|
||||
return getLocalizedString(R.string.TUIKitErrorTLSSDKUninit);
|
||||
case BaseConstants.ERR_SDK_ACCOUNT_TLS_TRANSPKG_ERROR:
|
||||
return getLocalizedString(R.string.TUIKitErrorTLSSDKTRANSPackageFormat);
|
||||
case BaseConstants.ERR_SDK_ACCOUNT_TLS_DECRYPT_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorTLSDecrypt);
|
||||
case BaseConstants.ERR_SDK_ACCOUNT_TLS_REQUEST_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorTLSSDKRequest);
|
||||
case BaseConstants.ERR_SDK_ACCOUNT_TLS_REQUEST_TIMEOUT:
|
||||
return getLocalizedString(R.string.TUIKitErrorTLSSDKRequestTimeout);
|
||||
|
||||
// 消息错误码
|
||||
// Message error codes
|
||||
case BaseConstants.ERR_INVALID_CONVERSATION:
|
||||
return getLocalizedString(R.string.TUIKitErrorInvalidConveration);
|
||||
case BaseConstants.ERR_FILE_TRANS_AUTH_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorFileTransAuthFailed);
|
||||
case BaseConstants.ERR_FILE_TRANS_NO_SERVER:
|
||||
return getLocalizedString(R.string.TUIKitErrorFileTransNoServer);
|
||||
case BaseConstants.ERR_FILE_TRANS_UPLOAD_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorFileTransUploadFailed);
|
||||
// case BaseConstants.ERR_IMAGE_UPLOAD_FAILED_NOTIMAGE:
|
||||
// return TUIKitLocalizableString(R.string.TUIKitErrorFileTransUploadFailedNotImage);
|
||||
case BaseConstants.ERR_FILE_TRANS_DOWNLOAD_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorFileTransDownloadFailed);
|
||||
case BaseConstants.ERR_HTTP_REQ_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorHTTPRequestFailed);
|
||||
case BaseConstants.ERR_INVALID_MSG_ELEM:
|
||||
return getLocalizedString(R.string.TUIKitErrorInvalidMsgElem);
|
||||
case BaseConstants.ERR_INVALID_SDK_OBJECT:
|
||||
return getLocalizedString(R.string.TUIKitErrorInvalidSDKObject);
|
||||
case BaseConstants.ERR_SDK_MSG_BODY_SIZE_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitSDKMsgBodySizeLimit);
|
||||
case BaseConstants.ERR_SDK_MSG_KEY_REQ_DIFFER_RSP:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKMsgKeyReqDifferRsp);
|
||||
|
||||
|
||||
// 群组错误码
|
||||
// Group error codes
|
||||
case BaseConstants.ERR_SDK_GROUP_INVALID_ID:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKGroupInvalidID);
|
||||
case BaseConstants.ERR_SDK_GROUP_INVALID_NAME:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKGroupInvalidName);
|
||||
case BaseConstants.ERR_SDK_GROUP_INVALID_INTRODUCTION:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKGroupInvalidIntroduction);
|
||||
case BaseConstants.ERR_SDK_GROUP_INVALID_NOTIFICATION:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKGroupInvalidNotification);
|
||||
case BaseConstants.ERR_SDK_GROUP_INVALID_FACE_URL:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKGroupInvalidFaceURL);
|
||||
case BaseConstants.ERR_SDK_GROUP_INVALID_NAME_CARD:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKGroupInvalidNameCard);
|
||||
case BaseConstants.ERR_SDK_GROUP_MEMBER_COUNT_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKGroupMemberCountLimit);
|
||||
case BaseConstants.ERR_SDK_GROUP_JOIN_PRIVATE_GROUP_DENY:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKGroupJoinPrivateGroupDeny);
|
||||
case BaseConstants.ERR_SDK_GROUP_INVITE_SUPER_DENY:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKGroupInviteSuperDeny);
|
||||
case BaseConstants.ERR_SDK_GROUP_INVITE_NO_MEMBER:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKGroupInviteNoMember);
|
||||
|
||||
|
||||
// 关系链错误码
|
||||
// Relationship chain error codes
|
||||
case BaseConstants.ERR_SDK_FRIENDSHIP_INVALID_PROFILE_KEY:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKFriendShipInvalidProfileKey);
|
||||
case BaseConstants.ERR_SDK_FRIENDSHIP_INVALID_ADD_REMARK:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKFriendshipInvalidAddRemark);
|
||||
case BaseConstants.ERR_SDK_FRIENDSHIP_INVALID_ADD_WORDING:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKFriendshipInvalidAddWording);
|
||||
case BaseConstants.ERR_SDK_FRIENDSHIP_INVALID_ADD_SOURCE:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKFriendshipInvalidAddSource);
|
||||
case BaseConstants.ERR_SDK_FRIENDSHIP_FRIEND_GROUP_EMPTY:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKFriendshipFriendGroupEmpty);
|
||||
|
||||
|
||||
// 网络错误码
|
||||
// Network error codes
|
||||
case BaseConstants.ERR_SDK_NET_ENCODE_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKNetEncodeFailed);
|
||||
case BaseConstants.ERR_SDK_NET_DECODE_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKNetDecodeFailed);
|
||||
case BaseConstants.ERR_SDK_NET_AUTH_INVALID:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKNetAuthInvalid);
|
||||
case BaseConstants.ERR_SDK_NET_COMPRESS_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKNetCompressFailed);
|
||||
case BaseConstants.ERR_SDK_NET_UNCOMPRESS_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKNetUncompressFaile);
|
||||
case BaseConstants.ERR_SDK_NET_FREQ_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKNetFreqLimit);
|
||||
case BaseConstants.ERR_SDK_NET_REQ_COUNT_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKnetReqCountLimit);
|
||||
case BaseConstants.ERR_SDK_NET_DISCONNECT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKNetDisconnect);
|
||||
case BaseConstants.ERR_SDK_NET_ALLREADY_CONN:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKNetAllreadyConn);
|
||||
case BaseConstants.ERR_SDK_NET_CONN_TIMEOUT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKNetConnTimeout);
|
||||
case BaseConstants.ERR_SDK_NET_CONN_REFUSE:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKNetConnRefuse);
|
||||
case BaseConstants.ERR_SDK_NET_NET_UNREACH:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKNetNetUnreach);
|
||||
case BaseConstants.ERR_SDK_NET_SOCKET_NO_BUFF:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKNetSocketNoBuff);
|
||||
case BaseConstants.ERR_SDK_NET_RESET_BY_PEER:
|
||||
return getLocalizedString(R.string.TUIKitERRORSDKNetResetByPeer);
|
||||
case BaseConstants.ERR_SDK_NET_SOCKET_INVALID:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKNetSOcketInvalid);
|
||||
case BaseConstants.ERR_SDK_NET_HOST_GETADDRINFO_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKNetHostGetAddressFailed);
|
||||
case BaseConstants.ERR_SDK_NET_CONNECT_RESET:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKNetConnectReset);
|
||||
case BaseConstants.ERR_SDK_NET_WAIT_INQUEUE_TIMEOUT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKNetWaitInQueueTimeout);
|
||||
case BaseConstants.ERR_SDK_NET_WAIT_SEND_TIMEOUT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKNetWaitSendTimeout);
|
||||
case BaseConstants.ERR_SDK_NET_WAIT_ACK_TIMEOUT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKNetWaitAckTimeut);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (二)服务端
|
||||
// Server error codes
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 网络接入层的错误码
|
||||
// Access layer error codes for network
|
||||
case BaseConstants.ERR_SVR_SSO_CONNECT_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKSVRSSOConnectLimit);
|
||||
case BaseConstants.ERR_SVR_SSO_VCODE:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKSVRSSOVCode);
|
||||
case BaseConstants.ERR_SVR_SSO_D2_EXPIRED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSOD2Expired);
|
||||
case BaseConstants.ERR_SVR_SSO_A2_UP_INVALID:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRA2UpInvalid);
|
||||
case BaseConstants.ERR_SVR_SSO_A2_DOWN_INVALID:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRA2DownInvalid);
|
||||
case BaseConstants.ERR_SVR_SSO_EMPTY_KEY:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSOEmpeyKey);
|
||||
case BaseConstants.ERR_SVR_SSO_UIN_INVALID:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSOUinInvalid);
|
||||
case BaseConstants.ERR_SVR_SSO_VCODE_TIMEOUT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSOVCodeTimeout);
|
||||
case BaseConstants.ERR_SVR_SSO_NO_IMEI_AND_A2:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSONoImeiAndA2);
|
||||
case BaseConstants.ERR_SVR_SSO_COOKIE_INVALID:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSOCookieInvalid);
|
||||
case BaseConstants.ERR_SVR_SSO_DOWN_TIP:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSODownTips);
|
||||
case BaseConstants.ERR_SVR_SSO_DISCONNECT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSODisconnect);
|
||||
case BaseConstants.ERR_SVR_SSO_IDENTIFIER_INVALID:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSOIdentifierInvalid);
|
||||
case BaseConstants.ERR_SVR_SSO_CLIENT_CLOSE:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSOClientClose);
|
||||
case BaseConstants.ERR_SVR_SSO_MSFSDK_QUIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSOMSFSDKQuit);
|
||||
case BaseConstants.ERR_SVR_SSO_D2KEY_WRONG:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSOD2KeyWrong);
|
||||
case BaseConstants.ERR_SVR_SSO_UNSURPPORT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSOUnsupport);
|
||||
case BaseConstants.ERR_SVR_SSO_PREPAID_ARREARS:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSOPrepaidArrears);
|
||||
case BaseConstants.ERR_SVR_SSO_PACKET_WRONG:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSOPacketWrong);
|
||||
case BaseConstants.ERR_SVR_SSO_APPID_BLACK_LIST:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSOAppidBlackList);
|
||||
case BaseConstants.ERR_SVR_SSO_CMD_BLACK_LIST:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSOCmdBlackList);
|
||||
case BaseConstants.ERR_SVR_SSO_APPID_WITHOUT_USING:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSOAppidWithoutUsing);
|
||||
case BaseConstants.ERR_SVR_SSO_FREQ_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSOFreqLimit);
|
||||
case BaseConstants.ERR_SVR_SSO_OVERLOAD:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRSSOOverload);
|
||||
|
||||
// 资源文件错误码
|
||||
// Resource file error codes
|
||||
case BaseConstants.ERR_SVR_RES_NOT_FOUND:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRResNotFound);
|
||||
case BaseConstants.ERR_SVR_RES_ACCESS_DENY:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRResAccessDeny);
|
||||
case BaseConstants.ERR_SVR_RES_SIZE_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRResSizeLimit);
|
||||
case BaseConstants.ERR_SVR_RES_SEND_CANCEL:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRResSendCancel);
|
||||
case BaseConstants.ERR_SVR_RES_READ_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRResReadFailed);
|
||||
case BaseConstants.ERR_SVR_RES_TRANSFER_TIMEOUT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRResTransferTimeout);
|
||||
case BaseConstants.ERR_SVR_RES_INVALID_PARAMETERS:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRResInvalidParameters);
|
||||
case BaseConstants.ERR_SVR_RES_INVALID_FILE_MD5:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRResInvalidFileMd5);
|
||||
case BaseConstants.ERR_SVR_RES_INVALID_PART_MD5:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRResInvalidPartMd5);
|
||||
|
||||
// 后台公共错误码
|
||||
// Common backend error codes
|
||||
case BaseConstants.ERR_SVR_COMM_INVALID_HTTP_URL:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonInvalidHttpUrl);
|
||||
case BaseConstants.ERR_SVR_COMM_REQ_JSON_PARSE_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommomReqJsonParseFailed);
|
||||
case BaseConstants.ERR_SVR_COMM_INVALID_ACCOUNT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonInvalidAccount);
|
||||
case BaseConstants.ERR_SVR_COMM_INVALID_ACCOUNT_EX:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonInvalidAccount);
|
||||
case BaseConstants.ERR_SVR_COMM_INVALID_SDKAPPID:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonInvalidSdkappid);
|
||||
case BaseConstants.ERR_SVR_COMM_REST_FREQ_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonRestFreqLimit);
|
||||
case BaseConstants.ERR_SVR_COMM_REQUEST_TIMEOUT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonRequestTimeout);
|
||||
case BaseConstants.ERR_SVR_COMM_INVALID_RES:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonInvalidRes);
|
||||
case BaseConstants.ERR_SVR_COMM_ID_NOT_ADMIN:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonIDNotAdmin);
|
||||
case BaseConstants.ERR_SVR_COMM_SDKAPPID_FREQ_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonSdkappidFreqLimit);
|
||||
case BaseConstants.ERR_SVR_COMM_SDKAPPID_MISS:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonSdkappidMiss);
|
||||
case BaseConstants.ERR_SVR_COMM_RSP_JSON_PARSE_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonRspJsonParseFailed);
|
||||
case BaseConstants.ERR_SVR_COMM_EXCHANGE_ACCOUNT_TIMEUT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonExchangeAccountTimeout);
|
||||
case BaseConstants.ERR_SVR_COMM_INVALID_ID_FORMAT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonInvalidIdFormat);
|
||||
case BaseConstants.ERR_SVR_COMM_SDKAPPID_FORBIDDEN:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonSDkappidForbidden);
|
||||
case BaseConstants.ERR_SVR_COMM_REQ_FORBIDDEN:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonReqForbidden);
|
||||
case BaseConstants.ERR_SVR_COMM_REQ_FREQ_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonReqFreqLimit);
|
||||
case BaseConstants.ERR_SVR_COMM_REQ_FREQ_LIMIT_EX:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonReqFreqLimit);
|
||||
case BaseConstants.ERR_SVR_COMM_INVALID_SERVICE:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonInvalidService);
|
||||
case BaseConstants.ERR_SVR_COMM_SENSITIVE_TEXT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonSensitiveText);
|
||||
case BaseConstants.ERR_SVR_COMM_BODY_SIZE_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRCommonBodySizeLimit);
|
||||
|
||||
// 帐号错误码
|
||||
// Account error codes
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_USERSIG_EXPIRED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountUserSigExpired);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_USERSIG_EMPTY:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountUserSigEmpty);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_USERSIG_CHECK_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountUserSigCheckFailed);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_USERSIG_CHECK_FAILED_EX:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountUserSigCheckFailed);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_USERSIG_MISMATCH_PUBLICKEY:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountUserSigMismatchPublicKey);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_USERSIG_MISMATCH_ID:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountUserSigMismatchId);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_USERSIG_MISMATCH_SDKAPPID:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountUserSigMismatchSdkAppid);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_USERSIG_PUBLICKEY_NOT_FOUND:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountUserSigPublicKeyNotFound);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_SDKAPPID_NOT_FOUND:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountUserSigSdkAppidNotFount);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_INVALID_USERSIG:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountInvalidUserSig);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_NOT_FOUND:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountNotFound);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_SEC_RSTR:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountSecRstr);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_INTERNAL_TIMEOUT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountInternalTimeout);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_INVALID_COUNT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountInvalidCount);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_INVALID_PARAMETERS:
|
||||
return getLocalizedString(R.string.TUIkitErrorSVRAccountINvalidParameters);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_ADMIN_REQUIRED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountAdminRequired);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_FREQ_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountFreqLimit);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_BLACKLIST:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountBlackList);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_COUNT_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountCountLimit);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_INTERNAL_ERROR:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountInternalError);
|
||||
case BaseConstants.ERR_SVR_ACCOUNT_USER_STATUS_DISABLED:
|
||||
return getLocalizedString(R.string.TUIKitErrorEnableUserStatusOnConsole);
|
||||
|
||||
// 资料错误码
|
||||
// Profile error codes
|
||||
case BaseConstants.ERR_SVR_PROFILE_INVALID_PARAMETERS:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRProfileInvalidParameters);
|
||||
case BaseConstants.ERR_SVR_PROFILE_ACCOUNT_MISS:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRProfileAccountMiss);
|
||||
case BaseConstants.ERR_SVR_PROFILE_ACCOUNT_NOT_FOUND:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRProfileAccountNotFound);
|
||||
case BaseConstants.ERR_SVR_PROFILE_ADMIN_REQUIRED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRProfileAdminRequired);
|
||||
case BaseConstants.ERR_SVR_PROFILE_SENSITIVE_TEXT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRProfileSensitiveText);
|
||||
case BaseConstants.ERR_SVR_PROFILE_INTERNAL_ERROR:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRProfileInternalError);
|
||||
case BaseConstants.ERR_SVR_PROFILE_READ_PERMISSION_REQUIRED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRProfileReadWritePermissionRequired);
|
||||
case BaseConstants.ERR_SVR_PROFILE_WRITE_PERMISSION_REQUIRED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRProfileReadWritePermissionRequired);
|
||||
case BaseConstants.ERR_SVR_PROFILE_TAG_NOT_FOUND:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRProfileTagNotFound);
|
||||
case BaseConstants.ERR_SVR_PROFILE_SIZE_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRProfileSizeLimit);
|
||||
case BaseConstants.ERR_SVR_PROFILE_VALUE_ERROR:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRProfileValueError);
|
||||
case BaseConstants.ERR_SVR_PROFILE_INVALID_VALUE_FORMAT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRProfileInvalidValueFormat);
|
||||
|
||||
// 关系链错误码
|
||||
// Relationship chain error codes
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_INVALID_PARAMETERS:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipInvalidParameters);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_INVALID_SDKAPPID:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipInvalidSdkAppid);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_ACCOUNT_NOT_FOUND:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipAccountNotFound);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_ADMIN_REQUIRED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipAdminRequired);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_SENSITIVE_TEXT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipSensitiveText);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_INTERNAL_ERROR:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountInternalError);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_NET_TIMEOUT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipNetTimeout);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_WRITE_CONFLICT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipWriteConflict);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_ADD_FRIEND_DENY:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipAddFriendDeny);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_COUNT_LIMIT:
|
||||
return getLocalizedString(R.string.TUIkitErrorSVRFriendshipCountLimit);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_GROUP_COUNT_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipGroupCountLimit);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_PENDENCY_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipPendencyLimit);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_BLACKLIST_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipBlacklistLimit);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_PEER_FRIEND_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipPeerFriendLimit);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_IN_SELF_BLACKLIST:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipInSelfBlacklist);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_ALLOW_TYPE_DENY_ANY:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipAllowTypeDenyAny);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_IN_PEER_BLACKLIST:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipInPeerBlackList);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_ALLOW_TYPE_NEED_CONFIRM:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipAllowTypeNeedConfirm);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_ADD_FRIEND_SEC_RSTR:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipAddFriendSecRstr);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_PENDENCY_NOT_FOUND:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipPendencyNotFound);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_DEL_FRIEND_SEC_RSTR:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipDelFriendSecRstr);
|
||||
case BaseConstants.ERR_SVR_FRIENDSHIP_ACCOUNT_NOT_FOUND_EX:
|
||||
return getLocalizedString(R.string.TUIKirErrorSVRFriendAccountNotFoundEx);
|
||||
|
||||
// 最近联系人错误码
|
||||
// Error codes for recent contacts
|
||||
case BaseConstants.ERR_SVR_CONV_ACCOUNT_NOT_FOUND:
|
||||
return getLocalizedString(R.string.TUIKirErrorSVRFriendAccountNotFoundEx);
|
||||
case BaseConstants.ERR_SVR_CONV_INVALID_PARAMETERS:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipInvalidParameters);
|
||||
case BaseConstants.ERR_SVR_CONV_ADMIN_REQUIRED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipAdminRequired);
|
||||
case BaseConstants.ERR_SVR_CONV_INTERNAL_ERROR:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountInternalError);
|
||||
case BaseConstants.ERR_SVR_CONV_NET_TIMEOUT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRFriendshipNetTimeout);
|
||||
|
||||
// 消息错误码
|
||||
// Message error codes
|
||||
case BaseConstants.ERR_SVR_MSG_PKG_PARSE_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgPkgParseFailed);
|
||||
case BaseConstants.ERR_SVR_MSG_INTERNAL_AUTH_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgInternalAuthFailed);
|
||||
case BaseConstants.ERR_SVR_MSG_INVALID_ID:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgInvalidId);
|
||||
case BaseConstants.ERR_SVR_MSG_NET_ERROR:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgNetError);
|
||||
case BaseConstants.ERR_SVR_MSG_INTERNAL_ERROR1:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountInternalError);
|
||||
case BaseConstants.ERR_SVR_MSG_PUSH_DENY:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgPushDeny);
|
||||
case BaseConstants.ERR_SVR_MSG_IN_PEER_BLACKLIST:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgInPeerBlackList);
|
||||
case BaseConstants.ERR_SVR_MSG_BOTH_NOT_FRIEND:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgBothNotFriend);
|
||||
case BaseConstants.ERR_SVR_MSG_NOT_PEER_FRIEND:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgNotPeerFriend);
|
||||
case BaseConstants.ERR_SVR_MSG_NOT_SELF_FRIEND:
|
||||
return getLocalizedString(R.string.TUIkitErrorSVRMsgNotSelfFriend);
|
||||
case BaseConstants.ERR_SVR_MSG_SHUTUP_DENY:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgShutupDeny);
|
||||
case BaseConstants.ERR_SVR_MSG_REVOKE_TIME_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgRevokeTimeLimit);
|
||||
case BaseConstants.ERR_SVR_MSG_DEL_RAMBLE_INTERNAL_ERROR:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgDelRambleInternalError);
|
||||
case BaseConstants.ERR_SVR_MSG_JSON_PARSE_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgJsonParseFailed);
|
||||
case BaseConstants.ERR_SVR_MSG_INVALID_JSON_BODY_FORMAT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgInvalidJsonBodyFormat);
|
||||
case BaseConstants.ERR_SVR_MSG_INVALID_TO_ACCOUNT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgInvalidToAccount);
|
||||
case BaseConstants.ERR_SVR_MSG_INVALID_RAND:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgInvalidRand);
|
||||
case BaseConstants.ERR_SVR_MSG_INVALID_TIMESTAMP:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgInvalidTimestamp);
|
||||
case BaseConstants.ERR_SVR_MSG_BODY_NOT_ARRAY:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgBodyNotArray);
|
||||
case BaseConstants.ERR_SVR_MSG_ADMIN_REQUIRED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountAdminRequired);
|
||||
case BaseConstants.ERR_SVR_MSG_INVALID_JSON_FORMAT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgInvalidJsonFormat);
|
||||
case BaseConstants.ERR_SVR_MSG_TO_ACCOUNT_COUNT_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgToAccountCountLimit);
|
||||
case BaseConstants.ERR_SVR_MSG_TO_ACCOUNT_NOT_FOUND:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgToAccountNotFound);
|
||||
case BaseConstants.ERR_SVR_MSG_TIME_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgTimeLimit);
|
||||
case BaseConstants.ERR_SVR_MSG_INVALID_SYNCOTHERMACHINE:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgInvalidSyncOtherMachine);
|
||||
case BaseConstants.ERR_SVR_MSG_INVALID_MSGLIFETIME:
|
||||
return getLocalizedString(R.string.TUIkitErrorSVRMsgInvalidMsgLifeTime);
|
||||
case BaseConstants.ERR_SVR_MSG_ACCOUNT_NOT_FOUND:
|
||||
return getLocalizedString(R.string.TUIKirErrorSVRFriendAccountNotFoundEx);
|
||||
case BaseConstants.ERR_SVR_MSG_INTERNAL_ERROR2:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountInternalError);
|
||||
case BaseConstants.ERR_SVR_MSG_INTERNAL_ERROR3:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountInternalError);
|
||||
case BaseConstants.ERR_SVR_MSG_INTERNAL_ERROR4:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountInternalError);
|
||||
case BaseConstants.ERR_SVR_MSG_INTERNAL_ERROR5:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountInternalError);
|
||||
case BaseConstants.ERR_SVR_MSG_BODY_SIZE_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRMsgBodySizeLimit);
|
||||
case BaseConstants.ERR_SVR_MSG_LONGPOLLING_COUNT_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRmsgLongPollingCountLimit);
|
||||
case BaseConstants.ERR_SDK_INTERFACE_NOT_SUPPORT:
|
||||
return getLocalizedString(R.string.TUIKitErrorUnsupporInterface);
|
||||
|
||||
// 群组错误码
|
||||
// Group error codes
|
||||
case BaseConstants.ERR_SVR_GROUP_INTERNAL_ERROR:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRAccountInternalError);
|
||||
case BaseConstants.ERR_SVR_GROUP_API_NAME_ERROR:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupApiNameError);
|
||||
case BaseConstants.ERR_SVR_GROUP_INVALID_PARAMETERS:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRResInvalidParameters);
|
||||
case BaseConstants.ERR_SVR_GROUP_ACOUNT_COUNT_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupAccountCountLimit);
|
||||
case BaseConstants.ERR_SVR_GROUP_FREQ_LIMIT:
|
||||
return getLocalizedString(R.string.TUIkitErrorSVRGroupFreqLimit);
|
||||
case BaseConstants.ERR_SVR_GROUP_PERMISSION_DENY:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupPermissionDeny);
|
||||
case BaseConstants.ERR_SVR_GROUP_INVALID_REQ:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupInvalidReq);
|
||||
case BaseConstants.ERR_SVR_GROUP_SUPER_NOT_ALLOW_QUIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupSuperNotAllowQuit);
|
||||
case BaseConstants.ERR_SVR_GROUP_NOT_FOUND:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupNotFound);
|
||||
case BaseConstants.ERR_SVR_GROUP_JSON_PARSE_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupJsonParseFailed);
|
||||
case BaseConstants.ERR_SVR_GROUP_INVALID_ID:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupInvalidId);
|
||||
case BaseConstants.ERR_SVR_GROUP_ALLREADY_MEMBER:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupAllreadyMember);
|
||||
case BaseConstants.ERR_SVR_GROUP_FULL_MEMBER_COUNT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupFullMemberCount);
|
||||
case BaseConstants.ERR_SVR_GROUP_INVALID_GROUPID:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupInvalidGroupId);
|
||||
case BaseConstants.ERR_SVR_GROUP_REJECT_FROM_THIRDPARTY:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupRejectFromThirdParty);
|
||||
case BaseConstants.ERR_SVR_GROUP_SHUTUP_DENY:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupShutDeny);
|
||||
case BaseConstants.ERR_SVR_GROUP_RSP_SIZE_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupRspSizeLimit);
|
||||
case BaseConstants.ERR_SVR_GROUP_ACCOUNT_NOT_FOUND:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupAccountNotFound);
|
||||
case BaseConstants.ERR_SVR_GROUP_GROUPID_IN_USED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupGroupIdInUse);
|
||||
case BaseConstants.ERR_SVR_GROUP_SEND_MSG_FREQ_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupSendMsgFreqLimit);
|
||||
case BaseConstants.ERR_SVR_GROUP_REQ_ALLREADY_BEEN_PROCESSED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupReqAllreadyBeenProcessed);
|
||||
case BaseConstants.ERR_SVR_GROUP_GROUPID_IN_USED_FOR_SUPER:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupGroupIdUserdForSuper);
|
||||
case BaseConstants.ERR_SVR_GROUP_SDKAPPID_DENY:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupSDkAppidDeny);
|
||||
case BaseConstants.ERR_SVR_GROUP_REVOKE_MSG_NOT_FOUND:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupRevokeMsgNotFound);
|
||||
case BaseConstants.ERR_SVR_GROUP_REVOKE_MSG_TIME_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupRevokeMsgTimeLimit);
|
||||
case BaseConstants.ERR_SVR_GROUP_REVOKE_MSG_DENY:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupRevokeMsgDeny);
|
||||
case BaseConstants.ERR_SVR_GROUP_NOT_ALLOW_REVOKE_MSG:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupNotAllowRevokeMsg);
|
||||
case BaseConstants.ERR_SVR_GROUP_REMOVE_MSG_DENY:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupRemoveMsgDeny);
|
||||
case BaseConstants.ERR_SVR_GROUP_NOT_ALLOW_REMOVE_MSG:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupNotAllowRemoveMsg);
|
||||
case BaseConstants.ERR_SVR_GROUP_AVCHATROOM_COUNT_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupAvchatRoomCountLimit);
|
||||
case BaseConstants.ERR_SVR_GROUP_COUNT_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupCountLimit);
|
||||
case BaseConstants.ERR_SVR_GROUP_MEMBER_COUNT_LIMIT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRGroupMemberCountLimit);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (三)V3版本错误码,待废弃
|
||||
// IM SDK V3 error codes,to be abandoned
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
case BaseConstants.ERR_NO_SUCC_RESULT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRNoSuccessResult);
|
||||
case BaseConstants.ERR_TO_USER_INVALID:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRToUserInvalid);
|
||||
case BaseConstants.ERR_INIT_CORE_FAIL:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRInitCoreFail);
|
||||
case BaseConstants.ERR_EXPIRED_SESSION_NODE:
|
||||
return getLocalizedString(R.string.TUIKitErrorExpiredSessionNode);
|
||||
case BaseConstants.ERR_LOGGED_OUT_BEFORE_LOGIN_FINISHED:
|
||||
return getLocalizedString(R.string.TUIKitErrorLoggedOutBeforeLoginFinished);
|
||||
case BaseConstants.ERR_TLSSDK_NOT_INITIALIZED:
|
||||
return getLocalizedString(R.string.TUIKitErrorTLSSDKNotInitialized);
|
||||
case BaseConstants.ERR_TLSSDK_USER_NOT_FOUND:
|
||||
return getLocalizedString(R.string.TUIKitErrorTLSSDKUserNotFound);
|
||||
// case BaseConstants.ERR_BIND_FAIL_UNKNOWN:
|
||||
// return @"QALSDK未知原因BIND失败";
|
||||
// case BaseConstants.ERR_BIND_FAIL_NO_SSOTICKET:
|
||||
// return @"缺少SSO票据";
|
||||
// case BaseConstants.ERR_BIND_FAIL_REPEATD_BIND:
|
||||
// return @"重复BIND";
|
||||
// case BaseConstants.ERR_BIND_FAIL_TINYID_NULL:
|
||||
// return @"tiny为空";
|
||||
// case BaseConstants.ERR_BIND_FAIL_GUID_NULL:
|
||||
// return @"guid为空";
|
||||
// case BaseConstants.ERR_BIND_FAIL_UNPACK_REGPACK_FAILED:
|
||||
// return @"解注册包失败";
|
||||
case BaseConstants.ERR_BIND_FAIL_REG_TIMEOUT:
|
||||
return getLocalizedString(R.string.TUIKitErrorBindFaildRegTimeout);
|
||||
case BaseConstants.ERR_BIND_FAIL_ISBINDING:
|
||||
return getLocalizedString(R.string.TUIKitErrorBindFaildIsBinding);
|
||||
case BaseConstants.ERR_PACKET_FAIL_UNKNOWN:
|
||||
return getLocalizedString(R.string.TUIKitErrorPacketFailUnknown);
|
||||
case BaseConstants.ERR_PACKET_FAIL_REQ_NO_NET:
|
||||
return getLocalizedString(R.string.TUIKitErrorPacketFailReqNoNet);
|
||||
case BaseConstants.ERR_PACKET_FAIL_RESP_NO_NET:
|
||||
return getLocalizedString(R.string.TUIKitErrorPacketFailRespNoNet);
|
||||
case BaseConstants.ERR_PACKET_FAIL_REQ_NO_AUTH:
|
||||
return getLocalizedString(R.string.TUIKitErrorPacketFailReqNoAuth);
|
||||
case BaseConstants.ERR_PACKET_FAIL_SSO_ERR:
|
||||
return getLocalizedString(R.string.TUIKitErrorPacketFailSSOErr);
|
||||
case BaseConstants.ERR_PACKET_FAIL_REQ_TIMEOUT:
|
||||
return getLocalizedString(R.string.TUIKitErrorSVRRequestTimeout);
|
||||
case BaseConstants.ERR_PACKET_FAIL_RESP_TIMEOUT:
|
||||
return getLocalizedString(R.string.TUIKitErrorPacketFailRespTimeout);
|
||||
|
||||
// case BaseConstants.ERR_PACKET_FAIL_REQ_ON_RESEND:
|
||||
// case BaseConstants.ERR_PACKET_FAIL_RESP_NO_RESEND:
|
||||
// case BaseConstants.ERR_PACKET_FAIL_FLOW_SAVE_FILTERED:
|
||||
// case BaseConstants.ERR_PACKET_FAIL_REQ_OVER_LOAD:
|
||||
// case BaseConstants.ERR_PACKET_FAIL_LOGIC_ERR:
|
||||
case BaseConstants.ERR_FRIENDSHIP_PROXY_NOT_SYNCED:
|
||||
return getLocalizedString(R.string.TUIKitErrorFriendshipProxySyncing);
|
||||
case BaseConstants.ERR_FRIENDSHIP_PROXY_SYNCING:
|
||||
return getLocalizedString(R.string.TUIKitErrorFriendshipProxySyncing);
|
||||
case BaseConstants.ERR_FRIENDSHIP_PROXY_SYNCED_FAIL:
|
||||
return getLocalizedString(R.string.TUIKitErrorFriendshipProxySyncedFail);
|
||||
case BaseConstants.ERR_FRIENDSHIP_PROXY_LOCAL_CHECK_ERR:
|
||||
return getLocalizedString(R.string.TUIKitErrorFriendshipProxyLocalCheckErr);
|
||||
case BaseConstants.ERR_GROUP_INVALID_FIELD:
|
||||
return getLocalizedString(R.string.TUIKitErrorGroupInvalidField);
|
||||
case BaseConstants.ERR_GROUP_STORAGE_DISABLED:
|
||||
return getLocalizedString(R.string.TUIKitErrorGroupStoreageDisabled);
|
||||
case BaseConstants.ERR_LOADGRPINFO_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorLoadGrpInfoFailed);
|
||||
case BaseConstants.ERR_REQ_NO_NET_ON_REQ:
|
||||
return getLocalizedString(R.string.TUIKitErrorReqNoNetOnReq);
|
||||
case BaseConstants.ERR_REQ_NO_NET_ON_RSP:
|
||||
return getLocalizedString(R.string.TUIKitErrorReqNoNetOnResp);
|
||||
case BaseConstants.ERR_SERIVCE_NOT_READY:
|
||||
return getLocalizedString(R.string.TUIKitErrorServiceNotReady);
|
||||
case BaseConstants.ERR_LOGIN_AUTH_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorLoginAuthFailed);
|
||||
case BaseConstants.ERR_NEVER_CONNECT_AFTER_LAUNCH:
|
||||
return getLocalizedString(R.string.TUIKitErrorNeverConnectAfterLaunch);
|
||||
case BaseConstants.ERR_REQ_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorReqFailed);
|
||||
case BaseConstants.ERR_REQ_INVALID_REQ:
|
||||
return getLocalizedString(R.string.TUIKitErrorReqInvaidReq);
|
||||
case BaseConstants.ERR_REQ_OVERLOADED:
|
||||
return getLocalizedString(R.string.TUIKitErrorReqOnverLoaded);
|
||||
case BaseConstants.ERR_REQ_KICK_OFF:
|
||||
return getLocalizedString(R.string.TUIKitErrorReqKickOff);
|
||||
case BaseConstants.ERR_REQ_SERVICE_SUSPEND:
|
||||
return getLocalizedString(R.string.TUIKitErrorReqServiceSuspend);
|
||||
case BaseConstants.ERR_REQ_INVALID_SIGN:
|
||||
return getLocalizedString(R.string.TUIKitErrorReqInvalidSign);
|
||||
case BaseConstants.ERR_REQ_INVALID_COOKIE:
|
||||
return getLocalizedString(R.string.TUIKitErrorReqInvalidCookie);
|
||||
case BaseConstants.ERR_LOGIN_TLS_RSP_PARSE_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorLoginTlsRspParseFailed);
|
||||
case BaseConstants.ERR_LOGIN_OPENMSG_TIMEOUT:
|
||||
return getLocalizedString(R.string.TUIKitErrorLoginOpenMsgTimeout);
|
||||
case BaseConstants.ERR_LOGIN_OPENMSG_RSP_PARSE_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorLoginOpenMsgRspParseFailed);
|
||||
case BaseConstants.ERR_LOGIN_TLS_DECRYPT_FAILED:
|
||||
return getLocalizedString(R.string.TUIKitErrorLoginTslDecryptFailed);
|
||||
case BaseConstants.ERR_WIFI_NEED_AUTH:
|
||||
return getLocalizedString(R.string.TUIKitErrorWifiNeedAuth);
|
||||
case BaseConstants.ERR_USER_CANCELED:
|
||||
return getLocalizedString(R.string.TUIKitErrorUserCanceled);
|
||||
case BaseConstants.ERR_REVOKE_TIME_LIMIT_EXCEED:
|
||||
return getLocalizedString(R.string.TUIkitErrorRevokeTimeLimitExceed);
|
||||
case BaseConstants.ERR_LACK_UGC_EXT:
|
||||
return getLocalizedString(R.string.TUIKitErrorLackUGExt);
|
||||
case BaseConstants.ERR_AUTOLOGIN_NEED_USERSIG:
|
||||
return getLocalizedString(R.string.TUIKitErrorAutoLoginNeedUserSig);
|
||||
case BaseConstants.ERR_QAL_NO_SHORT_CONN_AVAILABLE:
|
||||
return getLocalizedString(R.string.TUIKitErrorQALNoShortConneAvailable);
|
||||
case BaseConstants.ERR_REQ_CONTENT_ATTACK:
|
||||
return getLocalizedString(R.string.TUIKitErrorReqContentAttach);
|
||||
case BaseConstants.ERR_LOGIN_SIG_EXPIRE:
|
||||
return getLocalizedString(R.string.TUIKitErrorLoginSigExpire);
|
||||
case BaseConstants.ERR_SDK_HAD_INITIALIZED:
|
||||
return getLocalizedString(R.string.TUIKitErrorSDKHadInit);
|
||||
case BaseConstants.ERR_OPENBDH_BASE:
|
||||
return getLocalizedString(R.string.TUIKitErrorOpenBDHBase);
|
||||
case BaseConstants.ERR_REQUEST_NO_NET_ONREQ:
|
||||
return getLocalizedString(R.string.TUIKitErrorRequestNoNetOnReq);
|
||||
case BaseConstants.ERR_REQUEST_NO_NET_ONRSP:
|
||||
return getLocalizedString(R.string.TUIKitErrorRequestNoNetOnRsp);
|
||||
// case BaseConstants.ERR_REQUEST_FAILED:
|
||||
// return @"QAL执行失败";
|
||||
// case BaseConstants.ERR_REQUEST_INVALID_REQ:
|
||||
// return @"请求非法,toMsgService非法";
|
||||
case BaseConstants.ERR_REQUEST_OVERLOADED:
|
||||
return getLocalizedString(R.string.TUIKitErrorRequestOnverLoaded);
|
||||
case BaseConstants.ERR_REQUEST_KICK_OFF:
|
||||
return getLocalizedString(R.string.TUIKitErrorReqKickOff);
|
||||
case BaseConstants.ERR_REQUEST_SERVICE_SUSPEND:
|
||||
return getLocalizedString(R.string.TUIKitErrorReqServiceSuspend);
|
||||
case BaseConstants.ERR_REQUEST_INVALID_SIGN:
|
||||
return getLocalizedString(R.string.TUIKitErrorReqInvalidSign);
|
||||
case BaseConstants.ERR_REQUEST_INVALID_COOKIE:
|
||||
return getLocalizedString(R.string.TUIKitErrorReqInvalidCookie);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
private static String getLocalizedString(int errStringId) {
|
||||
return TUIConfig.getAppContext().getString(errStringId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,497 @@
|
||||
package com.tencent.qcloud.tuicore.util;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentUris;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.provider.MediaStore;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
import com.tencent.qcloud.tuicore.TUIConfig;
|
||||
import com.tencent.qcloud.tuicore.TUILogin;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
public class FileUtil {
|
||||
|
||||
public static final String DOCUMENTS_DIR = "documents";
|
||||
|
||||
public static final int SIZETYPE_B = 1;
|
||||
public static final int SIZETYPE_KB = 2;
|
||||
public static final int SIZETYPE_MB = 3;
|
||||
public static final int SIZETYPE_GB = 4;
|
||||
|
||||
public static String saveBitmap(String dir, Bitmap b) {
|
||||
String jpegName = TUIConfig.getMediaDir() + "picture_" + new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()) + ".jpg";
|
||||
try {
|
||||
FileOutputStream fout = new FileOutputStream(jpegName);
|
||||
BufferedOutputStream bos = new BufferedOutputStream(fout);
|
||||
b.compress(Bitmap.CompressFormat.JPEG, 100, bos);
|
||||
bos.flush();
|
||||
bos.close();
|
||||
return jpegName;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean deleteFile(String url) {
|
||||
boolean result = false;
|
||||
File file = new File(url);
|
||||
if (file.exists()) {
|
||||
result = file.delete();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String getPathFromUri(Uri uri) {
|
||||
String path = "";
|
||||
try {
|
||||
int sdkVersion = Build.VERSION.SDK_INT;
|
||||
if (sdkVersion >= 19) {
|
||||
path = getPathByCopyFile(TUILogin.getAppContext(), uri);
|
||||
} else {
|
||||
path = getRealFilePath(uri);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (path == null) {
|
||||
path = "";
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
public static String getRealFilePath(Uri uri) {
|
||||
if (null == uri) {
|
||||
return null;
|
||||
}
|
||||
final String scheme = uri.getScheme();
|
||||
String data = null;
|
||||
if (scheme == null) {
|
||||
data = uri.getPath();
|
||||
} else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
|
||||
data = uri.getPath();
|
||||
} else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
|
||||
Cursor cursor = TUILogin.getAppContext().getContentResolver().query(uri, new String[]{MediaStore.Images.ImageColumns.DATA}, null, null, null);
|
||||
if (null != cursor) {
|
||||
if (cursor.moveToFirst()) {
|
||||
int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
|
||||
if (index > -1) {
|
||||
data = cursor.getString(index);
|
||||
}
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public static Uri getUriFromPath(String path) {
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
return TUIFileProvider.getUriForFile(TUIConfig.getAppContext(), TUIConfig.getAppContext().getApplicationInfo().packageName + ".tuicore.fileprovider", new File(path));
|
||||
} else {
|
||||
return Uri.fromFile(new File(path));
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 专为Android4.4以上设计的从Uri获取文件路径
|
||||
*
|
||||
* Get file path from Uri specially designed for Android4.4 and above
|
||||
*/
|
||||
public static String getPath(final Context context, final Uri uri) {
|
||||
|
||||
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
|
||||
|
||||
// DocumentProvider
|
||||
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
|
||||
// ExternalStorageProvider
|
||||
if (isExternalStorageDocument(uri)) {
|
||||
|
||||
final String docId = DocumentsContract.getDocumentId(uri);
|
||||
final String[] split = docId.split(":");
|
||||
final String type = split[0];
|
||||
|
||||
if ("primary".equalsIgnoreCase(type)) {
|
||||
return Environment.getExternalStorageDirectory() + "/" + split[1];
|
||||
} else {
|
||||
return getPathByCopyFile(context, uri);
|
||||
}
|
||||
}
|
||||
// DownloadsProvider
|
||||
else if (isDownloadsDocument(uri)) {
|
||||
|
||||
final String id = DocumentsContract.getDocumentId(uri);
|
||||
if (id.startsWith("raw:")) {
|
||||
final String path = id.replaceFirst("raw:", "");
|
||||
return path;
|
||||
}
|
||||
String[] contentUriPrefixesToTry = new String[]{
|
||||
"content://downloads/public_downloads",
|
||||
"content://downloads/my_downloads",
|
||||
"content://downloads/all_downloads"
|
||||
};
|
||||
|
||||
for (String contentUriPrefix : contentUriPrefixesToTry) {
|
||||
Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.parseLong(id));
|
||||
try {
|
||||
String path = getDataColumn(context, contentUri, null, null);
|
||||
if (path != null && Build.VERSION.SDK_INT < 29) {
|
||||
return path;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// 在某些android8+的手机上,无法获取路径,所以用拷贝的方式,获取新文件名,然后把文件发出去
|
||||
// On some android8+ mobile phones, the path cannot be obtained, so the new file name is obtained by copying, and then the file is sent out
|
||||
return getPathByCopyFile(context, uri);
|
||||
}
|
||||
// MediaProvider
|
||||
else if (isMediaDocument(uri)) {
|
||||
|
||||
final String docId = DocumentsContract.getDocumentId(uri);
|
||||
final String[] split = docId.split(":");
|
||||
final String type = split[0];
|
||||
|
||||
Uri contentUri = null;
|
||||
if ("image".equals(type)) {
|
||||
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||
} else if ("video".equals(type)) {
|
||||
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
||||
} else if ("audio".equals(type)) {
|
||||
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
||||
}
|
||||
|
||||
final String selection = "_id=?";
|
||||
final String[] selectionArgs = new String[]{split[1]};
|
||||
|
||||
String path = getDataColumn(context, contentUri, selection, selectionArgs);
|
||||
if (TextUtils.isEmpty(path) || Build.VERSION.SDK_INT >= 29) {
|
||||
path = getPathByCopyFile(context, uri);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
}
|
||||
// MediaStore (and general)
|
||||
else if ("content".equalsIgnoreCase(uri.getScheme())) {
|
||||
String path = getDataColumn(context, uri, null, null);
|
||||
if (TextUtils.isEmpty(path) || Build.VERSION.SDK_INT >= 29) {
|
||||
// 在某些华为android9+的手机上,无法获取路径,所以用拷贝的方式,获取新文件名,然后把文件发出去
|
||||
path = getPathByCopyFile(context, uri);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
// File
|
||||
else if ("file".equalsIgnoreCase(uri.getScheme())) {
|
||||
return uri.getPath();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getPathByCopyFile(Context context, Uri uri) {
|
||||
String fileName = getFileName(context, uri);
|
||||
File cacheDir = getDocumentCacheDir(context);
|
||||
File file = generateFileName(fileName, cacheDir);
|
||||
String destinationPath = null;
|
||||
if (file != null) {
|
||||
destinationPath = file.getAbsolutePath();
|
||||
boolean saveSuccess = saveFileFromUri(context, uri, destinationPath);
|
||||
if (!saveSuccess) {
|
||||
file.delete();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return destinationPath;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File generateFileName(@Nullable String name, File directory) {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
File file = new File(directory, name);
|
||||
|
||||
if (file.exists()) {
|
||||
String fileName = name;
|
||||
String extension = "";
|
||||
int dotIndex = name.lastIndexOf('.');
|
||||
if (dotIndex > 0) {
|
||||
fileName = name.substring(0, dotIndex);
|
||||
extension = name.substring(dotIndex);
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
|
||||
while (file.exists()) {
|
||||
index++;
|
||||
name = fileName + '(' + index + ')' + extension;
|
||||
file = new File(directory, name);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (!file.createNewFile()) {
|
||||
return null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
public static String getFileName(@NonNull Context context, Uri uri) {
|
||||
String mimeType = context.getContentResolver().getType(uri);
|
||||
String filename = null;
|
||||
|
||||
if (mimeType == null && context != null) {
|
||||
filename = getName(uri.toString());
|
||||
} else {
|
||||
Cursor returnCursor = context.getContentResolver().query(uri, null,
|
||||
null, null, null);
|
||||
if (returnCursor != null) {
|
||||
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
|
||||
returnCursor.moveToFirst();
|
||||
filename = returnCursor.getString(nameIndex);
|
||||
returnCursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
private static String getName(String filename) {
|
||||
if (filename == null) {
|
||||
return null;
|
||||
}
|
||||
int index = filename.lastIndexOf('/');
|
||||
return filename.substring(index + 1);
|
||||
}
|
||||
|
||||
public static File getDocumentCacheDir(@NonNull Context context) {
|
||||
File dir = new File(context.getCacheDir(), DOCUMENTS_DIR);
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
private static boolean saveFileFromUri(Context context, Uri uri, String destinationPath) {
|
||||
InputStream is = null;
|
||||
BufferedOutputStream bos = null;
|
||||
try {
|
||||
is = context.getContentResolver().openInputStream(uri);
|
||||
bos = new BufferedOutputStream(new FileOutputStream(destinationPath, false));
|
||||
byte[] buf = new byte[1024];
|
||||
|
||||
int actualBytes;
|
||||
while ((actualBytes = is.read(buf)) != -1) {
|
||||
bos.write(buf, 0, actualBytes);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
} finally {
|
||||
try {
|
||||
if (is != null) is.close();
|
||||
if (bos != null) bos.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the data column for this Uri. This is useful for
|
||||
* MediaStore Uris, and other file-based ContentProviders.
|
||||
*
|
||||
* @param context The context.
|
||||
* @param uri The Uri to query.
|
||||
* @param selection (Optional) Filter used in the query.
|
||||
* @param selectionArgs (Optional) Selection arguments used in the query.
|
||||
* @return The value of the _data column, which is typically a file path.
|
||||
*/
|
||||
public static String getDataColumn(Context context, Uri uri, String selection,
|
||||
String[] selectionArgs) {
|
||||
|
||||
Cursor cursor = null;
|
||||
final String column = "_data";
|
||||
final String[] projection = {column};
|
||||
|
||||
try {
|
||||
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
|
||||
null);
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
final int column_index = cursor.getColumnIndexOrThrow(column);
|
||||
return cursor.getString(column_index);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uri The Uri to check.
|
||||
* @return Whether the Uri authority is ExternalStorageProvider.
|
||||
*/
|
||||
public static boolean isExternalStorageDocument(Uri uri) {
|
||||
return "com.android.externalstorage.documents".equals(uri.getAuthority());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uri The Uri to check.
|
||||
* @return Whether the Uri authority is DownloadsProvider.
|
||||
*/
|
||||
public static boolean isDownloadsDocument(Uri uri) {
|
||||
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uri The Uri to check.
|
||||
* @return Whether the Uri authority is MediaProvider.
|
||||
*/
|
||||
public static boolean isMediaDocument(Uri uri) {
|
||||
return "com.android.providers.media.documents".equals(uri.getAuthority());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 转换文件大小
|
||||
*
|
||||
* Convert file size to string
|
||||
*
|
||||
* @param fileS
|
||||
* @return
|
||||
*/
|
||||
public static String formatFileSize(long fileS) {
|
||||
DecimalFormat df = new DecimalFormat("#.00");
|
||||
String fileSizeString = "";
|
||||
String wrongSize = "0B";
|
||||
if (fileS == 0) {
|
||||
return wrongSize;
|
||||
}
|
||||
if (fileS < 1024) {
|
||||
fileSizeString = df.format((double) fileS) + "B";
|
||||
} else if (fileS < 1048576) {
|
||||
fileSizeString = df.format((double) fileS / 1024) + "KB";
|
||||
} else if (fileS < 1073741824) {
|
||||
fileSizeString = df.format((double) fileS / 1048576) + "MB";
|
||||
} else {
|
||||
fileSizeString = df.format((double) fileS / 1073741824) + "GB";
|
||||
}
|
||||
return fileSizeString;
|
||||
}
|
||||
|
||||
|
||||
// 修复 android.webkit.MimeTypeMap 的 getFileExtensionFromUrl 方法不支持中文的问题
|
||||
// fix the problem that getFileExtensionFromUrl does not support Chinese
|
||||
public static String getFileExtensionFromUrl(String url) {
|
||||
if (!TextUtils.isEmpty(url)) {
|
||||
int fragment = url.lastIndexOf('#');
|
||||
if (fragment > 0) {
|
||||
url = url.substring(0, fragment);
|
||||
}
|
||||
|
||||
int query = url.lastIndexOf('?');
|
||||
if (query > 0) {
|
||||
url = url.substring(0, query);
|
||||
}
|
||||
|
||||
int filenamePos = url.lastIndexOf('/');
|
||||
String filename =
|
||||
0 <= filenamePos ? url.substring(filenamePos + 1) : url;
|
||||
|
||||
// if the filename contains special characters, we don't
|
||||
// consider it valid for our matching purposes:
|
||||
// 去掉正则表达式判断以添加中文支持
|
||||
// if (!filename.isEmpty() && Pattern.matches("[a-zA-Z_0-9\\.\\-\\(\\)\\%]+", filename))
|
||||
if (!filename.isEmpty()) {
|
||||
int dotPos = filename.lastIndexOf('.');
|
||||
if (0 <= dotPos) {
|
||||
return filename.substring(dotPos + 1).toLowerCase();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static void openFile(String path, String fileName) {
|
||||
Uri uri = TUIFileProvider.getUriForFile(TUIConfig.getAppContext(),
|
||||
TUIConfig.getAppContext().getApplicationInfo().packageName + ".tuicore.fileprovider",
|
||||
new File(path));
|
||||
if (uri == null) {
|
||||
Log.e("FileUtil", "openFile failed , uri is null");
|
||||
return;
|
||||
}
|
||||
String fileExtension;
|
||||
if (TextUtils.isEmpty(fileName)) {
|
||||
fileExtension = FileUtil.getFileExtensionFromUrl(path);
|
||||
} else {
|
||||
fileExtension = FileUtil.getFileExtensionFromUrl(fileName);
|
||||
}
|
||||
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
intent.setDataAndType(uri, mimeType);
|
||||
try {
|
||||
Intent chooserIntent = Intent.createChooser(intent, TUIConfig.getAppContext().getString(R.string.open_file_tips));
|
||||
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
TUIConfig.getAppContext().startActivity(chooserIntent);
|
||||
} catch (Exception e) {
|
||||
Log.e("FileUtil", "openFile failed , " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static long getFileSize(String path) {
|
||||
File file = new File(path);
|
||||
if (file.exists()) {
|
||||
return file.length();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,464 @@
|
||||
package com.tencent.qcloud.tuicore.util;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.media.ExifInterface;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.tencent.qcloud.tuicore.TUIConfig;
|
||||
import com.tencent.qcloud.tuicore.TUILogin;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
|
||||
public class ImageUtil {
|
||||
public final static String SP_IMAGE = "_conversation_group_face";
|
||||
|
||||
/**
|
||||
* @param outFile
|
||||
* @param bitmap
|
||||
* @return
|
||||
*/
|
||||
public static File storeBitmap(File outFile, Bitmap bitmap) {
|
||||
if (!outFile.exists() || outFile.isDirectory()) {
|
||||
outFile.getParentFile().mkdirs();
|
||||
}
|
||||
FileOutputStream fOut = null;
|
||||
try {
|
||||
outFile.deleteOnExit();
|
||||
outFile.createNewFile();
|
||||
fOut = new FileOutputStream(outFile);
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
|
||||
fOut.flush();
|
||||
} catch (IOException e1) {
|
||||
outFile.deleteOnExit();
|
||||
} finally {
|
||||
if (null != fOut) {
|
||||
try {
|
||||
fOut.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
outFile.deleteOnExit();
|
||||
}
|
||||
}
|
||||
}
|
||||
return outFile;
|
||||
}
|
||||
|
||||
public static Bitmap getBitmapFormPath(Uri uri) {
|
||||
Bitmap bitmap = null;
|
||||
try {
|
||||
InputStream input = TUIConfig.getAppContext().getContentResolver().openInputStream(uri);
|
||||
BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
|
||||
onlyBoundsOptions.inJustDecodeBounds = true;
|
||||
onlyBoundsOptions.inDither = true;//optional
|
||||
onlyBoundsOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optional
|
||||
BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
|
||||
input.close();
|
||||
int originalWidth = onlyBoundsOptions.outWidth;
|
||||
int originalHeight = onlyBoundsOptions.outHeight;
|
||||
if ((originalWidth == -1) || (originalHeight == -1))
|
||||
return null;
|
||||
float hh = 800f;
|
||||
float ww = 480f;
|
||||
int degree = getBitmapDegree(uri);
|
||||
if (degree == 90 || degree == 270) {
|
||||
hh = 480;
|
||||
ww = 800;
|
||||
}
|
||||
// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
|
||||
// zoom ratio. Since it is a fixed scale scaling, only one data of height or width can be used for calculation.
|
||||
int be = 1;
|
||||
if (originalWidth > originalHeight && originalWidth > ww) {
|
||||
be = (int) (originalWidth / ww);
|
||||
} else if (originalWidth < originalHeight && originalHeight > hh) {
|
||||
be = (int) (originalHeight / hh);
|
||||
}
|
||||
if (be <= 0)
|
||||
be = 1;
|
||||
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
|
||||
bitmapOptions.inSampleSize = be;
|
||||
bitmapOptions.inDither = true;
|
||||
bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
|
||||
input = TUIConfig.getAppContext().getContentResolver().openInputStream(uri);
|
||||
bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
|
||||
|
||||
input.close();
|
||||
compressImage(bitmap);
|
||||
bitmap = rotateBitmapByDegree(bitmap, degree);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public static Bitmap getBitmapFormPath(String path) {
|
||||
if (TextUtils.isEmpty(path)) {
|
||||
return null;
|
||||
}
|
||||
return getBitmapFormPath(Uri.fromFile(new File(path)));
|
||||
}
|
||||
|
||||
public static Bitmap compressImage(Bitmap image) {
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
|
||||
int options = 100;
|
||||
while (baos.toByteArray().length / 1024 > 100) {
|
||||
baos.reset();
|
||||
image.compress(Bitmap.CompressFormat.JPEG, options, baos);
|
||||
options -= 10;
|
||||
}
|
||||
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
|
||||
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取图片的旋转的角度
|
||||
*
|
||||
* Read the rotation angle of the image
|
||||
*/
|
||||
public static int getBitmapDegree(Uri uri) {
|
||||
int degree = 0;
|
||||
try {
|
||||
ExifInterface exifInterface = new ExifInterface(FileUtil.getPathFromUri(uri));
|
||||
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
|
||||
ExifInterface.ORIENTATION_NORMAL);
|
||||
switch (orientation) {
|
||||
case ExifInterface.ORIENTATION_ROTATE_90:
|
||||
degree = 90;
|
||||
break;
|
||||
case ExifInterface.ORIENTATION_ROTATE_180:
|
||||
degree = 180;
|
||||
break;
|
||||
case ExifInterface.ORIENTATION_ROTATE_270:
|
||||
degree = 270;
|
||||
break;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return degree;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取图片的旋转的角度
|
||||
*
|
||||
* Read the rotation angle of the image
|
||||
*/
|
||||
public static int getBitmapDegree(String fileName) {
|
||||
int degree = 0;
|
||||
try {
|
||||
ExifInterface exifInterface = new ExifInterface(fileName);
|
||||
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
|
||||
ExifInterface.ORIENTATION_NORMAL);
|
||||
switch (orientation) {
|
||||
case ExifInterface.ORIENTATION_ROTATE_90:
|
||||
degree = 90;
|
||||
break;
|
||||
case ExifInterface.ORIENTATION_ROTATE_180:
|
||||
degree = 180;
|
||||
break;
|
||||
case ExifInterface.ORIENTATION_ROTATE_270:
|
||||
degree = 270;
|
||||
break;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return degree;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将图片按照某个角度进行旋转
|
||||
*
|
||||
* @param bm 需要旋转的图片
|
||||
* @param degree 旋转角度
|
||||
* @return 旋转后的图片
|
||||
*
|
||||
*
|
||||
* Rotate the image by an angle
|
||||
*
|
||||
* @param bm image to be rotated
|
||||
* @param degree Rotation angle
|
||||
* @return rotated image
|
||||
*/
|
||||
public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {
|
||||
Bitmap returnBm = null;
|
||||
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postRotate(degree);
|
||||
try {
|
||||
returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
|
||||
} catch (OutOfMemoryError e) {
|
||||
}
|
||||
if (returnBm == null) {
|
||||
returnBm = bm;
|
||||
}
|
||||
if (bm != returnBm) {
|
||||
bm.recycle();
|
||||
}
|
||||
return returnBm;
|
||||
}
|
||||
|
||||
public static int[] getImageSize(String path) {
|
||||
int size[] = new int[2];
|
||||
try {
|
||||
BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
|
||||
onlyBoundsOptions.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(path, onlyBoundsOptions);
|
||||
int originalWidth = onlyBoundsOptions.outWidth;
|
||||
int originalHeight = onlyBoundsOptions.outHeight;
|
||||
//size[0] = originalWidth;
|
||||
//size[1] = originalHeight;
|
||||
|
||||
int degree = getBitmapDegree(path);
|
||||
if (degree == 0) {
|
||||
size[0] = originalWidth;
|
||||
size[1] = originalHeight;
|
||||
} else {
|
||||
float hh = 800f;
|
||||
float ww = 480f;
|
||||
if (degree == 90 || degree == 270) {
|
||||
hh = 480;
|
||||
ww = 800;
|
||||
}
|
||||
int be = 1;
|
||||
if (originalWidth > originalHeight && originalWidth > ww) {
|
||||
be = (int) (originalWidth / ww);
|
||||
} else if (originalWidth < originalHeight && originalHeight > hh) {
|
||||
be = (int) (originalHeight / hh);
|
||||
}
|
||||
if (be <= 0)
|
||||
be = 1;
|
||||
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
|
||||
bitmapOptions.inSampleSize = be;
|
||||
bitmapOptions.inDither = true;
|
||||
bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
|
||||
Bitmap bitmap = BitmapFactory.decodeFile(path, bitmapOptions);
|
||||
bitmap = rotateBitmapByDegree(bitmap, degree);
|
||||
size[0] = bitmap.getWidth();
|
||||
size[1] = bitmap.getHeight();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return size;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 图片文件先在本地做旋转,返回旋转之后的图片文件路径
|
||||
// The image file is rotated locally, and the path of the image file after rotation is returned.
|
||||
public static String getImagePathAfterRotate(final Uri uri) {
|
||||
try {
|
||||
InputStream is = TUIConfig.getAppContext().getContentResolver()
|
||||
.openInputStream(uri);
|
||||
Bitmap originBitmap = BitmapFactory.decodeStream(is, null, null);
|
||||
int degree = ImageUtil.getBitmapDegree(uri);
|
||||
if (degree == 0) {
|
||||
return FileUtil.getPathFromUri(uri);
|
||||
} else {
|
||||
Bitmap newBitmap = ImageUtil.rotateBitmapByDegree(originBitmap, degree);
|
||||
String oldName = FileUtil.getFileName(TUIConfig.getAppContext(), uri);
|
||||
File newImageFile = FileUtil.generateFileName(oldName, FileUtil.getDocumentCacheDir(TUIConfig.getAppContext()));
|
||||
if (newImageFile == null) {
|
||||
return FileUtil.getPathFromUri(uri);
|
||||
}
|
||||
ImageUtil.storeBitmap(newImageFile, newBitmap);
|
||||
newBitmap.recycle();
|
||||
return newImageFile.getAbsolutePath();
|
||||
}
|
||||
}catch (FileNotFoundException e) {
|
||||
return FileUtil.getPathFromUri(uri);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换图片成圆形
|
||||
*
|
||||
* @param bitmap 传入Bitmap对象
|
||||
* @return
|
||||
*
|
||||
*
|
||||
* Convert image to circle
|
||||
*
|
||||
* @param bitmap Pass in a Bitmap object
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap toRoundBitmap(Bitmap bitmap) {
|
||||
int width = bitmap.getWidth();
|
||||
int height = bitmap.getHeight();
|
||||
float roundPx;
|
||||
float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;
|
||||
if (width <= height) {
|
||||
roundPx = width / 2;
|
||||
left = 0;
|
||||
top = 0;
|
||||
right = width;
|
||||
bottom = width;
|
||||
height = width;
|
||||
dst_left = 0;
|
||||
dst_top = 0;
|
||||
dst_right = width;
|
||||
dst_bottom = width;
|
||||
} else {
|
||||
roundPx = height / 2;
|
||||
float clip = (width - height) / 2;
|
||||
left = clip;
|
||||
right = width - clip;
|
||||
top = 0;
|
||||
bottom = height;
|
||||
width = height;
|
||||
dst_left = 0;
|
||||
dst_top = 0;
|
||||
dst_right = height;
|
||||
dst_bottom = height;
|
||||
}
|
||||
|
||||
Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(output);
|
||||
|
||||
final int color = 0xff424242;
|
||||
final Paint paint = new Paint();
|
||||
final Rect src = new Rect((int) left, (int) top, (int) right, (int) bottom);
|
||||
final Rect dst = new Rect((int) dst_left, (int) dst_top, (int) dst_right, (int) dst_bottom);
|
||||
final RectF rectF = new RectF(dst);
|
||||
|
||||
paint.setAntiAlias(true);
|
||||
|
||||
canvas.drawARGB(0, 0, 0, 0);
|
||||
paint.setColor(color);
|
||||
|
||||
// canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
|
||||
canvas.drawCircle(roundPx, roundPx, roundPx, paint);
|
||||
|
||||
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
|
||||
canvas.drawBitmap(bitmap, src, dst, paint);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public static boolean isImageDownloaded(String imagePath) {
|
||||
try {
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(imagePath, options);
|
||||
// ImageDecoder.Source src = ImageDecoder.createSource(mContext.getContentResolver(),
|
||||
// uri, res);
|
||||
// return ImageDecoder.decodeDrawable(src, (decoder, info, s) -> {
|
||||
// decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE);
|
||||
// });
|
||||
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载高分辨率图片需要做下适配
|
||||
*
|
||||
* @param imagePath 图片路径
|
||||
* @return Bitmap 调整后的位图
|
||||
*
|
||||
*
|
||||
* Loading high-resolution images requires adaptation
|
||||
*
|
||||
* @param imagePath
|
||||
* @return Bitmap
|
||||
*/
|
||||
public static Bitmap adaptBitmapFormPath(String imagePath, int reqWidth, int reqHeight){
|
||||
try {
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(imagePath, options);
|
||||
|
||||
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
|
||||
|
||||
options.inJustDecodeBounds = false;
|
||||
return BitmapFactory.decodeFile(imagePath, options);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int calculateInSampleSize(
|
||||
BitmapFactory.Options options, int reqWidth, int reqHeight) {
|
||||
// Raw height and width of image
|
||||
final int height = options.outHeight;
|
||||
final int width = options.outWidth;
|
||||
int inSampleSize = 1;
|
||||
|
||||
if (height > reqHeight || width > reqWidth) {
|
||||
|
||||
final int halfHeight = height / 2;
|
||||
final int halfWidth = width / 2;
|
||||
|
||||
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
|
||||
// height and width larger than the requested height and width.
|
||||
while ((halfHeight / inSampleSize) >= reqHeight
|
||||
&& (halfWidth / inSampleSize) >= reqWidth) {
|
||||
inSampleSize *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
return inSampleSize;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据图片 UUID 和 类型得到图片文件路径
|
||||
* @param uuid 图片 UUID
|
||||
* @param imageType 图片类型 V2TIMImageElem.V2TIM_IMAGE_TYPE_THUMB , V2TIMImageElem.V2TIM_IMAGE_TYPE_ORIGIN ,
|
||||
* V2TIMImageElem.V2TIM_IMAGE_TYPE_LARGE
|
||||
* @return 图片文件路径
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* Get the image file path based on the image UUID and type
|
||||
* @param uuid
|
||||
* @param imageType V2TIMImageElem.V2TIM_IMAGE_TYPE_THUMB , V2TIMImageElem.V2TIM_IMAGE_TYPE_ORIGIN ,
|
||||
* V2TIMImageElem.V2TIM_IMAGE_TYPE_LARGE
|
||||
* @return path
|
||||
*/
|
||||
public static String generateImagePath(String uuid, int imageType) {
|
||||
return TUIConfig.getImageDownloadDir() + uuid + "_" + imageType;
|
||||
}
|
||||
|
||||
|
||||
public static String getGroupConversationAvatar(String groupId) {
|
||||
SPUtils spUtils = SPUtils.getInstance(TUILogin.getSdkAppId() + SP_IMAGE);
|
||||
final String savedIcon = spUtils.getString(groupId, "");
|
||||
if (!TextUtils.isEmpty(savedIcon) && new File(savedIcon).isFile() && new File(savedIcon).exists()) {
|
||||
return savedIcon;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static void setGroupConversationAvatar(String conversationId, String url) {
|
||||
SPUtils spUtils = SPUtils.getInstance(TUILogin.getSdkAppId() + SP_IMAGE);
|
||||
spUtils.put(conversationId, url);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,630 @@
|
||||
package com.tencent.qcloud.tuicore.util;
|
||||
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.ActionBar;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.annotation.StringDef;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
import com.tencent.qcloud.tuicore.TUIConfig;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public final class PermissionRequester {
|
||||
|
||||
private static final List<String> PERMISSIONS = getPermissions();
|
||||
|
||||
private static PermissionRequester instance;
|
||||
private static Context applicationContext;
|
||||
private SimpleCallback mSimpleCallback;
|
||||
private FullCallback mFullCallback;
|
||||
private PermissionDialogCallback mDialogCallback;
|
||||
private Set<String> mPermissions;
|
||||
private List<String> mPermissionsRequest;
|
||||
private String mCurrentRequestPermission;
|
||||
private List<String> mPermissionsGranted;
|
||||
private List<String> mPermissionsDenied;
|
||||
|
||||
private static boolean isRequesting = false;
|
||||
|
||||
private String mReason;
|
||||
private String mReasonTitle;
|
||||
private String mDeniedAlert;
|
||||
private int mIconId;
|
||||
|
||||
private static final Map<String, PermissionRequestContent> permissionRequestContentMap = new HashMap<>();
|
||||
|
||||
public static class PermissionRequestContent {
|
||||
int iconResId;
|
||||
String reasonTitle;
|
||||
String reason;
|
||||
String deniedAlert;
|
||||
|
||||
public void setReasonTitle(String reasonTitle) {
|
||||
this.reasonTitle = reasonTitle;
|
||||
}
|
||||
|
||||
public void setReason(String reason) {
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
public void setIconResId(int iconResId) {
|
||||
this.iconResId = iconResId;
|
||||
}
|
||||
|
||||
public void setDeniedAlert(String deniedAlert) {
|
||||
this.deniedAlert = deniedAlert;
|
||||
}
|
||||
}
|
||||
|
||||
public static void setPermissionRequestContent(String permission, PermissionRequestContent content) {
|
||||
permissionRequestContentMap.put(permission, content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the permissions used in application.
|
||||
*
|
||||
* @return the permissions used in application
|
||||
*/
|
||||
public static List<String> getPermissions() {
|
||||
return getPermissions(getApplicationContext().getPackageName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the permissions used in application.
|
||||
*
|
||||
* @param packageName The name of the package.
|
||||
* @return the permissions used in application
|
||||
*/
|
||||
public static List<String> getPermissions(final String packageName) {
|
||||
PackageManager pm = getApplicationContext().getPackageManager();
|
||||
try {
|
||||
String[] permissions = pm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS).requestedPermissions;
|
||||
if (permissions == null) return Collections.emptyList();
|
||||
return Arrays.asList(permissions);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isGranted(final String... permissions) {
|
||||
for (String permission : permissions) {
|
||||
if (!isGranted(permission)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isGranted(final String permission) {
|
||||
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M
|
||||
|| PackageManager.PERMISSION_GRANTED
|
||||
== ContextCompat.checkSelfPermission(getApplicationContext(), permission);
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the application's details settings.
|
||||
*/
|
||||
public static void launchAppDetailsSettings() {
|
||||
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
intent.setData(Uri.parse("package:" + getApplicationContext().getPackageName()));
|
||||
if (!isIntentAvailable(intent)) return;
|
||||
getApplicationContext().startActivity(intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the permissions.
|
||||
*
|
||||
* @param permission The permissions.
|
||||
* @return the single {@link PermissionRequester} instance
|
||||
*/
|
||||
public static PermissionRequester permission(@PermissionConstants.Permission final String permission) {
|
||||
return new PermissionRequester(permission);
|
||||
}
|
||||
|
||||
private static boolean isIntentAvailable(final Intent intent) {
|
||||
return getApplicationContext()
|
||||
.getPackageManager()
|
||||
.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
|
||||
.size() > 0;
|
||||
}
|
||||
|
||||
private PermissionRequester(final String permission) {
|
||||
mPermissions = new LinkedHashSet<>();
|
||||
mCurrentRequestPermission = permission;
|
||||
for (String aPermission : PermissionConstants.getPermissions(permission)) {
|
||||
if (PERMISSIONS.contains(aPermission)) {
|
||||
mPermissions.add(aPermission);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the simple call back.
|
||||
*
|
||||
* @param callback the simple call back
|
||||
* @return the single {@link PermissionRequester} instance
|
||||
*/
|
||||
public PermissionRequester callback(final SimpleCallback callback) {
|
||||
mSimpleCallback = callback;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the full call back.
|
||||
*
|
||||
* @param callback the full call back
|
||||
* @return the single {@link PermissionRequester} instance
|
||||
*/
|
||||
public PermissionRequester callback(final FullCallback callback) {
|
||||
mFullCallback = callback;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PermissionRequester reason(String reason) {
|
||||
mReason = reason;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PermissionRequester reasonTitle(String reasonTitle) {
|
||||
mReasonTitle = reasonTitle;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PermissionRequester deniedAlert(String deniedAlert) {
|
||||
mDeniedAlert = deniedAlert;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PermissionRequester reasonIcon(int iconId) {
|
||||
mIconId = iconId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PermissionRequester permissionDialogCallback(PermissionDialogCallback callback) {
|
||||
mDialogCallback = callback;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void request() {
|
||||
if (isRequesting) {
|
||||
return;
|
||||
}
|
||||
isRequesting = true;
|
||||
instance = this;
|
||||
mPermissionsGranted = new ArrayList<>();
|
||||
mPermissionsRequest = new ArrayList<>();
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||
mPermissionsGranted.addAll(mPermissions);
|
||||
isRequesting = false;
|
||||
requestCallback();
|
||||
} else {
|
||||
for (String permission : mPermissions) {
|
||||
if (isGranted(permission)) {
|
||||
mPermissionsGranted.add(permission);
|
||||
} else {
|
||||
mPermissionsRequest.add(permission);
|
||||
}
|
||||
}
|
||||
if (mPermissionsRequest.isEmpty()) {
|
||||
isRequesting = false;
|
||||
requestCallback();
|
||||
} else {
|
||||
startPermissionActivity();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
private void startPermissionActivity() {
|
||||
mPermissionsDenied = new ArrayList<>();
|
||||
Context context = getApplicationContext();
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
Intent intent = new Intent(context, PermissionActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
private void getPermissionsStatus() {
|
||||
for (String permission : mPermissionsRequest) {
|
||||
if (isGranted(permission)) {
|
||||
mPermissionsGranted.add(permission);
|
||||
} else {
|
||||
mPermissionsDenied.add(permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void requestCallback() {
|
||||
if (mSimpleCallback != null) {
|
||||
if (mPermissionsRequest.size() == 0
|
||||
|| mPermissions.size() == mPermissionsGranted.size()) {
|
||||
mSimpleCallback.onGranted();
|
||||
} else {
|
||||
if (!mPermissionsDenied.isEmpty()) {
|
||||
mSimpleCallback.onDenied();
|
||||
}
|
||||
}
|
||||
mSimpleCallback = null;
|
||||
}
|
||||
if (mFullCallback != null) {
|
||||
if (mPermissionsRequest.size() == 0
|
||||
|| mPermissions.size() == mPermissionsGranted.size()) {
|
||||
mFullCallback.onGranted(mPermissionsGranted);
|
||||
} else {
|
||||
if (!mPermissionsDenied.isEmpty()) {
|
||||
mFullCallback.onDenied(mPermissionsDenied);
|
||||
}
|
||||
}
|
||||
mFullCallback = null;
|
||||
}
|
||||
mDialogCallback = null;
|
||||
}
|
||||
|
||||
private void onRequestPermissionsResult(final Activity activity) {
|
||||
|
||||
getPermissionsStatus();
|
||||
if (!mPermissionsDenied.isEmpty()) {
|
||||
showPermissionDialog(activity, new PermissionDialogCallback() {
|
||||
@Override
|
||||
public void onApproved() {
|
||||
if (mDialogCallback != null) {
|
||||
mDialogCallback.onApproved();
|
||||
}
|
||||
mDialogCallback = null;
|
||||
launchAppDetailsSettings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefused() {
|
||||
if (mDialogCallback != null) {
|
||||
mDialogCallback.onRefused();
|
||||
}
|
||||
mDialogCallback = null;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
isRequesting = false;
|
||||
mDialogCallback = null;
|
||||
activity.finish();
|
||||
}
|
||||
|
||||
requestCallback();
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
public static class PermissionActivity extends Activity {
|
||||
private static final int SHOW_TIP_DELAY = 150; // ms
|
||||
|
||||
private boolean isDenied = false;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (TUIBuild.getVersionInt() >= 21) {
|
||||
View decorView = getWindow().getDecorView();
|
||||
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
|
||||
getWindow().setStatusBarColor(Color.TRANSPARENT);
|
||||
getWindow().setNavigationBarColor(Color.TRANSPARENT);
|
||||
}
|
||||
ActionBar actionBar = getActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.hide();
|
||||
}
|
||||
|
||||
requestPermission();
|
||||
}
|
||||
|
||||
private void requestPermission() {
|
||||
isDenied = false;
|
||||
if (instance.mPermissionsRequest != null) {
|
||||
int size = instance.mPermissionsRequest.size();
|
||||
if (size <= 0) {
|
||||
instance.onRequestPermissionsResult(this);
|
||||
} else {
|
||||
BackgroundTasks.getInstance().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!isDenied) {
|
||||
fillContentView();
|
||||
}
|
||||
}
|
||||
}, SHOW_TIP_DELAY);
|
||||
|
||||
requestPermissions(instance.mPermissionsRequest.toArray(new String[size]), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fillContentView() {
|
||||
PermissionRequestContent info = permissionRequestContentMap.get(instance.mCurrentRequestPermission);
|
||||
int iconResId = instance.mIconId;
|
||||
String reasonTitle = instance.mReasonTitle;
|
||||
String reason = instance.mReason;
|
||||
if (info != null) {
|
||||
if (info.iconResId != 0) {
|
||||
iconResId = info.iconResId;
|
||||
}
|
||||
if (!TextUtils.isEmpty(info.reasonTitle)) {
|
||||
reasonTitle = info.reasonTitle;
|
||||
}
|
||||
if (!TextUtils.isEmpty(info.reason)) {
|
||||
reason = info.reason;
|
||||
}
|
||||
}
|
||||
if (TextUtils.isEmpty(reason)) {
|
||||
return;
|
||||
}
|
||||
setContentView(R.layout.permission_activity_layout);
|
||||
|
||||
TextView permissionReasonTitle = findViewById(R.id.permission_reason_title);
|
||||
TextView permissionReason = findViewById(R.id.permission_reason);
|
||||
ImageView permissionIcon = findViewById(R.id.permission_icon);
|
||||
permissionReasonTitle.setText(reasonTitle);
|
||||
permissionReason.setText(reason);
|
||||
if (iconResId != 0) {
|
||||
permissionIcon.setBackgroundResource(iconResId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode,
|
||||
@NonNull String[] permissions,
|
||||
@NonNull int[] grantResults) {
|
||||
|
||||
if (instance.mPermissionsRequest != null) {
|
||||
instance.onRequestPermissionsResult(this);
|
||||
if (instance.mPermissionsDenied != null && !instance.mPermissionsDenied.isEmpty()) {
|
||||
isDenied = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
return super.dispatchTouchEvent(ev);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
isRequesting = false;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// interface
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
public interface SimpleCallback {
|
||||
void onGranted();
|
||||
void onDenied();
|
||||
}
|
||||
|
||||
public interface FullCallback {
|
||||
void onGranted(List<String> permissionsGranted);
|
||||
void onDenied(List<String> permissionsDenied);
|
||||
}
|
||||
|
||||
public static final class PermissionConstants {
|
||||
|
||||
public static final String CALENDAR = Manifest.permission_group.CALENDAR;
|
||||
public static final String CAMERA = Manifest.permission_group.CAMERA;
|
||||
public static final String CONTACTS = Manifest.permission_group.CONTACTS;
|
||||
public static final String LOCATION = Manifest.permission_group.LOCATION;
|
||||
public static final String MICROPHONE = Manifest.permission_group.MICROPHONE;
|
||||
public static final String PHONE = Manifest.permission_group.PHONE;
|
||||
public static final String SENSORS = Manifest.permission_group.SENSORS;
|
||||
public static final String SMS = Manifest.permission_group.SMS;
|
||||
public static final String STORAGE = Manifest.permission_group.STORAGE;
|
||||
|
||||
private static final String[] GROUP_CALENDAR = {
|
||||
Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR
|
||||
};
|
||||
private static final String[] GROUP_CAMERA = {
|
||||
Manifest.permission.CAMERA
|
||||
};
|
||||
private static final String[] GROUP_CONTACTS = {
|
||||
Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS, Manifest.permission.GET_ACCOUNTS
|
||||
};
|
||||
private static final String[] GROUP_LOCATION = {
|
||||
Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION
|
||||
};
|
||||
private static final String[] GROUP_MICROPHONE = {
|
||||
Manifest.permission.RECORD_AUDIO
|
||||
};
|
||||
private static final String[] GROUP_PHONE = {
|
||||
Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_PHONE_NUMBERS, Manifest.permission.CALL_PHONE,
|
||||
Manifest.permission.READ_CALL_LOG, Manifest.permission.WRITE_CALL_LOG, Manifest.permission.ADD_VOICEMAIL,
|
||||
Manifest.permission.USE_SIP, Manifest.permission.PROCESS_OUTGOING_CALLS, Manifest.permission.ANSWER_PHONE_CALLS
|
||||
};
|
||||
private static final String[] GROUP_PHONE_BELOW_O = {
|
||||
Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_PHONE_NUMBERS, Manifest.permission.CALL_PHONE,
|
||||
Manifest.permission.READ_CALL_LOG, Manifest.permission.WRITE_CALL_LOG, Manifest.permission.ADD_VOICEMAIL,
|
||||
Manifest.permission.USE_SIP, Manifest.permission.PROCESS_OUTGOING_CALLS
|
||||
};
|
||||
private static final String[] GROUP_SENSORS = {
|
||||
Manifest.permission.BODY_SENSORS
|
||||
};
|
||||
private static final String[] GROUP_SMS = {
|
||||
Manifest.permission.SEND_SMS, Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_SMS,
|
||||
Manifest.permission.RECEIVE_WAP_PUSH, Manifest.permission.RECEIVE_MMS,
|
||||
};
|
||||
private static final String[] GROUP_STORAGE = {
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
};
|
||||
|
||||
@StringDef({CALENDAR, CAMERA, CONTACTS, LOCATION, MICROPHONE, PHONE, SENSORS, SMS, STORAGE,})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Permission {
|
||||
}
|
||||
|
||||
public static String[] getPermissions(@Permission final String permission) {
|
||||
switch (permission) {
|
||||
case CALENDAR:
|
||||
return GROUP_CALENDAR;
|
||||
case CAMERA:
|
||||
return GROUP_CAMERA;
|
||||
case CONTACTS:
|
||||
return GROUP_CONTACTS;
|
||||
case LOCATION:
|
||||
return GROUP_LOCATION;
|
||||
case MICROPHONE:
|
||||
return GROUP_MICROPHONE;
|
||||
case PHONE:
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
return GROUP_PHONE_BELOW_O;
|
||||
} else {
|
||||
return GROUP_PHONE;
|
||||
}
|
||||
case SENSORS:
|
||||
return GROUP_SENSORS;
|
||||
case SMS:
|
||||
return GROUP_SMS;
|
||||
case STORAGE:
|
||||
return GROUP_STORAGE;
|
||||
}
|
||||
return new String[]{permission};
|
||||
}
|
||||
}
|
||||
|
||||
private static Context getApplicationContext() {
|
||||
if (applicationContext == null) {
|
||||
applicationContext = TUIConfig.getAppContext();
|
||||
}
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
public void showPermissionDialog(Activity activity, PermissionDialogCallback callback) {
|
||||
|
||||
PermissionRequestContent info = permissionRequestContentMap.get(instance.mCurrentRequestPermission);
|
||||
String deniedAlert = mDeniedAlert;
|
||||
if (info != null) {
|
||||
if (!TextUtils.isEmpty(info.deniedAlert)) {
|
||||
deniedAlert = info.deniedAlert;
|
||||
}
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(deniedAlert)) {
|
||||
deniedAlert = mReason;
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(deniedAlert)) {
|
||||
isRequesting = false;
|
||||
activity.finish();
|
||||
callback.onRefused();
|
||||
return;
|
||||
}
|
||||
|
||||
activity.setContentView(R.layout.permission_activity_layout);
|
||||
|
||||
View itemPop = LayoutInflater.from(activity).inflate(R.layout.permission_tip_layout, null);
|
||||
TextView tipsTv = itemPop.findViewById(R.id.tips);
|
||||
TextView positiveBtn = itemPop.findViewById(R.id.positive_btn);
|
||||
TextView negativeBtn = itemPop.findViewById(R.id.negative_btn);
|
||||
tipsTv.setText(deniedAlert);
|
||||
|
||||
Dialog permissionTipDialog = new AlertDialog.Builder(activity)
|
||||
.setView(itemPop)
|
||||
.setCancelable(false)
|
||||
.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
isRequesting = false;
|
||||
}
|
||||
})
|
||||
.create();
|
||||
|
||||
positiveBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
isRequesting = false;
|
||||
permissionTipDialog.cancel();
|
||||
activity.finish();
|
||||
callback.onApproved();
|
||||
}
|
||||
});
|
||||
|
||||
negativeBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
isRequesting = false;
|
||||
permissionTipDialog.cancel();
|
||||
activity.finish();
|
||||
callback.onRefused();
|
||||
}
|
||||
});
|
||||
permissionTipDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
|
||||
@Override
|
||||
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
isRequesting = false;
|
||||
permissionTipDialog.cancel();
|
||||
activity.finish();
|
||||
callback.onRefused();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
permissionTipDialog.show();
|
||||
Window dialogWindow = permissionTipDialog.getWindow();
|
||||
dialogWindow.setBackgroundDrawable(new ColorDrawable());
|
||||
WindowManager.LayoutParams layoutParams = dialogWindow.getAttributes();
|
||||
layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
dialogWindow.setAttributes(layoutParams);
|
||||
}
|
||||
|
||||
public interface PermissionDialogCallback{
|
||||
void onApproved();
|
||||
void onRefused();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.tencent.qcloud.tuicore.util;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Build;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupWindow;
|
||||
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
|
||||
public class PopWindowUtil {
|
||||
|
||||
public static AlertDialog buildFullScreenDialog(Activity activity) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
if (activity.isDestroyed())
|
||||
return null;
|
||||
}
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity, R.style.TUIKit_AlertDialogStyle);
|
||||
builder.setTitle("");
|
||||
builder.setCancelable(true);
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.getWindow().setDimAmount(0);
|
||||
dialog.setCanceledOnTouchOutside(true);
|
||||
dialog.show();
|
||||
dialog.getWindow().setLayout(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
|
||||
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static PopupWindow popupWindow(View windowView, View parent, int x, int y) {
|
||||
PopupWindow popup = new PopupWindow(windowView, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT);
|
||||
// int[] position = calculatePopWindowPos(windowView, parent, x, y);
|
||||
popup.setOutsideTouchable(true);
|
||||
popup.setFocusable(true);
|
||||
popup.setBackgroundDrawable(new ColorDrawable(0xAEEEEE00));
|
||||
popup.showAtLocation(windowView, Gravity.CENTER | Gravity.TOP, x, y);
|
||||
return popup;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
package com.tencent.qcloud.tuicore.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.tencent.qcloud.tuicore.ServiceInitializer;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SPUtils {
|
||||
|
||||
public static final String DEFAULT_DATABASE = "tuikit";
|
||||
private static final Map<String, SPUtils> SP_UTILS_MAP = new HashMap<>();
|
||||
|
||||
private final SharedPreferences mSharedPreferences;
|
||||
|
||||
public static SPUtils getInstance() {
|
||||
return getInstance(DEFAULT_DATABASE, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
public static SPUtils getInstance(final int mode) {
|
||||
return getInstance(DEFAULT_DATABASE, mode);
|
||||
}
|
||||
|
||||
public static SPUtils getInstance(String spName) {
|
||||
return getInstance(spName, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
public static SPUtils getInstance(String spName, final int mode) {
|
||||
if (isSpace(spName)) {
|
||||
spName = DEFAULT_DATABASE;
|
||||
}
|
||||
SPUtils spUtils = SP_UTILS_MAP.get(spName);
|
||||
if (spUtils == null) {
|
||||
synchronized (SPUtils.class) {
|
||||
spUtils = SP_UTILS_MAP.get(spName);
|
||||
if (spUtils == null) {
|
||||
spUtils = new SPUtils(spName, mode);
|
||||
SP_UTILS_MAP.put(spName, spUtils);
|
||||
}
|
||||
}
|
||||
}
|
||||
return spUtils;
|
||||
}
|
||||
|
||||
private SPUtils(final String spName, final int mode) {
|
||||
mSharedPreferences = getApplicationContext().getSharedPreferences(spName, mode);
|
||||
}
|
||||
|
||||
private Context getApplicationContext() {
|
||||
return ServiceInitializer.getAppContext();
|
||||
}
|
||||
|
||||
|
||||
// String
|
||||
public void put(@NonNull final String key, final String value) {
|
||||
put(key, value, false);
|
||||
}
|
||||
|
||||
public void put(@NonNull final String key, final String value, final boolean isCommit) {
|
||||
if (isCommit) {
|
||||
mSharedPreferences.edit().putString(key, value).commit();
|
||||
} else {
|
||||
mSharedPreferences.edit().putString(key, value).apply();
|
||||
}
|
||||
}
|
||||
|
||||
public String getString(@NonNull final String key) {
|
||||
return getString(key, "");
|
||||
}
|
||||
|
||||
public String getString(@NonNull final String key, final String defaultValue) {
|
||||
return mSharedPreferences.getString(key, defaultValue);
|
||||
}
|
||||
|
||||
// boolean
|
||||
public void put(@NonNull final String key, final boolean value) {
|
||||
put(key, value, false);
|
||||
}
|
||||
|
||||
public void put(@NonNull final String key, final boolean value, final boolean isCommit) {
|
||||
if (isCommit) {
|
||||
mSharedPreferences.edit().putBoolean(key, value).commit();
|
||||
} else {
|
||||
mSharedPreferences.edit().putBoolean(key, value).apply();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getBoolean(@NonNull final String key) {
|
||||
return getBoolean(key, false);
|
||||
}
|
||||
|
||||
public boolean getBoolean(@NonNull final String key, final boolean defaultValue) {
|
||||
return mSharedPreferences.getBoolean(key, defaultValue);
|
||||
}
|
||||
|
||||
// int
|
||||
public void put(@NonNull final String key, final int value) {
|
||||
put(key, value, false);
|
||||
}
|
||||
|
||||
public void put(@NonNull final String key, final int value, final boolean isCommit) {
|
||||
if (isCommit) {
|
||||
mSharedPreferences.edit().putInt(key, value).commit();
|
||||
} else {
|
||||
mSharedPreferences.edit().putInt(key, value).apply();
|
||||
}
|
||||
}
|
||||
|
||||
public int getInt(@NonNull final String key) {
|
||||
return getInt(key, -1);
|
||||
}
|
||||
|
||||
public int getInt(@NonNull final String key, final int defaultValue) {
|
||||
return mSharedPreferences.getInt(key, defaultValue);
|
||||
}
|
||||
|
||||
// float
|
||||
public void put(@NonNull final String key, final float value) {
|
||||
put(key, value, false);
|
||||
}
|
||||
|
||||
public void put(@NonNull final String key, final float value, final boolean isCommit) {
|
||||
if (isCommit) {
|
||||
mSharedPreferences.edit().putFloat(key, value).commit();
|
||||
} else {
|
||||
mSharedPreferences.edit().putFloat(key, value).apply();
|
||||
}
|
||||
}
|
||||
|
||||
public float getFloat(@NonNull final String key) {
|
||||
return getFloat(key, -1f);
|
||||
}
|
||||
|
||||
public float getFloat(@NonNull final String key, final float defaultValue) {
|
||||
return mSharedPreferences.getFloat(key, defaultValue);
|
||||
}
|
||||
|
||||
// long
|
||||
public void put(@NonNull final String key, final long value) {
|
||||
put(key, value, false);
|
||||
}
|
||||
|
||||
public void put(@NonNull final String key, final long value, final boolean isCommit) {
|
||||
if (isCommit) {
|
||||
mSharedPreferences.edit().putLong(key, value).commit();
|
||||
} else {
|
||||
mSharedPreferences.edit().putLong(key, value).apply();
|
||||
}
|
||||
}
|
||||
|
||||
public long getLong(@NonNull final String key) {
|
||||
return getLong(key, -1L);
|
||||
}
|
||||
|
||||
public long getLong(@NonNull final String key, final long defaultValue) {
|
||||
return mSharedPreferences.getLong(key, defaultValue);
|
||||
}
|
||||
|
||||
|
||||
public boolean contains(@NonNull final String key) {
|
||||
return mSharedPreferences.contains(key);
|
||||
}
|
||||
|
||||
public void remove(@NonNull final String key) {
|
||||
remove(key, false);
|
||||
}
|
||||
|
||||
public void remove(@NonNull final String key, final boolean isCommit) {
|
||||
if (isCommit) {
|
||||
mSharedPreferences.edit().remove(key).commit();
|
||||
} else {
|
||||
mSharedPreferences.edit().remove(key).apply();
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
clear(false);
|
||||
}
|
||||
|
||||
public void clear(final boolean isCommit) {
|
||||
if (isCommit) {
|
||||
mSharedPreferences.edit().clear().commit();
|
||||
} else {
|
||||
mSharedPreferences.edit().clear().apply();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isSpace(final String s) {
|
||||
if (s == null) {
|
||||
return true;
|
||||
}
|
||||
for (int i = 0, len = s.length(); i < len; ++i) {
|
||||
if (!Character.isWhitespace(s.charAt(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.tencent.qcloud.tuicore.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Display;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.tencent.qcloud.tuicore.TUIConfig;
|
||||
|
||||
public class ScreenUtil {
|
||||
|
||||
private static final String TAG = ScreenUtil.class.getSimpleName();
|
||||
|
||||
public static int getScreenHeight(Context context) {
|
||||
DisplayMetrics metric = new DisplayMetrics();
|
||||
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
wm.getDefaultDisplay().getMetrics(metric);
|
||||
return metric.heightPixels;
|
||||
}
|
||||
|
||||
public static int getScreenWidth(Context context) {
|
||||
DisplayMetrics metric = new DisplayMetrics();
|
||||
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
wm.getDefaultDisplay().getMetrics(metric);
|
||||
return metric.widthPixels;
|
||||
}
|
||||
|
||||
public static int getPxByDp(float dp) {
|
||||
float scale = TUIConfig.getAppContext().getResources().getDisplayMetrics().density;
|
||||
return (int) (dp * scale + 0.5f);
|
||||
}
|
||||
|
||||
public static int getRealScreenHeight(Context context) {
|
||||
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
Display display = wm.getDefaultDisplay();
|
||||
DisplayMetrics dm = new DisplayMetrics();
|
||||
display.getRealMetrics(dm);
|
||||
return dm.heightPixels;
|
||||
}
|
||||
|
||||
public static int getRealScreenWidth(Context context) {
|
||||
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
Display display = wm.getDefaultDisplay();
|
||||
DisplayMetrics dm = new DisplayMetrics();
|
||||
display.getRealMetrics(dm);
|
||||
return dm.widthPixels;
|
||||
}
|
||||
|
||||
public static int getNavigationBarHeight(Context context){
|
||||
int resourceId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
|
||||
if (resourceId > 0) {
|
||||
return context.getResources().getDimensionPixelSize(resourceId);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int[] scaledSize(int containerWidth, int containerHeight, int realWidth, int realHeight) {
|
||||
Log.i(TAG, "scaledSize containerWidth: " + containerWidth + " containerHeight: " + containerHeight
|
||||
+ " realWidth: " + realWidth + " realHeight: " + realHeight);
|
||||
float deviceRate = (float) containerWidth / (float) containerHeight;
|
||||
float rate = (float) realWidth / (float) realHeight;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
if (rate < deviceRate) {
|
||||
height = containerHeight;
|
||||
width = (int) (containerHeight * rate);
|
||||
} else {
|
||||
width = containerWidth;
|
||||
height = (int) (containerWidth / rate);
|
||||
}
|
||||
return new int[]{width, height};
|
||||
}
|
||||
|
||||
public static int dip2px(float dpValue) {
|
||||
final float scale = TUIConfig.getAppContext().getResources().getDisplayMetrics().density;
|
||||
return (int) (dpValue * scale + 0.5f);
|
||||
}
|
||||
|
||||
public static float dp2px(float dpValue, DisplayMetrics displayMetrics) {
|
||||
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, displayMetrics);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.tencent.qcloud.tuicore.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.os.IBinder;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import com.tencent.qcloud.tuicore.TUIConfig;
|
||||
|
||||
public class SoftKeyBoardUtil {
|
||||
|
||||
public static void hideKeyBoard(IBinder token) {
|
||||
InputMethodManager imm = (InputMethodManager) TUIConfig.getAppContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (imm != null) {
|
||||
imm.hideSoftInputFromWindow(token, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public static void showKeyBoard(Window window) {
|
||||
InputMethodManager imm = (InputMethodManager) TUIConfig.getAppContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (imm != null) {
|
||||
if (!isSoftInputShown(window)) {
|
||||
imm.toggleSoftInput(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void hideKeyBoard(Window window) {
|
||||
InputMethodManager imm = (InputMethodManager) TUIConfig.getAppContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (imm != null) {
|
||||
if (isSoftInputShown(window)) {
|
||||
imm.toggleSoftInput(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isSoftInputShown(Window window) {
|
||||
View decorView = window.getDecorView();
|
||||
int screenHeight = decorView.getHeight();
|
||||
Rect rect = new Rect();
|
||||
decorView.getWindowVisibleDisplayFrame(rect);
|
||||
return screenHeight - rect.bottom - getNavigateBarHeight(window.getWindowManager()) >= 0;
|
||||
}
|
||||
|
||||
private static int getNavigateBarHeight(WindowManager windowManager) {
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
windowManager.getDefaultDisplay().getMetrics(metrics);
|
||||
int usableHeight = metrics.heightPixels;
|
||||
windowManager.getDefaultDisplay().getRealMetrics(metrics);
|
||||
int realHeight = metrics.heightPixels;
|
||||
if (realHeight > usableHeight) {
|
||||
return realHeight - usableHeight;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
package com.tencent.qcloud.tuicore.util;
|
||||
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
public final class TUIBuild {
|
||||
|
||||
private static final String TAG = "TUIBuild";
|
||||
|
||||
private static String MODEL = ""; //Build.MODEL;
|
||||
private static String BRAND = ""; //Build.BRAND;
|
||||
private static String DEVICE = ""; //Build.DEVICE;
|
||||
private static String MANUFACTURER = ""; //Build.MANUFACTURER;
|
||||
private static String HARDWARE = ""; //Build.HARDWARE;
|
||||
private static String VERSION = ""; //Build.VERSION.RELEASE;
|
||||
private static String BOARD = ""; //Build.BOARD;
|
||||
private static String VERSION_INCREMENTAL = ""; //Build.VERSION.INCREMENTAL
|
||||
private static int VERSION_INT = 0; //Build.VERSION.SDK_INT;
|
||||
|
||||
public static void setModel(final String model) {
|
||||
synchronized (TUIBuild.class) {
|
||||
MODEL = model;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getModel() {
|
||||
if (MODEL == null || MODEL.isEmpty()) {
|
||||
synchronized (TUIBuild.class) {
|
||||
if (MODEL == null || MODEL.isEmpty()) {
|
||||
MODEL = Build.MODEL;
|
||||
Log.i(TAG, "get MODEL by Build.MODEL :" + MODEL);
|
||||
}
|
||||
}
|
||||
}
|
||||
return MODEL;
|
||||
}
|
||||
|
||||
public static void setBrand(final String brand) {
|
||||
synchronized (TUIBuild.class) {
|
||||
BRAND = brand;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getBrand() {
|
||||
if (BRAND == null || BRAND.isEmpty()) {
|
||||
synchronized (TUIBuild.class) {
|
||||
if (BRAND == null || BRAND.isEmpty()) {
|
||||
BRAND = Build.BRAND;
|
||||
Log.i(TAG, "get BRAND by Build.BRAND :" + BRAND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return BRAND;
|
||||
}
|
||||
|
||||
public static void setDevice(final String device) {
|
||||
synchronized (TUIBuild.class) {
|
||||
DEVICE = device;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getDevice() {
|
||||
if (DEVICE == null || DEVICE.isEmpty()) {
|
||||
synchronized (TUIBuild.class) {
|
||||
if (DEVICE == null || DEVICE.isEmpty()) {
|
||||
DEVICE = Build.DEVICE;
|
||||
Log.i(TAG, "get DEVICE by Build.DEVICE :" + DEVICE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DEVICE;
|
||||
}
|
||||
|
||||
public static void setManufacturer(final String manufacturer) {
|
||||
synchronized (TUIBuild.class) {
|
||||
MANUFACTURER = manufacturer;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getManufacturer() {
|
||||
if (MANUFACTURER == null || MANUFACTURER.isEmpty()) {
|
||||
synchronized (TUIBuild.class) {
|
||||
if (MANUFACTURER == null || MANUFACTURER.isEmpty()) {
|
||||
MANUFACTURER = Build.MANUFACTURER;
|
||||
Log.i(TAG, "get MANUFACTURER by Build.MANUFACTURER :" + MANUFACTURER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return MANUFACTURER;
|
||||
}
|
||||
|
||||
public static void setHardware(final String hardware) {
|
||||
synchronized (TUIBuild.class) {
|
||||
HARDWARE = hardware;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getHardware() {
|
||||
if (HARDWARE == null || HARDWARE.isEmpty()) {
|
||||
synchronized (TUIBuild.class) {
|
||||
if (HARDWARE == null || HARDWARE.isEmpty()) {
|
||||
HARDWARE = Build.HARDWARE;
|
||||
Log.i(TAG, "get HARDWARE by Build.HARDWARE :" + HARDWARE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return HARDWARE;
|
||||
}
|
||||
|
||||
public static void setVersion(final String version) {
|
||||
synchronized (TUIBuild.class) {
|
||||
VERSION = version;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getVersion() {
|
||||
if (VERSION == null || VERSION.isEmpty()) {
|
||||
synchronized (TUIBuild.class) {
|
||||
if (VERSION == null || VERSION.isEmpty()) {
|
||||
VERSION = Build.VERSION.RELEASE;
|
||||
Log.i(TAG, "get VERSION by Build.VERSION.RELEASE :" + VERSION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
public static void setVersionInt(final int versionInt) {
|
||||
synchronized (TUIBuild.class) {
|
||||
VERSION_INT = versionInt;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getVersionInt() {
|
||||
if (VERSION_INT == 0) {
|
||||
synchronized (TUIBuild.class) {
|
||||
if (VERSION_INT == 0) {
|
||||
VERSION_INT = Build.VERSION.SDK_INT;
|
||||
Log.i(TAG, "get VERSION_INT by Build.VERSION.SDK_INT :" + VERSION_INT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return VERSION_INT;
|
||||
}
|
||||
|
||||
public static void setVersionIncremental(final String version_incremental) {
|
||||
synchronized (TUIBuild.class) {
|
||||
VERSION_INCREMENTAL = version_incremental;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getVersionIncremental() {
|
||||
if (VERSION_INCREMENTAL == null || VERSION_INCREMENTAL.isEmpty()) {
|
||||
synchronized (TUIBuild.class) {
|
||||
if (VERSION_INCREMENTAL == null || VERSION_INCREMENTAL.isEmpty()) {
|
||||
VERSION_INCREMENTAL = Build.VERSION.INCREMENTAL;
|
||||
Log.i(TAG, "get VERSION_INCREMENTAL by Build.VERSION.INCREMENTAL :" + VERSION_INCREMENTAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
return VERSION_INCREMENTAL;
|
||||
}
|
||||
|
||||
public static void setBoard(final String board) {
|
||||
synchronized (TUIBuild.class) {
|
||||
BOARD = board;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getBoard() {
|
||||
if (BOARD == null || BOARD.isEmpty()) {
|
||||
synchronized (TUIBuild.class) {
|
||||
if (BOARD == null || BOARD.isEmpty()) {
|
||||
BOARD = Build.BOARD;
|
||||
Log.i(TAG, "get BOARD by Build.BOARD :" + BOARD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return BOARD;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.tencent.qcloud.tuicore.util;
|
||||
|
||||
import androidx.core.content.FileProvider;
|
||||
|
||||
public class TUIFileProvider extends FileProvider {
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.tencent.qcloud.tuicore.util;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.tencent.imsdk.v2.V2TIMManager;
|
||||
import com.tencent.qcloud.tuicore.R;
|
||||
import com.tencent.qcloud.tuicore.TUIThemeManager;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class TUIUtil {
|
||||
private static String currentProcessName = "";
|
||||
|
||||
public static String getProcessName() {
|
||||
if (!TextUtils.isEmpty(currentProcessName)) {
|
||||
return currentProcessName;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
currentProcessName = Application.getProcessName();
|
||||
return currentProcessName;
|
||||
}
|
||||
|
||||
try {
|
||||
final Method declaredMethod = Class.forName("android.app.ActivityThread", false, Application.class.getClassLoader())
|
||||
.getDeclaredMethod("currentProcessName", (Class<?>[]) new Class[0]);
|
||||
declaredMethod.setAccessible(true);
|
||||
final Object invoke = declaredMethod.invoke(null, new Object[0]);
|
||||
if (invoke instanceof String) {
|
||||
currentProcessName = (String) invoke;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return currentProcessName;
|
||||
}
|
||||
|
||||
public static int getDefaultGroupIconResIDByGroupType(Context context, String groupType) {
|
||||
if (context == null || TextUtils.isEmpty(groupType)) {
|
||||
return R.drawable.core_default_group_icon_community;
|
||||
}
|
||||
if (TextUtils.equals(groupType, V2TIMManager.GROUP_TYPE_WORK)) {
|
||||
return TUIThemeManager.getAttrResId(context, R.attr.core_default_group_icon_work);
|
||||
} else if (TextUtils.equals(groupType, V2TIMManager.GROUP_TYPE_MEETING)) {
|
||||
return TUIThemeManager.getAttrResId(context, R.attr.core_default_group_icon_meeting);
|
||||
} else if (TextUtils.equals(groupType, V2TIMManager.GROUP_TYPE_PUBLIC)) {
|
||||
return TUIThemeManager.getAttrResId(context, R.attr.core_default_group_icon_public);
|
||||
} else if (TextUtils.equals(groupType, V2TIMManager.GROUP_TYPE_COMMUNITY)) {
|
||||
return TUIThemeManager.getAttrResId(context, R.attr.core_default_group_icon_community);
|
||||
}
|
||||
return R.drawable.core_default_group_icon_community;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.tencent.qcloud.tuicore.util;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* 线程工具,用于执行线程等
|
||||
*
|
||||
* Threading tools
|
||||
*/
|
||||
public final class ThreadHelper {
|
||||
public static final ThreadHelper INST = new ThreadHelper();
|
||||
|
||||
private ExecutorService executors;
|
||||
|
||||
private ThreadHelper(){
|
||||
}
|
||||
|
||||
/**
|
||||
* 在线程中执行
|
||||
* @param runnable 要执行的runnable
|
||||
*
|
||||
* execute in thread
|
||||
*/
|
||||
public void execute(Runnable runnable) {
|
||||
ExecutorService executorService = getExecutorService();
|
||||
if (executorService != null) {
|
||||
executorService.execute(runnable);
|
||||
} else {
|
||||
new Thread(runnable).start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存线程池
|
||||
* @return 缓存线程池服务
|
||||
*
|
||||
* Get the cache thread pool
|
||||
*/
|
||||
private ExecutorService getExecutorService(){
|
||||
if (executors == null) {
|
||||
executors = Executors.newCachedThreadPool();
|
||||
}
|
||||
|
||||
return executors;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.tencent.qcloud.tuicore.util;
|
||||
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.tencent.qcloud.tuicore.ServiceInitializer;
|
||||
|
||||
public class ToastUtil {
|
||||
|
||||
private static Toast toast;
|
||||
|
||||
public static void toastLongMessage(final String message) {
|
||||
toastMessage(message, true);
|
||||
}
|
||||
|
||||
public static void toastShortMessage(final String message) {
|
||||
toastMessage(message, false);
|
||||
}
|
||||
|
||||
private static void toastMessage(final String message, boolean isLong) {
|
||||
BackgroundTasks.getInstance().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (toast != null) {
|
||||
toast.cancel();
|
||||
toast = null;
|
||||
}
|
||||
toast = Toast.makeText(ServiceInitializer.getAppContext(), message,
|
||||
isLong ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT);
|
||||
View view = toast.getView();
|
||||
if (view != null) {
|
||||
TextView textView = view.findViewById(android.R.id.message);
|
||||
if (textView != null) {
|
||||
textView.setGravity(Gravity.CENTER);
|
||||
}
|
||||
}
|
||||
toast.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<gradient android:startColor="?attr/core_header_end_color"
|
||||
android:endColor="?attr/core_header_end_color"/>
|
||||
|
||||
|
||||
</shape>
|
||||
29
tuicore/src/main/res-light/values/light_colors.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- 颜色规范 start -->
|
||||
<color name="core_light_bg_title_text_color_light">#FF000000</color>
|
||||
<color name="core_light_bg_primary_text_color_light">#FF444444</color>
|
||||
<color name="core_light_bg_secondary_text_color_light">#FF888888</color>
|
||||
<color name="core_light_bg_secondary2_text_color_light">#FF999999</color>
|
||||
<color name="core_light_bg_disable_text_color_light">#FFBBBBBB</color>
|
||||
<color name="core_dark_bg_primary_text_color_light">#FFFFFFFF</color>
|
||||
|
||||
<color name="core_primary_bg_color_light">#FFFFFFFF</color>
|
||||
<color name="core_bg_color_light">#FFF2F3F5</color>
|
||||
<color name="core_primary_color_light">#FF147AFF</color>
|
||||
<color name="core_error_tip_color_light">#FFFF584C</color>
|
||||
<color name="core_success_tip_color_light">#FF26CB3E</color>
|
||||
<color name="core_bubble_bg_color_light">#FFDCEAFD</color>
|
||||
<color name="core_divide_color_light">#FFE5E5E5</color>
|
||||
<color name="core_border_color_light">#FFDDDDDD</color>
|
||||
<color name="core_header_start_color_light">#FFFFFFFF</color>
|
||||
<color name="core_header_end_color_light">#FFEBF0F6</color>
|
||||
|
||||
<color name="core_btn_normal_color_light">#FF147AFF</color>
|
||||
<color name="core_btn_pressed_color_light">#FF0064E7</color>
|
||||
<color name="core_btn_disable_color_light">#4D147AFF</color>
|
||||
<!-- 颜色规范 end -->
|
||||
|
||||
<color name="core_title_bar_text_bg_light">#111111</color>
|
||||
|
||||
</resources>
|
||||
41
tuicore/src/main/res-light/values/light_styles.xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="TUIBaseLightTheme" parent="@style/TUIBaseTheme">
|
||||
<!-- 颜色规范 start -->
|
||||
<item name="core_light_bg_title_text_color">@color/core_light_bg_title_text_color_light</item>
|
||||
<item name="core_light_bg_primary_text_color">@color/core_light_bg_primary_text_color_light</item>
|
||||
<item name="core_light_bg_secondary_text_color">@color/core_light_bg_secondary_text_color_light</item>
|
||||
<item name="core_light_bg_secondary2_text_color">@color/core_light_bg_secondary2_text_color_light</item>
|
||||
<item name="core_light_bg_disable_text_color">@color/core_light_bg_disable_text_color_light</item>
|
||||
<item name="core_dark_bg_primary_text_color">@color/core_dark_bg_primary_text_color_light</item>
|
||||
<item name="core_primary_bg_color">@color/core_primary_bg_color_light</item>
|
||||
<item name="core_bg_color">@color/core_bg_color_light</item>
|
||||
<item name="core_primary_color">@color/core_primary_color_light</item>
|
||||
<item name="core_error_tip_color">@color/core_error_tip_color_light</item>
|
||||
<item name="core_success_tip_color">@color/core_success_tip_color_light</item>
|
||||
<item name="core_bubble_bg_color">@color/core_bubble_bg_color_light</item>
|
||||
<item name="core_divide_color">@color/core_divide_color_light</item>
|
||||
<item name="core_border_color">@color/core_border_color_light</item>
|
||||
<item name="core_header_start_color">@color/core_header_start_color_light</item>
|
||||
<item name="core_header_end_color">@color/core_header_end_color_light</item>
|
||||
<item name="core_btn_normal_color">@color/core_btn_normal_color_light</item>
|
||||
<item name="core_btn_pressed_color">@color/core_btn_pressed_color_light</item>
|
||||
<item name="core_btn_disable_color">@color/core_btn_disable_color_light</item>
|
||||
<!-- 颜色规范 end -->
|
||||
|
||||
<item name="core_line_controller_view_switch_btn_selected_bg">@color/core_primary_color_light</item>
|
||||
<item name="core_selected_icon">@drawable/core_selected_icon_light</item>
|
||||
<item name="core_title_bar_bg">@drawable/core_title_bar_bg_light</item>
|
||||
<item name="core_title_bar_text_bg">@color/core_title_bar_text_bg_light</item>
|
||||
<item name="core_title_bar_back_icon">@drawable/core_title_bar_back_light</item>
|
||||
<item name="core_default_group_icon_public">@drawable/core_default_group_icon_public_light</item>
|
||||
<item name="core_default_group_icon_work">@drawable/core_default_group_icon_work_light</item>
|
||||
<item name="core_default_group_icon_meeting">@drawable/core_default_group_icon_meeting_light</item>
|
||||
<item name="core_default_group_icon_community">@drawable/core_default_group_icon_community_light</item>
|
||||
<item name="core_default_user_icon">@drawable/core_default_user_icon_light</item>
|
||||
<item name="user_status_online">@drawable/core_online_status_light</item>
|
||||
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<gradient android:startColor="?attr/core_header_start_color"
|
||||
android:endColor="?attr/core_header_start_color"/>
|
||||
|
||||
</shape>
|
||||
29
tuicore/src/main/res-lively/values/lively_colors.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- 颜色规范 start -->
|
||||
<color name="core_light_bg_title_text_color_lively">#FF000000</color>
|
||||
<color name="core_light_bg_primary_text_color_lively">#FF444444</color>
|
||||
<color name="core_light_bg_secondary_text_color_lively">#FF888888</color>
|
||||
<color name="core_light_bg_secondary2_text_color_lively">#FF999999</color>
|
||||
<color name="core_light_bg_disable_text_color_lively">#FFBBBBBB</color>
|
||||
<color name="core_dark_bg_primary_text_color_lively">#FFFFFFFF</color>
|
||||
|
||||
<color name="core_primary_bg_color_lively">#FFFFFFFF</color>
|
||||
<color name="core_bg_color_lively">#FFF2F3F5</color>
|
||||
<color name="core_primary_color_lively">#FFFF8E82</color>
|
||||
<color name="core_error_tip_color_lively">#FFFF584C</color>
|
||||
<color name="core_success_tip_color_lively">#FF26CB3E</color>
|
||||
<color name="core_bubble_bg_color_lively">#FF9D85</color>
|
||||
<color name="core_divide_color_lively">#FFE5E5E5</color>
|
||||
<color name="core_border_color_lively">#FFDDDDDD</color>
|
||||
<color name="core_header_start_color_lively">#FFFF7B7B</color>
|
||||
<color name="core_header_end_color_lively">#FFFFA88B</color>
|
||||
|
||||
<color name="core_btn_normal_color_lively">#FFFF8E82</color>
|
||||
<color name="core_btn_pressed_color_lively">#FFF86657</color>
|
||||
<color name="core_btn_disable_color_lively">#4DFF8E82</color>
|
||||
<!-- 颜色规范 end -->
|
||||
|
||||
<color name="core_title_bar_text_bg_lively">#FFFFFFFF</color>
|
||||
|
||||
</resources>
|
||||
40
tuicore/src/main/res-lively/values/lively_styles.xml
Normal file
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="TUIBaseLivelyTheme" parent="@style/TUIBaseTheme">
|
||||
<!-- 颜色规范 start -->
|
||||
<item name="core_light_bg_title_text_color">@color/core_light_bg_title_text_color_lively</item>
|
||||
<item name="core_light_bg_primary_text_color">@color/core_light_bg_primary_text_color_lively</item>
|
||||
<item name="core_light_bg_secondary_text_color">@color/core_light_bg_secondary_text_color_lively</item>
|
||||
<item name="core_light_bg_secondary2_text_color">@color/core_light_bg_secondary2_text_color_lively</item>
|
||||
<item name="core_light_bg_disable_text_color">@color/core_light_bg_disable_text_color_lively</item>
|
||||
<item name="core_dark_bg_primary_text_color">@color/core_dark_bg_primary_text_color_lively</item>
|
||||
<item name="core_primary_bg_color">@color/core_primary_bg_color_lively</item>
|
||||
<item name="core_bg_color">@color/core_bg_color_lively</item>
|
||||
<item name="core_primary_color">@color/core_primary_color_lively</item>
|
||||
<item name="core_error_tip_color">@color/core_error_tip_color_lively</item>
|
||||
<item name="core_success_tip_color">@color/core_success_tip_color_lively</item>
|
||||
<item name="core_bubble_bg_color">@color/core_bubble_bg_color_lively</item>
|
||||
<item name="core_divide_color">@color/core_divide_color_lively</item>
|
||||
<item name="core_border_color">@color/core_border_color_lively</item>
|
||||
<item name="core_header_start_color">@color/core_header_start_color_lively</item>
|
||||
<item name="core_header_end_color">@color/core_header_end_color_lively</item>
|
||||
<item name="core_btn_normal_color">@color/core_btn_normal_color_lively</item>
|
||||
<item name="core_btn_pressed_color">@color/core_btn_pressed_color_lively</item>
|
||||
<item name="core_btn_disable_color">@color/core_btn_disable_color_lively</item>
|
||||
<!-- 颜色规范 end -->
|
||||
|
||||
<item name="core_line_controller_view_switch_btn_selected_bg">@color/core_primary_color_lively</item>
|
||||
<item name="core_selected_icon">@drawable/core_selected_icon_lively</item>
|
||||
<item name="core_title_bar_bg">@drawable/core_title_bar_bg_lively</item>
|
||||
<item name="core_title_bar_text_bg">@color/core_title_bar_text_bg_lively</item>
|
||||
<item name="core_title_bar_back_icon">@drawable/core_title_bar_back_lively</item>
|
||||
<item name="core_default_group_icon_public">@drawable/core_default_group_icon_public_lively</item>
|
||||
<item name="core_default_group_icon_work">@drawable/core_default_group_icon_work_lively</item>
|
||||
<item name="core_default_group_icon_meeting">@drawable/core_default_group_icon_meeting_lively</item>
|
||||
<item name="core_default_group_icon_community">@drawable/core_default_group_icon_community_lively</item>
|
||||
<item name="core_default_user_icon">@drawable/core_default_user_icon_lively</item>
|
||||
<item name="user_status_online">@drawable/core_online_status_lively</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 503 B |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<gradient android:startColor="?attr/core_header_start_color"
|
||||
android:endColor="?attr/core_header_start_color"
|
||||
android:angle="270"/>
|
||||
|
||||
</shape>
|
||||
29
tuicore/src/main/res-serious/values/serious_colors.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- 颜色规范 start -->
|
||||
<color name="core_light_bg_title_text_color_serious">#FF000000</color>
|
||||
<color name="core_light_bg_primary_text_color_serious">#FF444444</color>
|
||||
<color name="core_light_bg_secondary_text_color_serious">#FF888888</color>
|
||||
<color name="core_light_bg_secondary2_text_color_serious">#FF999999</color>
|
||||
<color name="core_light_bg_disable_text_color_serious">#FFBBBBBB</color>
|
||||
<color name="core_dark_bg_primary_text_color_serious">#FFFFFFFF</color>
|
||||
|
||||
<color name="core_primary_bg_color_serious">#FFFFFFFF</color>
|
||||
<color name="core_bg_color_serious">#FFF2F3F5</color>
|
||||
<color name="core_primary_color_serious">#FF0052FF</color>
|
||||
<color name="core_error_tip_color_serious">#FFFF584C</color>
|
||||
<color name="core_success_tip_color_serious">#FF26CB3E</color>
|
||||
<color name="core_bubble_bg_color_serious">#FF4F87FF</color>
|
||||
<color name="core_divide_color_serious">#FFE5E5E5</color>
|
||||
<color name="core_border_color_serious">#FFDDDDDD</color>
|
||||
<color name="core_header_start_color_serious">#FF6395FF</color>
|
||||
<color name="core_header_end_color_serious">#FF0052FF</color>
|
||||
|
||||
<color name="core_btn_normal_color_serious">#FF0052FF</color>
|
||||
<color name="core_btn_pressed_color_serious">#FF0049E4</color>
|
||||
<color name="core_btn_disable_color_serious">#4D0052FF</color>
|
||||
<!-- 颜色规范 end -->
|
||||
|
||||
<color name="core_title_bar_text_bg_serious">#FFFFFFFF</color>
|
||||
|
||||
</resources>
|
||||
42
tuicore/src/main/res-serious/values/serious_styles.xml
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="TUIBaseSeriousTheme" parent="@style/TUIBaseTheme">
|
||||
|
||||
<!-- 颜色规范 start -->
|
||||
<item name="core_light_bg_title_text_color">@color/core_light_bg_title_text_color_serious</item>
|
||||
<item name="core_light_bg_primary_text_color">@color/core_light_bg_primary_text_color_serious</item>
|
||||
<item name="core_light_bg_secondary_text_color">@color/core_light_bg_secondary_text_color_serious</item>
|
||||
<item name="core_light_bg_secondary2_text_color">@color/core_light_bg_secondary2_text_color_serious</item>
|
||||
<item name="core_light_bg_disable_text_color">@color/core_light_bg_disable_text_color_serious</item>
|
||||
<item name="core_dark_bg_primary_text_color">@color/core_dark_bg_primary_text_color_serious</item>
|
||||
<item name="core_primary_bg_color">@color/core_primary_bg_color_serious</item>
|
||||
<item name="core_bg_color">@color/core_bg_color_serious</item>
|
||||
<item name="core_primary_color">@color/core_primary_color_serious</item>
|
||||
<item name="core_error_tip_color">@color/core_error_tip_color_serious</item>
|
||||
<item name="core_success_tip_color">@color/core_success_tip_color_serious</item>
|
||||
<item name="core_bubble_bg_color">@color/core_bubble_bg_color_serious</item>
|
||||
<item name="core_divide_color">@color/core_divide_color_serious</item>
|
||||
<item name="core_border_color">@color/core_border_color_serious</item>
|
||||
<item name="core_header_start_color">@color/core_header_start_color_serious</item>
|
||||
<item name="core_header_end_color">@color/core_header_end_color_serious</item>
|
||||
<item name="core_btn_normal_color">@color/core_btn_normal_color_serious</item>
|
||||
<item name="core_btn_pressed_color">@color/core_btn_pressed_color_serious</item>
|
||||
<item name="core_btn_disable_color">@color/core_btn_disable_color_serious</item>
|
||||
<!-- 颜色规范 end -->
|
||||
|
||||
<item name="core_line_controller_view_switch_btn_selected_bg">@color/core_primary_color_serious</item>
|
||||
<item name="core_selected_icon">@drawable/core_selected_icon_serious</item>
|
||||
<item name="core_title_bar_bg">@drawable/core_title_bar_bg_serious</item>
|
||||
<item name="core_title_bar_text_bg">@color/core_title_bar_text_bg_serious</item>
|
||||
<item name="core_title_bar_back_icon">@drawable/core_title_bar_back_serious</item>
|
||||
<item name="core_default_group_icon_public">@drawable/core_default_group_icon_public_serious</item>
|
||||
<item name="core_default_group_icon_work">@drawable/core_default_group_icon_work_serious</item>
|
||||
<item name="core_default_group_icon_meeting">@drawable/core_default_group_icon_meeting_serious</item>
|
||||
<item name="core_default_group_icon_community">@drawable/core_default_group_icon_community_serious</item>
|
||||
<item name="core_default_user_icon">@drawable/core_default_user_icon_serious</item>
|
||||
<item name="user_status_online">@drawable/core_online_status_serious</item>
|
||||
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
8
tuicore/src/main/res/anim/core_popup_in_anim.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate
|
||||
android:duration="150"
|
||||
android:fromYDelta="100%"
|
||||
android:interpolator="@android:anim/accelerate_interpolator"
|
||||
android:toYDelta="0"/>
|
||||
</set>
|
||||
8
tuicore/src/main/res/anim/core_popup_out_anim.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate
|
||||
android:duration="150"
|
||||
android:fromYDelta="0"
|
||||
android:interpolator="@android:anim/accelerate_interpolator"
|
||||
android:toYDelta="100%"/>
|
||||
</set>
|
||||
BIN
tuicore/src/main/res/drawable-xxhdpi/arrow_right.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |