liumingming

sdk

Showing 35 changed files with 2803 additions and 0 deletions
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
.idea/*
../.idea
.idea/sonarlint/
/captures
.externalNativeBuild
\ No newline at end of file
... ...
/build
... ...
apply plugin: 'com.jfrog.bintray'
version = android.defaultConfig.versionName
if (project.hasProperty("android")) { // Android libraries
task sourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
// task javadoc(type: Javadoc) {
// source = android.sourceSets.main.java.srcDirs
// classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
// }
} else { // Java libraries
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
}
//task javadocJar(type: Jar, dependsOn: javadoc) {
// classifier = 'javadoc'
// from javadoc.destinationDir
//}
artifacts {
// archives javadocJar
archives sourcesJar
}
// Bintray
//Properties properties = new Properties()
//properties.load(project.rootProject.file('local.properties').newDataInputStream())
bintray {
// user = properties.getProperty("bintray.user")
// key = properties.getProperty("bintray.apikey")
user = rootProject.ext.user
key = rootProject.ext.apikey
// user = 'hh-medic'
// key = 'c3a4fa32ed2a3cd54d736d04307bb86c12c11ff8'
configurations = ['archives']
pkg {
repo = rootProject.ext.repo
name = rootProject.ext.name
if (rootProject.ext.isCompany) {
userOrg = "hh-medic"
}
desc = rootProject.ext.name
websiteUrl = rootProject.ext.url
vcsUrl = rootProject.ext.vcsUrl
licenses = ["Apache-2.0"]
publish = true
}
}
\ No newline at end of file
... ...
import java.text.SimpleDateFormat
apply plugin: 'com.android.library'
//apply plugin: 'com.jfrog.bintray'
//apply plugin: 'com.github.dcendents.android-maven'
static def buildTime() {
def df = new SimpleDateFormat("MMddHHmm")
return df.format(new Date())
}
// versionCode按时间自增
static def increasedVersionCode(){
return (int)(System.currentTimeMillis()/1000/60)
}
def baseVersion = "1.1.0"
android {
compileSdkVersion 28
defaultConfig {
useLibrary 'org.apache.http.legacy'
// applicationId "com.hhmedic.android.sdk.base"
minSdkVersion 17
targetSdkVersion 28
versionCode increasedVersionCode()
versionName "${baseVersion}.${buildTime()}"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
// proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug{
minifyEnabled false
// proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions
{
checkReleaseBuilds false
abortOnError false
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.2.0'
api 'com.google.code.gson:gson:2.8.0'
// implementation 'com.orhanobut:logger:2.2.0'
}
repositories {
mavenCentral()
maven {
credentials {
username 'hh-public'
password 'OFGB5wX0'
}
url 'http://develop.hh-medic.com/repository/maven-public'
}
}
//apply from:'maven-release-aar.gradle'
apply from:'bintray.gradle'
apply from:'install.gradle'
\ No newline at end of file
... ...
apply plugin: 'com.github.dcendents.android-maven'
group = rootProject.ext.groupId // Maven Group ID for the artifact
install {
repositories.mavenInstaller {
// This generates POM.xml with proper parameters
pom {
project {
packaging 'aar'
groupId rootProject.ext.groupId
artifactId rootProject.ext.artifactId
// Add your description here
name rootProject.ext.name
description rootProject.ext.description
url rootProject.ext.url
// Set your license
licenses {
license {
name rootProject.ext.license_name
url rootProject.ext.license_url
}
}
developers {
developer {
id rootProject.ext.developer_id
name rootProject.ext.developer_name
email rootProject.ext.email
}
}
scm {
connection rootProject.ext.url
developerConnection rootProject.ext.url
url rootProject.ext.url
}
}
}
}
}
\ No newline at end of file
... ...
// 1.maven-插件
apply plugin: 'maven'
// 2.maven-信息
//ext {// ext is a gradle closure allowing the declaration of global properties
// PUBLISH_GROUP_ID = 'com.hhmedic.android.sdk'
// PUBLISH_ARTIFACT_ID = 'nim'
// PUBLISH_VERSION = android.defaultConfig.versionName
//}
def PUBLISH_URL = 'http://develop.hh-medic.com/repository/maven-releases/'
def PUBLISH_GROUP_ID = 'com.hhmedic.android.sdk'
def PUBLISH_ARTIFACT_ID = "base_small"
def PUBLISH_VERSION = android.defaultConfig.versionName
// 3.maven-输出路径
uploadArchives {
// repositories.mavenDeployer {
// //这里就是最后输出地址,在自己电脑上新建个文件夹,把文件夹路径粘贴在此
// //注意”file://“ + 路径,有三个斜杠,别漏了
// repository(url: "file:///Workspace/Workshop/HHSDKAndroidOutput")
//
// pom.project {
// groupId project.PUBLISH_GROUP_ID
// artifactId project.PUBLISH_ARTIFACT_ID
// version project.PUBLISH_VERSION
// }
// }
repositories{
mavenDeployer{
repository(url: PUBLISH_URL) {
authentication(userName: "hh-user", password: "hi9rqvdR")
}
pom.groupId = PUBLISH_GROUP_ID
pom.artifactId = PUBLISH_ARTIFACT_ID
pom.version = PUBLISH_VERSION
pom.project {
licenses {
license {
name 'The Apache Software License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
}
}
}
}
//以下代码会生成jar包源文件,如果是不开源码,请不要输入这段
//aar包内包含注释
//task androidSourcesJar(type: Jar) {
// classifier = 'sources'
// from android.sourceSets.main.java.sourceFiles
//}
//
//artifacts {
// archives androidSourcesJar
//}
\ No newline at end of file
... ...
## Add project specific ProGuard rules here.
## You can control the set of applied configuration files using the
## proguardFiles setting in build.gradle.
##
## For more details, see
## http://developer.android.com/guide/developing/tools/proguard.html
#
## If your project uses WebView with JS, uncomment the following
## and specify the fully qualified class name to the JavaScript interface
## class:
##-keepclassmembers class fqcn.of.javascript.interface.for.webview {
## public *;
##}
#
## Uncomment this to preserve the line number information for
## debugging stack traces.
##-keepattributes SourceFile,LineNumberTable
#
## If you keep the line number information, uncomment this to
## hide the original source file name.
##-renamesourcefileattribute SourceFile
#
#-ignorewarnings
#-keepattributes *Annotation*
#-keepattributes Exceptions
#-keepattributes InnerClasses
#-keepattributes Signature
#-keepattributes SourceFile,LineNumberTable
#
#
##指定代码的压缩级别
#-optimizationpasses 5
#
##包明不混合大小写
#-dontusemixedcaseclassnames
#
##不去忽略非公共的库类
#-dontskipnonpubliclibraryclasses
#
# #优化 不优化输入的类文件
#-dontoptimize
#
# #预校验
#-dontpreverify
#
# #混淆时是否记录日志
#-verbose
#
# # 混淆时所采用的算法
#-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
#
##保护注解
#-keepattributes *Annotation*
#
## 保持哪些类不被混淆
#-keep public class * extends android.app.Fragment
#-keep public class * extends android.app.Activity
#-keep public class * extends android.app.Application
#-keep public class * extends android.app.Service
#-keep public class * extends android.content.BroadcastReceiver
#-keep public class * extends android.content.ContentProvider
#-keep public class * extends android.app.backup.BackupAgentHelper
#-keep public class * extends android.preference.Preference
#-keep public class com.android.vending.licensing.ILicensingService
##如果有引用v4包可以添加下面这行
#-keep public class * extends android.support.v4.app.Fragment
#
#
###记录生成的日志数据,gradle build时在本项目根目录输出##
##apk 包内所有 class 的内部结构
##-dump proguard/class_files.txt
##未混淆的类和成员
##-printseeds proguard/seeds.txt
##列出从 apk 中删除的代码
##-printusage proguard/unused.txt
##混淆前后的映射
##-printmapping proguard/mapping.txt
#########记录生成的日志数据,gradle build时 在本项目根目录输出-end######
#
#
##如果引用了v4或者v7包
#-dontwarn android.support.**
#
#####混淆保护自己项目的部分代码以及引用的第三方jar包library-end####
#
#
#
##保持 native 方法不被混淆
#-keepclasseswithmembernames class * {
# native <methods>;
#}
#
##保持自定义控件类不被混淆
#-keepclasseswithmembers class * {
# public <init>(android.content.Context, android.util.AttributeSet);
#}
#
##保持自定义控件类不被混淆
#-keepclassmembers class * extends android.app.Activity {
# public void *(android.view.View);
#}
#
#-keep public class * extends android.view.View {
# public <init>(android.content.Context);
# public <init>(android.content.Context, android.util.AttributeSet);
# public <init>(android.content.Context, android.util.AttributeSet, int);
# public void set*(...);
#}
#
##保持 Parcelable 不被混淆
#-keep class * implements android.os.Parcelable {
# public static final android.os.Parcelable$Creator *;
#}
#
##保持 Serializable 不被混淆
#-keepnames class * implements java.io.Serializable
#
##保持 Serializable 不被混淆并且enum 类也不被混淆
#-keepclassmembers class * implements java.io.Serializable {
# static final long serialVersionUID;
# private static final java.io.ObjectStreamField[] serialPersistentFields;
# !static !transient <fields>;
# !private <fields>;
# !private <methods>;
# private void writeObject(java.io.ObjectOutputStream);
# private void readObject(java.io.ObjectInputStream);
# java.lang.Object writeReplace();
# java.lang.Object readResolve();
#}
#
##保持枚举 enum 类不被混淆
#-keepclassmembers enum * {
# public static **[] values();
# public static ** valueOf(java.lang.String);
#}
#
#-keepclassmembers class * {
# public void *ButtonClicked(android.view.View);
#}
#
##不混淆资源类
#-keepclassmembers class **.R$* {
# public static <fields>;
#}
#
#-keep interface * {
# <methods>;
#}
#
#-keep public class * extends android.app.Dialog
#
#
#
#
##-dontwarn com.xiaomi.push.**
##-keep class com.xiaomi.** {*;}
##-keep class org.apache.** {*;}
##-keep class com.google.** {*;}
##-dontnote com.xiaomi.**
#
#
#-dontwarn com.bumptech.glide.**
#
#-dontwarn java.lang.invoke.**
#
#-dontnote org.apache.http.**
#-dontnote android.net.http.**
#
#-dontnote android.os.**
#-dontnote com.android.internal.**
#-dontnote android.view.**
#
#
#
#-keep class com.hhmedic.android.sdk.base.utils.** {*;}
#-keep class com.hhmedic.android.sdk.base.net.HHNetErrorHelper {*;}
#-keep class com.hhmedic.android.sdk.base.net.HHSecurityInfo {*;}
#
#-keep class com.hhmedic.android.sdk.base.BaseConfig {*;}
#
#
#-keep class com.hhmedic.android.sdk.base.net.dns.* {*;}
#-keep class com.hhmedic.android.sdk.base.net.open.* {*;}
#-keep class com.hhmedic.android.sdk.base.controller.** {*;}
#-keep class com.hhmedic.android.sdk.base.net.HHNetApplicationConfig {*;}
#-keep class com.hhmedic.android.sdk.base.user.Caches {*;}
#-keep class com.hhmedic.android.sdk.base.user.UserExtension {*;}
#-keep class com.hhmedic.android.sdk.base.user.HHUser {*;}
#-keep class com.hhmedic.android.sdk.base.net.HHRequestQueue {*;}
#
#-keep class com.hhmedic.android.sdk.base.net.volley.*{*;}
#-keep class com.hhmedic.android.sdk.base.net.volley.toolbox.*{*;}
#-keep class com.hhmedic.android.sdk.base.net.ErrorCode{*;}
#-keep class com.hhmedic.android.sdk.base.net.HHNetConfig{*;}
#-keep class com.hhmedic.android.sdk.base.net.HHNetConstants{*;}
#
#-dontwarn okio.**
#-keep class okhttp3.**{*;}
#-keep class okio.**{*;}
#-keep class com.zhy.http.**{*;}
#-keep class com.alexvasilkov.**{*;}
#-keep class com.bumptech.glide.**{*;}
#-keep class android.arch.**{*;}
#-keep class com.google.gson.**{*;}
#
#-dontnote com.bumptech.glide.**
#-dontnote com.google.gson.**
#-dontnote okhttp3.internal.**
#-dontnote okhttp3.**
#-dontnote okio.**
#
#-keepattributes *Annotation*
#-keep @**annotation** class * {*;}
#
#
#-dontnote com.ut.**
#-dontnote android.net.**
... ...
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hhmedic.android.sdk.base">
</manifest>
\ No newline at end of file
... ...
package com.hhmedic.android.sdk.base;
import android.os.Build;
import android.text.TextUtils;
import java.util.UUID;
public class BaseConfig {
public static boolean isTest = false;
public static boolean canPrintLog = false;
public static boolean isDebug = false;
private static String DEVICE_ID;
private static String mPId;
private static String mCoopId;
private static String mHardwareId;
private static String mSdkVersion;
private static String mAppVersion;
static {
DEVICE_ID = getUniqueID();
}
public static String getPid(){
if (TextUtils.isEmpty(mPId)){
mPId = "3001";
}
return mPId;
}
public static String getCoopId(){
if (TextUtils.isEmpty(mCoopId)){
mCoopId = "coopId";
}
return mCoopId;
}
public static String getDeviceId(){
return DEVICE_ID;
}
public static String getHardwareId(){
return mHardwareId;
}
public static void setPid(String pid) {
mPId = pid;
}
public static void setHardwareId(String id){
mHardwareId = id;
}
public static void setCoopId(String id) {
mCoopId = id;
}
public static void setSdkVersion(String version){
mSdkVersion = version;
}
public static void setAppVersion(String version){
mAppVersion = version;
}
public static String getAppVersion(){
if (TextUtils.isEmpty(mAppVersion)){
return getSdkVersion();
}
return mAppVersion;
}
public static String getSdkVersion(){
if (TextUtils.isEmpty(mSdkVersion)){
return "2.6.0";
}
return mSdkVersion;
}
private static String getUniqueID()
{
// If all else fails, if the user does have lower than API 9 (lower
// than Gingerbread), has reset their device or 'Secure.ANDROID_ID'
// returns 'null', then simply the ID returned will be solely based
// off their Android device information. This is where the collisions
// can happen.
// Thanks http://www.pocketmagic.net/?p=1662!
// Try not to use DISPLAY, HOST or ID - these items could change.
// If there are collisions, there will be overlapping data
String m_szDevIDShort = "35" + (Build.BOARD.length() % 10) + (Build.BRAND.length() % 10) + (Build.CPU_ABI.length() % 10) + (Build.DEVICE.length() % 10) + (Build.MANUFACTURER.length() % 10) + (Build.MODEL.length() % 10) + (Build.PRODUCT.length() % 10);
// Thanks to @Roman SL!
// http://stackoverflow.com/a/4789483/950427
// Only devices with API >= 9 have android.os.Build.SERIAL
// http://developer.android.com/reference/android/os/Build.html#SERIAL
// If a user upgrades software or roots their device, there will be a duplicate entry
String serial = null;
try {
serial = Build.class.getField("SERIAL").get(null).toString();
// Go ahead and return the serial for api => 9
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
} catch (Exception exception) {
// String needs to be initialized
serial = "serial"; // some value
}
// Thanks @Joe!
// http://stackoverflow.com/a/2853253/950427
// Finally, combine the values we have found by using the UUID class to create a unique identifier
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
}
}
... ...
package com.hhmedic.android.sdk.base.utils;
import android.app.Activity;
import android.content.Context;
public class HHActivityCompat {
public static boolean isDead(Context context) {
if (context == null) {
return true;
}
if (context instanceof Activity) {
Activity activity = (Activity)context;
if (activity.isFinishing() || activity.isDestroyed()) {
return true;
}
}
return false;
}
}
... ...
package com.hhmedic.android.sdk.base.utils;
import android.text.TextUtils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* Created by iOS on 2017/2/16.
*
*/
public class HHDateUtils
{
public static final String MONTH = "month";
public static final String DAY = "day";
private static final String NORMAL_FORMAT = "yyyy-MM-dd HH:mm";
private static final String DATE_FORMAT = "yyyy-MM-dd";
public static final String DATE_FORMAT_ALL = "yyyy-MM-dd HH:mm:ss";
public static final String DATE_FORMAT_NO_SP = "yyyyMMdd";
public static final String CHINA_MONTH = "MM月dd日";
public static String formatTime(long time)
{
return formatTime(time,NORMAL_FORMAT);
}
public static String formatDay(long time)
{
return formatTime(time,DATE_FORMAT);
}
public static String formatDay(Date date)
{
return formatDay(date,DATE_FORMAT);
}
private HHDateUtils()
{
}
public static String formatDay(Date date,String formart)
{
if (date == null)
{
return "";
}
return formatDate(date,formart);
}
public static String formatTime(long time, String formatStr)
{
// if (time <=0)
// {
// return null;
// }
SimpleDateFormat format = new SimpleDateFormat(formatStr);
return format.format(new Date(time));
}
public static String formatDate(Date date, String formatStr)
{
if (date ==null)
{
return null;
}
SimpleDateFormat format = new SimpleDateFormat(formatStr);
return format.format(date);
}
public static String formatTimeFromLong(long time)
{
long se = time /1000;
long m = se/60;
long la = se%60;
String split = la < 10 ? "0" :"";
if (m>0)
{
return m + ":" + split +la;
}
else
{
return "0:" + split +la;
}
}
public static long timeStr2Long(String time)
{
return timeStr2Long(time,DATE_FORMAT);
}
public static long timeStr2Long(String time,String formatStr)
{
if (TextUtils.isEmpty(time))
{
return 0;
}
SimpleDateFormat format = new SimpleDateFormat(formatStr);
try
{
Date date = format.parse(time);
return date.getTime();
}
catch (ParseException e)
{
Logger.e(e.getMessage());
}
return 0;
}
public static Date str2Date(String time)
{
if (TextUtils.isEmpty(time))
{
return null;
}
SimpleDateFormat format = new SimpleDateFormat(NORMAL_FORMAT);
try
{
return format.parse(time);
}
catch (ParseException e)
{
e.printStackTrace();
}
return null;
}
public static String parseTime(Date date)
{
return parseTime(date,"HH时mm分");
}
public static String parseNormal(Date date)
{
return parseTime(date,"HH:mm");
}
private static String parseTime(Date date, String formatStr)
{
SimpleDateFormat format = new SimpleDateFormat(formatStr);
return format.format(date);
}
public static Map<String,String> formart(Date date)
{
HashMap<String,String> result = new HashMap<>();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int month = cal.get(Calendar.MONTH) + 1;
String mStr = String.valueOf(month);
if (month <10)
{
mStr = "0"+mStr;
}
result.put(MONTH,(mStr+"月"));
result.put(DAY,String.valueOf(cal.get(Calendar.DAY_OF_MONTH)));
return result;
}
}
... ...
package com.hhmedic.android.sdk.base.utils;
import android.content.Context;
import android.os.Environment;
import java.io.File;
import java.io.IOException;
/**
* Created by iOS on 2017/8/15.
*
*/
public class HHDirUtils
{
private static final String TEMP = "temp";
public static String getTempPath(Context context,String name)
{
String dir = getCacheDir(context,TEMP);
return dir + File.separator + name;
}
private static String getCacheDir(Context context, String dir)
{
File cacheDir = getCacheDirectory(context);
String path = cacheDir.getAbsolutePath() + File.separator +dir;
File file = new File(path);
if (!file.exists())
{
file.mkdir();
}
return path;
}
private static final String EXTERNAL_STORAGE_PERMISSION = "android.permission.WRITE_EXTERNAL_STORAGE";
private static final String INDIVIDUAL_DIR_NAME = "uil-images";
public static File getCacheDirectory(Context context) {
return getCacheDirectory(context, true);
}
public static File getCacheDirectory(Context context, boolean preferExternal) {
File appCacheDir = null;
String externalStorageState;
try {
externalStorageState = Environment.getExternalStorageState();
} catch (NullPointerException var5) {
externalStorageState = "";
} catch (IncompatibleClassChangeError var6) {
externalStorageState = "";
}
if(preferExternal && "mounted".equals(externalStorageState) && hasExternalStoragePermission(context)) {
appCacheDir = getExternalCacheDir(context);
}
if(appCacheDir == null) {
appCacheDir = context.getCacheDir();
}
if(appCacheDir == null) {
String cacheDirPath = "/data/data/" + context.getPackageName() + "/cache/";
appCacheDir = new File(cacheDirPath);
}
return appCacheDir;
}
public static File getIndividualCacheDirectory(Context context) {
return getIndividualCacheDirectory(context, "uil-images");
}
public static File getIndividualCacheDirectory(Context context, String cacheDir) {
File appCacheDir = getCacheDirectory(context);
File individualCacheDir = new File(appCacheDir, cacheDir);
if(!individualCacheDir.exists() && !individualCacheDir.mkdir()) {
individualCacheDir = appCacheDir;
}
return individualCacheDir;
}
public static File getOwnCacheDirectory(Context context, String cacheDir) {
File appCacheDir = null;
if("mounted".equals(Environment.getExternalStorageState()) && hasExternalStoragePermission(context)) {
appCacheDir = new File(Environment.getExternalStorageDirectory(), cacheDir);
}
if(appCacheDir == null || !appCacheDir.exists() && !appCacheDir.mkdirs()) {
appCacheDir = context.getCacheDir();
}
return appCacheDir;
}
public static File getOwnCacheDirectory(Context context, String cacheDir, boolean preferExternal) {
File appCacheDir = null;
if(preferExternal && "mounted".equals(Environment.getExternalStorageState()) && hasExternalStoragePermission(context)) {
appCacheDir = new File(Environment.getExternalStorageDirectory(), cacheDir);
}
if(appCacheDir == null || !appCacheDir.exists() && !appCacheDir.mkdirs()) {
appCacheDir = context.getCacheDir();
}
return appCacheDir;
}
private static File getExternalCacheDir(Context context) {
File dataDir = new File(new File(Environment.getExternalStorageDirectory(), "Android"), "data");
File appCacheDir = new File(new File(dataDir, context.getPackageName()), "cache");
if(!appCacheDir.exists()) {
if(!appCacheDir.mkdirs()) {
return null;
}
try {
(new File(appCacheDir, ".nomedia")).createNewFile();
} catch (IOException var4) {
}
}
return appCacheDir;
}
private static boolean hasExternalStoragePermission(Context context) {
int perm = context.checkCallingOrSelfPermission("android.permission.WRITE_EXTERNAL_STORAGE");
return perm == 0;
}
}
... ...
package com.hhmedic.android.sdk.base.utils;
import androidx.core.content.FileProvider;
public class HHFileProvider extends FileProvider {
}
... ...
package com.hhmedic.android.sdk.base.utils;
import android.content.ContentUris;
import android.content.Context;
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.view.View;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Created by iOS on 2016/11/25.
*
*
*/
public class HHImageUtils
{
public static Bitmap getCacheBitmapFromView(View view)
{
final boolean drawingCacheEnabled = true;
view.setDrawingCacheEnabled(drawingCacheEnabled);
view.buildDrawingCache(drawingCacheEnabled);
final Bitmap drawingCache = view.getDrawingCache();
Bitmap bitmap;
if (drawingCache != null)
{
bitmap = Bitmap.createBitmap(drawingCache);
view.setDrawingCacheEnabled(false);
}
else
{
bitmap = null;
}
return bitmap;
}
/**
* uri转换
*
* @param contentURI path
* @return path
*/
public static String convertUri(Uri contentURI, Context context)
{
try
{
Logger.e(contentURI.toString());
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, contentURI)) {
// ExternalStorageProvider
if (isExternalStorageDocument(contentURI)) {
final String docId = DocumentsContract.getDocumentId(contentURI);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
}
// DownloadsProvider
else if (isDownloadsDocument(contentURI)) {
final String id = DocumentsContract.getDocumentId(contentURI);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(contentURI)) {
final String docId = DocumentsContract.getDocumentId(contentURI);
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]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
String result;
Cursor cursor = context.getContentResolver().query(contentURI, null, null, null, null);
if (cursor == null)
{
// Source is Dropbox or other similar local file path
result = contentURI.getPath();
}
else
{
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
result = cursor.getString(idx);
cursor.close();
}
return result;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
private 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);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
private 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.
*/
private 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.
*/
private static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
public static boolean bitmaoSaveFile(Bitmap image,String filePath)
{
File file = new File(filePath);
if (file.exists())
{
file.delete();
}
FileOutputStream out = null;
try
{
out = new FileOutputStream(file);
image.compress(Bitmap.CompressFormat.PNG, 90, out);
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
finally {
if (out!=null)
{
try {
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
public static byte[] bitmap2byte(Bitmap bitmap)
{
if (bitmap == null)
{
return null;
}
ByteArrayOutputStream baos = null;
try
{
baos=new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 50, baos);
byte [] bitmapByte =baos.toByteArray();
return bitmapByte;
}
catch (Exception e)
{
e.printStackTrace();
}
finally {
bitmap.recycle();
if (baos!=null)
{
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
public static String createImagePath(Context context)
{
return HHDirUtils.getTempPath(context,String.valueOf(System.currentTimeMillis())+".jpg");
}
}
... ...
package com.hhmedic.android.sdk.base.utils;
import android.text.Html;
import android.text.Spanned;
import android.text.TextUtils;
import android.util.Base64;
import com.hhmedic.android.sdk.base.utils.secret.HHSecretUtils;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* Created by iOS on 2016/11/3.
*
*/
public final class HHStringUtils
{
private static String WHITE_SPACE = " ";
public static String getSHA1(String str)
{
return HHSecretUtils.getSHA1(str);
}
public static String createLinkString(Map<String, Object> params,boolean urlEncode)
{
List<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);
String prestr = "";
for (int i = 0; i < keys.size(); i++)
{
String key = keys.get(i);
if (params.get(key)==null)
{
continue;
}
String value = params.get(key).toString();
if(urlEncode)
{
value = urlEncode(value);
}
if (i == keys.size() - 1)
{//拼接时,不包括最后一个&字符
prestr = prestr + key + "=" + value;
}
else
{
prestr = prestr + key + "=" + value + "&";
}
}
return prestr;
}
public static String urlEncode(String value)
{
try
{
value = URLEncoder.encode(value,"UTF-8");
} catch (UnsupportedEncodingException e) {
Logger.e("urlEncode error:"+e.getLocalizedMessage());
}
return value;
}
private static byte[] getContentBytes(String content, String charset)
{
if (TextUtils.isEmpty(charset))
{
return content.getBytes();
}
try
{
return content.getBytes(charset);
}
catch (UnsupportedEncodingException e)
{
Logger.e("getContentBytes error:"+e.getLocalizedMessage());
}
return null;
}
public static Spanned formatHtml(String content)
{
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N)
{
return Html.fromHtml(content,Html.FROM_HTML_MODE_LEGACY);
}
else
{
return Html.fromHtml(content);
}
}
public static String base64(String str)
{
try
{
return Base64.encodeToString(str.getBytes("UTF-8"),Base64.NO_WRAP);
}
catch (UnsupportedEncodingException e)
{
Logger.e("base64 error:"+e.getLocalizedMessage());
}
return "";
}
public static String base64(byte[] data)
{
if (data == null)
{
return null;
}
return Base64.encodeToString(data,Base64.NO_WRAP);
}
}
... ...
package com.hhmedic.android.sdk.base.utils;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.Toast;
/**
* Created by iOS on 2018/4/11.
*
*
*/
public class HHUtils
{
private static long lastClickTime;
/// 是否快速连续点击
public static boolean isFastClick()
{
long time = System.currentTimeMillis();
if (time - lastClickTime < 300) {
return true;
}
lastClickTime = time;
return false;
}
public static float density;
public static int screenWidth;
public static int screenHeight;
public static int screenMin;// 宽高中,小的一边
public static int screenMax;// 宽高中,较大的值
public static void init(Context context) {
if (null == context) {
return;
}
DisplayMetrics dm = context.getApplicationContext().getResources().getDisplayMetrics();
screenWidth = dm.widthPixels;
screenHeight = dm.heightPixels;
screenMin = (screenWidth > screenHeight) ? screenHeight : screenWidth;
density = dm.density;
}
public static int screenOffset(Activity activity, View globalView) {
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
int topOffset = dm.heightPixels - globalView.getMeasuredHeight();
return Math.abs(topOffset);
}
public static int dip2px(float dipValue) {
return (int) (dipValue * density + 0.5f);
}
public static void errorTips(Context context,String tips)
{
if (TextUtils.isEmpty(tips) || context == null)
{
return;
}
try
{
Toast.makeText(context,tips,Toast.LENGTH_LONG).show();
}
catch (Exception e)
{
Logger.e(e.toString());
}
}
}
... ...
package com.hhmedic.android.sdk.base.utils;
import android.text.TextUtils;
import android.util.Log;
import com.hhmedic.android.sdk.base.BaseConfig;
public class Logger {
public static void e(String tips){
if (!BaseConfig.isDebug){
return;
}
if (!TextUtils.isEmpty(tips)){
Log.e("HH",tips);
}
}
}
... ...
package com.hhmedic.android.sdk.base.utils;
import java.util.HashMap;
/**
* Created by iOS on 2018/4/4.
*
*
*
*/
public class Maps
{
public static HashMap<String,Object> of(String k1,Object v1)
{
HashMap<String,Object> map = new HashMap<>();
map.put(k1,v1);
return map;
}
public static HashMap<String,Object> of(String k1,String v1,String k2,String v2)
{
HashMap<String,Object> map = new HashMap<>();
map.put(k1,v1);
map.put(k2,v2);
return map;
}
public static HashMap<String,Object> of(String k1,Object v1,String k2,Object v2)
{
HashMap<String,Object> map = new HashMap<>();
map.put(k1,v1);
map.put(k2,v2);
return map;
}
public static HashMap<String,Object> of(String k1,String v1,String k2,long v2)
{
HashMap<String,Object> map = new HashMap<>();
map.put(k1,v1);
map.put(k2,v2);
return map;
}
public static HashMap<String,Object> of(String k1,Object v1,String k2,Object v2,String k3,Object v3)
{
HashMap<String,Object> map = new HashMap<>();
map.put(k1,v1);
map.put(k2,v2);
map.put(k3,v3);
return map;
}
public static HashMap<String,Object> of(String k1,Object v1,String k2,Object v2,String k3,Object v3,String k4,Object v4)
{
HashMap<String,Object> map = new HashMap<>();
map.put(k1,v1);
map.put(k2,v2);
map.put(k3,v3);
map.put(k4,v4);
return map;
}
}
... ...
package com.hhmedic.android.sdk.base.utils.cache;
import android.util.Base64;
import com.hhmedic.android.sdk.base.utils.secret.HHDesConfig;
//
//
//import com.hhmedic.android.sdk.base.utils.secret.HHDesConfig;
//
//import javax.crypto.Cipher;
//import javax.crypto.spec.IvParameterSpec;
//import javax.crypto.spec.SecretKeySpec;
/**
* Created by iOS on 2017/1/12.
*
*/
class HHDes
{
private static byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0};
static String encode(String str) throws Exception
{
// IvParameterSpec zeroIv = new IvParameterSpec(iv);
// SecretKeySpec key = new SecretKeySpec(HHDesConfig.getSIMPLE().getBytes(HHDesConfig.getENCODING()), HHDesConfig.getDES());
// Cipher cipher = Cipher.getInstance(HHDesConfig.getDES());
// cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
// byte[] encryptedData = cipher.doFinal(str.getBytes(HHDesConfig.getENCODING()));
// return Base64.encodeToString(encryptedData, 1);
return Base64.encodeToString(str.getBytes(HHDesConfig.getENCODING()),1);
}
static String decode(String str) throws Exception
{
// IvParameterSpec zeroIv = new IvParameterSpec(iv);
// SecretKeySpec key = new SecretKeySpec(HHDesConfig.getSIMPLE().getBytes(HHDesConfig.getENCODING()), HHDesConfig.getDES());
// Cipher cipher = Cipher.getInstance(HHDesConfig.getDES());
// cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
// byte[] decryptData = cipher.doFinal(Base64.decode(str, 1));
//
// return new String(decryptData,HHDesConfig.getENCODING());
return new String(Base64.decode(str, 1), HHDesConfig.getENCODING());
}
}
... ...
package com.hhmedic.android.sdk.base.utils.cache;
import android.content.Context;
import android.content.SharedPreferences;
import android.text.TextUtils;
import com.hhmedic.android.sdk.base.utils.Logger;
import com.hhmedic.android.sdk.base.utils.secret.HHSecretUtils;
/**
* Created by iOS on 2017/1/12.
*
*/
public class HHSharedPreferences
{
private static final String COMMON = "hh_common";
private static SharedPreferences mSharedPre;
public static void init(Context context)
{
initShared(context,COMMON);
}
public static void check(Context context)
{
if (mSharedPre == null)
{
init(context);
}
}
public static void putString(String key,String value)
{
try
{
mSharedPre.edit().putString(HHSecretUtils.getSHA1(key), HHDes.encode(value)).apply();
}
catch (Exception e)
{
Logger.e(e.toString());
}
}
private static void initShared(Context context,String nameSpace)
{
mSharedPre = context.getSharedPreferences(HHSecretUtils.getSHA1(nameSpace),Context.MODE_PRIVATE);
}
public static String getValue(String key)
{
return getValue(COMMON,key);
}
public static String getValue(String nameSpace,String key)
{
try
{
SharedPreferences shared = mSharedPre;
String content = shared.getString(HHSecretUtils.getSHA1(key),"");
if (TextUtils.isEmpty(content))
{
return "";
}
return HHDes.decode(content);
}
catch (Exception e)
{
Logger.e(e.toString());
}
return "";
}
public static void clear()
{
if (mSharedPre !=null)
{
mSharedPre.edit().clear().apply();
}
}
public static void removeKey(String key)
{
if (mSharedPre != null && !TextUtils.isEmpty(key))
{
mSharedPre.edit().remove(HHSecretUtils.getSHA1(key)).apply();
}
}
}
... ...
package com.hhmedic.android.sdk.base.utils.luban;
import android.text.TextUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
class Checker {
private static List<String> format = new ArrayList<>();
private static final String JPG = "jpg";
private static final String JPEG = "jpeg";
private static final String PNG = "png";
private static final String WEBP = "webp";
private static final String GIF = "gif";
static {
format.add(JPG);
format.add(JPEG);
format.add(PNG);
format.add(WEBP);
format.add(GIF);
}
static boolean isImage(String path) {
if (TextUtils.isEmpty(path)) {
return false;
}
String suffix = path.substring(path.lastIndexOf(".") + 1, path.length());
return format.contains(suffix.toLowerCase());
}
static boolean isJPG(String path) {
if (TextUtils.isEmpty(path)) {
return false;
}
String suffix = path.substring(path.lastIndexOf("."), path.length()).toLowerCase();
return suffix.contains(JPG) || suffix.contains(JPEG);
}
static String checkSuffix(String path) {
if (TextUtils.isEmpty(path)) {
return ".jpg";
}
return path.substring(path.lastIndexOf("."), path.length());
}
static boolean isNeedCompress(int leastCompressSize, String path) {
if (leastCompressSize > 0) {
File source = new File(path);
if (!source.exists()) {
return false;
}
if (source.length() <= (leastCompressSize << 10)) {
return false;
}
}
return true;
}
}
... ...
package com.hhmedic.android.sdk.base.utils.luban;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Responsible for starting compress and managing active and cached resources.
*/
class Engine {
private ExifInterface srcExif;
private String srcImg;
private File tagImg;
private int srcWidth;
private int srcHeight;
Engine(String srcImg, File tagImg) throws IOException {
if (Checker.isJPG(srcImg)) {
this.srcExif = new ExifInterface(srcImg);
}
this.tagImg = tagImg;
this.srcImg = srcImg;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inSampleSize = 1;
BitmapFactory.decodeFile(srcImg, options);
this.srcWidth = options.outWidth;
this.srcHeight = options.outHeight;
}
private int computeSize() {
srcWidth = srcWidth % 2 == 1 ? srcWidth + 1 : srcWidth;
srcHeight = srcHeight % 2 == 1 ? srcHeight + 1 : srcHeight;
int longSide = Math.max(srcWidth, srcHeight);
int shortSide = Math.min(srcWidth, srcHeight);
float scale = ((float) shortSide / longSide);
if (scale <= 1 && scale > 0.5625) {
if (longSide < 2000) {
return 1;
} else if (longSide >= 2000 && longSide < 4990) {
return 2;
} else if (longSide > 4990 && longSide < 10240) {
return 4;
} else {
return longSide / 1280 == 0 ? 1 : longSide / 1280;
}
} else if (scale <= 0.5625 && scale > 0.5) {
return longSide / 1280 == 0 ? 1 : longSide / 1280;
} else {
return (int) Math.ceil(longSide / (1280.0 / scale));
}
}
private Bitmap rotatingImage(Bitmap bitmap) {
if (srcExif == null) return bitmap;
Matrix matrix = new Matrix();
int angle = 0;
int orientation = srcExif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
angle = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
angle = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
angle = 270;
break;
}
matrix.postRotate(angle);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
File compress() throws Exception {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = computeSize();
Bitmap tagBitmap = BitmapFactory.decodeFile(srcImg, options);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
tagBitmap = rotatingImage(tagBitmap);
if (tagBitmap == null)
{
tagBitmap = BitmapFactory.decodeFile(srcImg, options);
}
tagBitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream);
tagBitmap.recycle();
FileOutputStream fos = new FileOutputStream(tagImg);
fos.write(stream.toByteArray());
fos.flush();
fos.close();
stream.close();
return tagImg;
}
}
\ No newline at end of file
... ...
package com.hhmedic.android.sdk.base.utils.luban;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.annotation.WorkerThread;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Luban implements Handler.Callback {
private static final String TAG = "Luban";
private static final String DEFAULT_DISK_CACHE_DIR = "luban_disk_cache";
private static final int MSG_COMPRESS_SUCCESS = 0;
private static final int MSG_COMPRESS_START = 1;
private static final int MSG_COMPRESS_ERROR = 2;
private String mTargetDir;
private List<String> mPaths;
private int mLeastCompressSize;
private OnCompressListener mCompressListener;
private Handler mHandler;
private Luban(Builder builder) {
this.mPaths = builder.mPaths;
this.mTargetDir = builder.mTargetDir;
this.mCompressListener = builder.mCompressListener;
this.mLeastCompressSize = builder.mLeastCompressSize;
mHandler = new Handler(Looper.getMainLooper(), this);
}
public static Builder with(Context context) {
return new Builder(context);
}
/**
* Returns a mFile with a cache audio name in the private cache directory.
*
* @param context
* A context.
*/
private File getImageCacheFile(Context context, String suffix) {
if (TextUtils.isEmpty(mTargetDir)) {
mTargetDir = getImageCacheDir(context).getAbsolutePath();
}
String cacheBuilder = mTargetDir + "/" +
System.currentTimeMillis() +
(int) (Math.random() * 1000) +
(TextUtils.isEmpty(suffix) ? ".jpg" : suffix);
return new File(cacheBuilder);
}
/**
* Returns a directory with a default name in the private cache directory of the application to
* use to store retrieved audio.
*
* @param context
* A context.
*
* @see #getImageCacheDir(Context, String)
*/
@Nullable
private File getImageCacheDir(Context context) {
return getImageCacheDir(context, DEFAULT_DISK_CACHE_DIR);
}
/**
* Returns a directory with the given name in the private cache directory of the application to
* use to store retrieved media and thumbnails.
*
* @param context
* A context.
* @param cacheName
* The name of the subdirectory in which to store the cache.
*
* @see #getImageCacheDir(Context)
*/
@Nullable
private File getImageCacheDir(Context context, String cacheName) {
File cacheDir = context.getExternalCacheDir();
if (cacheDir != null) {
File result = new File(cacheDir, cacheName);
if (!result.mkdirs() && (!result.exists() || !result.isDirectory())) {
// File wasn't able to create a directory, or the result exists but not a directory
return null;
}
return result;
}
if (Log.isLoggable(TAG, Log.ERROR)) {
Log.e(TAG, "default disk cache dir is null");
}
return null;
}
/**
* start asynchronous compress thread
*/
@UiThread
private void launch(final Context context) {
if (mPaths == null || mPaths.size() == 0 && mCompressListener != null) {
mCompressListener.onError(new NullPointerException("image file cannot be null"));
}
Iterator<String> iterator = mPaths.iterator();
while (iterator.hasNext()) {
final String path = iterator.next();
if (Checker.isImage(path)) {
AsyncTask.SERIAL_EXECUTOR.execute(new Runnable() {
@Override public void run() {
try {
mHandler.sendMessage(mHandler.obtainMessage(MSG_COMPRESS_START));
File result = Checker.isNeedCompress(mLeastCompressSize, path) ?
new Engine(path, getImageCacheFile(context, Checker.checkSuffix(path))).compress() :
new File(path);
mHandler.sendMessage(mHandler.obtainMessage(MSG_COMPRESS_SUCCESS, result));
} catch (Exception e) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_COMPRESS_ERROR, e));
}
}
});
} else {
mCompressListener.onError(new IllegalArgumentException("can not read the path : " + path));
}
iterator.remove();
}
}
/**
* start compress and return the mFile
*/
@WorkerThread
private File get(String path, Context context) throws Exception {
return new Engine(path, getImageCacheFile(context, Checker.checkSuffix(path))).compress();
}
@WorkerThread private List<File> get(Context context) throws Exception {
List<File> results = new ArrayList<>();
Iterator<String> iterator = mPaths.iterator();
while (iterator.hasNext()) {
String path = iterator.next();
if (Checker.isImage(path)) {
results.add(new Engine(path, getImageCacheFile(context, Checker.checkSuffix(path))).compress());
}
iterator.remove();
}
return results;
}
@Override
public boolean handleMessage(Message msg) {
if (mCompressListener == null) return false;
switch (msg.what) {
case MSG_COMPRESS_START:
mCompressListener.onStart();
break;
case MSG_COMPRESS_SUCCESS:
mCompressListener.onSuccess((File) msg.obj);
break;
case MSG_COMPRESS_ERROR:
mCompressListener.onError((Throwable) msg.obj);
break;
}
return false;
}
public static class Builder {
private Context context;
private String mTargetDir;
private List<String> mPaths;
private int mLeastCompressSize = 100;
private OnCompressListener mCompressListener;
Builder(Context context) {
this.context = context;
this.mPaths = new ArrayList<>();
}
private Luban build() {
return new Luban(this);
}
public Builder load(File file) {
this.mPaths.add(file.getAbsolutePath());
return this;
}
public Builder load(String string) {
this.mPaths.add(string);
return this;
}
public Builder load(List<String> list) {
this.mPaths.addAll(list);
return this;
}
public Builder putGear(int gear) {
return this;
}
public Builder setCompressListener(OnCompressListener listener) {
this.mCompressListener = listener;
return this;
}
public Builder setTargetDir(String targetDir) {
this.mTargetDir = targetDir;
return this;
}
/**
* do not compress when the origin image file size less than one value
*
* @param size
* the value of file size, unit KB, default 100K
*/
public Builder ignoreBy(int size) {
this.mLeastCompressSize = size;
return this;
}
/**
* begin compress image with asynchronous
*/
public void launch() {
build().launch(context);
}
public File get(String path) throws Exception {
return build().get(path, context);
}
/**
* begin compress image with synchronize
*
* @return the thumb image file list
*/
public List<File> get() throws Exception {
return build().get(context);
}
}
}
\ No newline at end of file
... ...
package com.hhmedic.android.sdk.base.utils.luban;
import java.io.File;
public interface OnCompressListener {
/**
* Fired when the compression is started, override to handle in your own code
*/
void onStart();
/**
* Fired when a compression returns successfully, override to handle in your own code
*/
void onSuccess(File file);
/**
* Fired when a compression fails to complete, override to handle in your own code
*/
void onError(Throwable e);
}
... ...
package com.hhmedic.android.sdk.base.utils.secret;
import java.security.MessageDigest;
/**
* Created by iOS on 2018/1/3.
*
*
*/
public class HHCheckSumBuilder
{
// 计算并获取CheckSum
public static String getCheckSum(String appSecret, String nonce, String curTime)
{
return encode("sha1", appSecret + nonce + curTime);
}
// 计算并获取md5值
public static String getMD5(String requestBody)
{
return encode("md5", requestBody);
}
private static String encode(String algorithm, String value) {
if (value == null) {
return null;
}
try {
MessageDigest messageDigest
= MessageDigest.getInstance(algorithm);
messageDigest.update(value.getBytes());
return getFormattedText(messageDigest.digest());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static String getFormattedText(byte[] bytes) {
int len = bytes.length;
StringBuilder buf = new StringBuilder(len * 2);
for (int j = 0; j < len; j++) {
buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
}
return buf.toString();
}
private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
}
... ...
package com.hhmedic.android.sdk.base.utils.secret;
public class HHDesConfig {
public static String getDES() {
return "DES";
}
public static String getENCODING() {
return "UTF-8";
}
public static String getSIMPLE() {
return "pacs_des";
}
}
... ...
package com.hhmedic.android.sdk.base.utils.secret;
import java.security.MessageDigest;
public class HHSecretUtils {
public static String getSHA1(String str)
{
try
{
MessageDigest md5 = MessageDigest.getInstance("SHA-1");
md5.update(str.getBytes("UTF-8"));
byte[] m = md5.digest();//加密
return get16String(m);
}
catch (Exception e)
{
e.printStackTrace();
}
return "";
}
private static String get16String(byte[] messageDigest)
{
StringBuilder hexString = new StringBuilder();
// 字节数组转换为 十六进制 数
for (int i = 0; i < messageDigest.length; i++)
{
String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
if (shaHex.length() < 2)
{
hexString.append(0);
}
hexString.append(shaHex);
}
return hexString.toString();
}
public static String createToken(long uuid)
{
String uuidStr = String.valueOf(uuid) + "HEHUAN_2015";
return string2MD5(uuidStr);
}
private static String string2MD5(String inStr)
{
MessageDigest md5 = null;
try
{
md5 = MessageDigest.getInstance("MD5");
}
catch (Exception e)
{
System.out.println(e.toString());
e.printStackTrace();
return "";
}
char[] charArray = inStr.toCharArray();
byte[] byteArray = new byte[charArray.length];
for (int i = 0; i < charArray.length; i++)
byteArray[i] = (byte) charArray[i];
byte[] md5Bytes = md5.digest(byteArray);
StringBuilder hexValue = new StringBuilder();
for (int i = 0; i < md5Bytes.length; i++){
int val = ((int) md5Bytes[i]) & 0xff;
if (val < 16)
hexValue.append("0");
hexValue.append(Integer.toHexString(val));
}
return hexValue.toString();
}
}
... ...
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.2'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
apply from:'publish_config.gradle'
\ No newline at end of file
... ...
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
#android.useAndroidX=true
## Automatically convert third-party libraries to use AndroidX
#android.enableJetifier=true
#android.enableD8=true
\ No newline at end of file
... ...
No preview for this file type
#Mon Jul 20 16:09:02 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
... ...
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
... ...
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
... ...
ext {
isCompany = false//控制是发布到企业账号还是个人账号
user = isCompany ? "hhmedic" : "hhclient"
apikey = isCompany ? "6501341d8094b0482a82e3e6eb3b205d2925b194" : "89c96bff0896bb09eb50b53affb8616e18aece15"
url = "https://www.hh-medic.com" //整体用到的URL
groupId = "com.hhmedic.android.sdk" //SDK引用包名
artifactId = "base_small" //SDK引用ID
name = "base_small" //描述
description = "base_small" //描述
license_name = "The Apache Software License, Version 2.0" //协议名称
license_url = "http://www.apache.org/licenses/LICENSE-2.0.txt" //协议地址
developer_id = isCompany ? "hhmedic" : "hhclient" //开发者账号
developer_name = "hhmedic" //开发者昵称
email = "liumingming@hh-medic.com" //开发者邮箱
repo = "maven" //bintray上定义的Repositories
vcsUrl = "http://code.hh-medic.com/dev-client/hhsdk.android.base.git"
}
\ No newline at end of file
... ...
rootProject.name='sdk.base'
include ':app'
... ...