Commit 1ac0acf1 authored by xuelimin's avatar xuelimin

分批2

parent b50acce0
Pipeline #1093 canceled with stages
{
"key": "value"
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Homebozz</string>
<string name="login_login"><![CDATA[Sign In & Continue]]></string>
<string name="login_forgot_password">Forgot your Password?</string>
<string name="error_login_user">Please enter your account number</string>
<string name="error_login_user_password">Please input a password</string>
<string name="logout">Log Out</string>
<string name="str_edit_profile">Edit Profile</string>
<string name="str_save_changes">Save</string>
<string name="str_old_password">Old Password</string>
<string name="str_new_password">New Password</string>
<string name="str_confirm_password">Confirm Password</string>
<string name="str_edit">Edit</string>
<string name="str_profile_setting">Profile Setting</string>
<string name="str_password">Password</string>
<string name="str_profile_photo">Profile Photo</string>
<string name="login_tips_number">Please enter your account number</string>
<string name="login_tips_password">Please input a password</string>
<string name="str_pending">Pending</string>
<string name="str_accepted">Accepted</string>
<string name="str_go_to">Go To</string>
<string name="str_jobs">My Job Listing</string>
<string name="error_login_user_new_password">Please enter the same password</string>
<string name="str_terms_and_condition">Terms and Condition</string>
<string name="str_disagree">Disagree</string>
<string name="str_agree">I Agree</string>
<string name="str_property_details">Property Details</string>
<string name="str_forgot_password_input_id_error">Please input Login ID/Email</string>
<string name="str_term_contents_tips"><![CDATA[By touching Agree, you agree to the <font color="#0060A7">User Agreement</font> and acknowledge that you have read the <font color="#0060A7">Privacy Policy</font>, which includes information about your data subject rights.]]></string>
<string name="str_remember_me">Remember Me</string>
<string name="str_sign_in">Sign In</string>
<string name="str_reset_password">Reset Password</string>
<string name="str_my_jobs">My Jobs</string>
<string name="str_bookmarks">Bookmarks</string>
<string name="str_messages">Messages</string>
<string name="str_my_folder">My Folder</string>
<string name="str_properties">Properties</string>
<string name="str_account">Account</string>
<string name="str_announcements">Announcements</string>
<string name="str_change_password">Change Password</string>
<string name="str_view_job">View Job</string>
<string name="str_job_info">Job Info</string>
<string name="str_property_info">Property Info</string>
<string name="str_assignments">Assignments</string>
<string name="str_check">Check Ins / Check Outs</string>
<string name="str_expenses">Expenses</string>
<string name="str_manage_jobs">Manage Jobs</string>
<string name="str_job_info_cancel_tips">Are you sure you want to cancel this job? The system will immediately checkout anyone who has not checked out and cancel outstanding assignments if you proceed.</string>
<string name="str_job_info_on_hold_tips">Are you sure you want to put this job on hold? The system will immediately checkout anyone who has not checked out and cancel outstanding assignments if you proceed.</string>
<!-- <string name="str_assignments">Assignments</string>-->
<!-- <string name="str_check">Check Ins / Check Outs</string>-->
<!-- <string name="str_expenses">Expenses</string>-->
<!-- <string name="str_job_info">Job Info</string>-->
<!-- <string name="str_job_info_cancel_tips">Are you sure you want to cancel this job? The system will immediately checkout anyone who has not checked out and cancel outstanding assignments if you proceed.</string>-->
<!-- <string name="str_job_info_on_hold_tips">Are you sure you want to put this job on hold? The system will immediately checkout anyone who has not checked out and cancel outstanding assignments if you proceed.</string>-->
<!-- <string name="str_manage_jobs">Manage Jobs</string>-->
<!-- <string name="str_property_info">Property Info</string>-->
<!-- <string name="str_view_job">View Job</string>-->
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Homebozz</string>
<string name="login_login"><![CDATA[ログイン & 続行]]></string>
<string name="login_forgot_password">パスワードを忘れましたか?</string>
<string name="error_login_user">アカウントを入力してください.</string>
<string name="error_login_user_password">パスワードを入力してください</string>
<string name="logout">ログアウト</string>
<string name="str_edit_profile">プロフィールを編集</string>
<string name="str_save_changes">変更を保存</string>
<string name="str_old_password">古いパスワード</string>
<string name="str_new_password">新しいパスワード</string>
<string name="str_confirm_password">パスワードを確認</string>
<string name="str_edit">編集</string>
<string name="str_profile_setting">プロファイル設定</string>
<string name="str_password">パスワード</string>
<string name="str_profile_photo">プロフィール写真</string>
<string name="login_tips_number">"アカウントを入力してください "</string>
<string name="login_tips_password">"パスワードを入力してください "</string>
<string name="str_pending">処理待ち</string>
<string name="str_accepted">処理済み</string>
<string name="str_go_to">Go To</string>
<string name="str_jobs">仕事</string>
<string name="error_login_user_new_password">"同じパスワードを入力してください "</string>
<string name="str_terms_and_condition">"条項と条件 "</string>
<string name="str_disagree">反対する</string>
<string name="str_agree">同意する</string>
<string name="str_property_details">詳細情報</string>
<string name="str_forgot_password_input_id_error">入力してください Login ID/Email</string>
<string name="str_term_contents_tips"><![CDATA[同意触れることで、あなたは<font color="#0060A7">利用規約</font>に同意し、あなたがデータ主体の権利に関する情報が含まれて<font color="#0060A7">プライバシーポリシーを</font>、読んだことを認めています。]]></string>
<string name="str_remember_me">"覚えて "</string>
<string name="str_sign_in">ログイン</string>
<string name="str_reset_password">"リセットパスワード "</string>
<string name="str_my_jobs">マイジョブ</string>
<string name="str_bookmarks">"ブックマーク "</string>
<string name="str_messages">メッセージ</string>
<string name="str_my_folder">マイフォルダ</string>
<string name="str_properties">Properties</string>
<string name="str_account">アカウント</string>
<string name="str_announcements">発表</string>
<string name="str_change_password">"パスワード変更 "</string>
<string name="str_view_job">View Job</string>
<string name="str_job_info">"ジョブ情報 "</string>
<string name="str_property_info">"プロパティ情報 "</string>
<string name="str_assignments">分配</string>
<string name="str_check">チェック/チェックアウト</string>
<string name="str_expenses">経費</string>
<string name="str_manage_jobs">Manage Jobs</string>
<string name="str_job_info_cancel_tips">"この仕事をキャンセルしてください。システムはすぐにチェックアウトしていない場合は、優れた割り当てを取り消している誰もチェックアウトします。 "</string>
<string name="str_job_info_on_hold_tips">"この仕事を保留にしてください。システムはすぐにチェックアウトしていない場合は、優れた割り当てを取り消している誰もチェックアウトします。 "</string>
<!-- <string name="str_assignments">Assignments</string>-->
<!-- <string name="str_check">Check Ins / Check Outs</string>-->
<!-- <string name="str_expenses">Expenses</string>-->
<!-- <string name="str_job_info">Job Info</string>-->
<!-- <string name="str_job_info_cancel_tips">Are you sure you want to cancel this job? The system will immediately checkout anyone who has not checked out and cancel outstanding assignments if you proceed.</string>-->
<!-- <string name="str_job_info_on_hold_tips">Are you sure you want to put this job on hold? The system will immediately checkout anyone who has not checked out and cancel outstanding assignments if you proceed.</string>-->
<!-- <string name="str_manage_jobs">Manage Jobs</string>-->
<!-- <string name="str_property_info">Property Info</string>-->
<!-- <string name="str_view_job">View Job</string>-->
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Homebozz</string>
<string name="login_login"><![CDATA[登录 & 继续]]></string>
<string name="login_forgot_password">忘记密码了吗?</string>
<string name="error_login_user">请输入账号</string>
<string name="error_login_user_password">请输入密码</string>
<string name="logout">登 出</string>
<string name="str_edit_profile">更改个人资讯</string>
<string name="str_save_changes">完成</string>
<string name="str_old_password">旧密码</string>
<string name="str_new_password">新密码</string>
<string name="str_confirm_password">确认密码</string>
<string name="str_edit">编辑</string>
<string name="str_profile_setting">个人资讯设置</string>
<string name="str_password">密码</string>
<string name="str_profile_photo">大头照贴</string>
<string name="login_tips_number">请输入账号</string>
<string name="login_tips_password">请输入密码</string>
<string name="str_pending">待处理</string>
<string name="str_accepted">已处理</string>
<string name="str_go_to">Go To</string>
<string name="str_jobs">工作列表</string>
<string name="error_login_user_new_password">请输入相同的密码</string>
<string name="str_terms_and_condition">条款及条件</string>
<string name="str_disagree">不同意</string>
<string name="str_agree">同意</string>
<string name="str_property_details">详细信息</string>
<string name="str_forgot_password_input_id_error">请输入 Login ID/Email</string>
<string name="str_term_contents_tips"> <![CDATA[触按“同意”即表示您同意<font color="#0060A7">用户协议</font>,并确认您已阅读了包含您的数据主题权限信息的<font color="#0060A7">隐私政策</font>。]]></string>
<string name="str_remember_me">记住我</string>
<string name="str_sign_in">登录</string>
<string name="str_reset_password">"重置密码 "</string>
<string name="str_my_jobs">"我的工作 "</string>
<string name="str_bookmarks">书签</string>
<string name="str_messages">信息</string>
<string name="str_my_folder">"我的文件夹 "</string>
<string name="str_properties">Properties</string>
<string name="str_account">"帐户 "</string>
<string name="str_announcements">公告</string>
<string name="str_change_password">"修改密码 "</string>
<string name="str_view_job">View Job</string>
<string name="str_job_info">"工作信息 "</string>
<string name="str_property_info">"内容信息 "</string>
<string name="str_assignments">分配</string>
<string name="str_check">"签入/签出 "</string>
<string name="str_expenses">费用</string>
<string name="str_manage_jobs">Manage Jobs</string>
<string name="str_job_info_cancel_tips">确定要取消此作业吗?如果您继续,系统将立即签出任何尚未签出的人,并取消未完成的工作分配。</string>
<string name="str_job_info_on_hold_tips">你确定要搁置这项工作吗?如果您继续,系统将立即签出任何尚未签出的人,并取消未完成的工作分配。</string>
<!-- <string name="str_assignments">Assignments</string>-->
<!-- <string name="str_check">Check Ins / Check Outs</string>-->
<!-- <string name="str_expenses">Expenses</string>-->
<!-- <string name="str_job_info">Job Info</string>-->
<!-- <string name="str_job_info_cancel_tips">Are you sure you want to cancel this job? The system will immediately checkout anyone who has not checked out and cancel outstanding assignments if you proceed.</string>-->
<!-- <string name="str_job_info_on_hold_tips">Are you sure you want to put this job on hold? The system will immediately checkout anyone who has not checked out and cancel outstanding assignments if you proceed.</string>-->
<!-- <string name="str_manage_jobs">Manage Jobs</string>-->
<!-- <string name="str_property_info">Property Info</string>-->
<!-- <string name="str_view_job">View Job</string>-->
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Homebozz</string>
<string name="login_login"><![CDATA[登錄 & 繼續]]></string>
<string name="login_forgot_password">忘記密碼了嗎?</string>
<string name="error_login_user">請輸入帳號</string>
<string name="error_login_user_password">請輸入密碼</string>
<string name="logout">登 出</string>
<string name="str_edit_profile">更改個人資訊</string>
<string name="str_save_changes">完成</string>
<string name="str_old_password">舊密碼</string>
<string name="str_new_password">新密碼</string>
<string name="str_confirm_password">確認密碼</string>
<string name="str_edit">編輯</string>
<string name="str_password">密碼</string>
<string name="str_profile_setting">個人資訊設定</string>
<string name="str_profile_photo">大頭照貼</string>
<string name="login_tips_number">"請輸入帳號 "</string>
<string name="login_tips_password">"請輸入密碼 "</string>
<string name="str_pending">待處理</string>
<string name="str_accepted">已處理</string>
<string name="str_go_to">Go To</string>
<string name="str_jobs">工作列表</string>
<string name="error_login_user_new_password">"請輸入相同的密碼 "</string>
<string name="str_terms_and_condition">條款及條件</string>
<string name="str_disagree">不同意</string>
<string name="str_agree">同意</string>
<string name="str_property_details">詳細資訊</string>
<string name="str_forgot_password_input_id_error">請輸入 Login ID/Email</string>
<string name="str_term_contents_tips"> <![CDATA[觸按“同意”即表示您同意<font color="#0060A7">使用者協定</font>,並確認您已閱讀了包含您的數據主題許可權資訊的<font color="#0060A7">隱私政策</font>。]]></string>
<string name="str_remember_me">記住我</string>
<string name="str_sign_in">登錄</string>
<string name="str_reset_password">"重置密碼 "</string>
<string name="str_my_jobs">"我的工作 "</string>
<string name="str_bookmarks">書簽</string>
<string name="str_messages">資訊</string>
<string name="str_my_folder">我的資料夾</string>
<string name="str_properties">Properties</string>
<string name="str_account">帳戶</string>
<string name="str_announcements">公告</string>
<string name="str_change_password">"修改密碼 "</string>
<string name="str_view_job">View Job</string>
<string name="str_job_info">"工作資訊 "</string>
<string name="str_property_info">"内容資訊 "</string>
<string name="str_assignments">分配</string>
<string name="str_check">簽入/簽出</string>
<string name="str_expenses">費用</string>
<string name="str_manage_jobs">Manage Jobs</string>
<string name="str_job_info_cancel_tips">確定要取消此工作嗎?如果您繼續,系統將立即簽出任何尚未簽出的人,並取消未完成的工作分配。</string>
<string name="str_job_info_on_hold_tips">你確定要擱置這項工作嗎?如果您繼續,系統將立即簽出任何尚未簽出的人,並取消未完成的工作分配。</string>
<!-- <string name="str_assignments">Assignments</string>-->
<!-- <string name="str_check">Check Ins / Check Outs</string>-->
<!-- <string name="str_expenses">Expenses</string>-->
<!-- <string name="str_job_info">Job Info</string>-->
<!-- <string name="str_job_info_cancel_tips">Are you sure you want to cancel this job? The system will immediately checkout anyone who has not checked out and cancel outstanding assignments if you proceed.</string>-->
<!-- <string name="str_job_info_on_hold_tips">Are you sure you want to put this job on hold? The system will immediately checkout anyone who has not checked out and cancel outstanding assignments if you proceed.</string>-->
<!-- <string name="str_manage_jobs">Manage Jobs</string>-->
<!-- <string name="str_property_info">Property Info</string>-->
<!-- <string name="str_view_job">View Job</string>-->
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="color_my_theme">#F64932</color>
<color name="color_forgot_password">#AFC1C4</color>
<color name="edit_hint_color">#C0C0C2</color>
<color name="job_info_edit_yes_or_no_un_select_color">#F6F7F9</color>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="login_margin_left_and_right">40dp</dimen>
<dimen name="view_height">50dp</dimen>
<dimen name="text_size">14sp</dimen>
<dimen name="pending_text_size">12sp</dimen>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#FFFFFF</color>
</resources>
\ No newline at end of file
<resources>
<string name="app_name">Homebozz</string>
<string name="login_login"><![CDATA[Sign In & Continue]]></string>
<string name="login_forgot_password">Forgot your Password?</string>
<string name="error_login_user">Please enter your account number</string>
<string name="error_login_user_password">Please input a password</string>
<string name="logout">Log Out</string>
<string name="str_edit_profile">Edit Profile</string>
<string name="str_save_changes">Save</string>
<string name="str_old_password">Old Password</string>
<string name="str_new_password">New Password</string>
<string name="str_confirm_password">Confirm Password</string>
<string name="str_edit">Edit</string>
<string name="str_profile_setting">Profile Setting</string>
<string name="str_password">Password</string>
<string name="str_profile_photo">Profile Photo</string>
<string name="login_tips_number">Please enter your account number</string>
<string name="login_tips_password">Please input a password</string>
<string name="str_pending">Pending</string>
<string name="str_accepted">Accepted</string>
<string name="str_go_to">Go To</string>
<string name="str_jobs">My Job Listing</string>
<string name="error_login_user_new_password">Please enter the same password</string>
<string name="str_terms_and_condition">Terms and Condition</string>
<string name="str_disagree">Disagree</string>
<string name="str_agree">I Agree</string>
<string name="str_property_details">Property Details</string>
<string name="str_forgot_password_input_id_error">Please input Login ID/Email</string>
<string name="str_term_contents_tips"><![CDATA[By touching Agree, you agree to the <font color="#0060A7">User Agreement</font> and acknowledge that you have read the <font color="#0060A7">Privacy Policy</font>, which includes information about your data subject rights.]]></string>
<string name="str_remember_me">Remember Me</string>
<string name="str_sign_in">Sign In</string>
<string name="str_reset_password">Reset Password</string>
<string name="str_my_jobs">My Jobs</string>
<string name="str_bookmarks">Bookmarks</string>
<string name="str_messages">Messages</string>
<string name="str_my_folder">My Folder</string>
<string name="str_properties">Properties</string>
<string name="str_account">Account</string>
<string name="str_announcements">Announcements</string>
<string name="str_change_password">Change Password</string>
<string name="str_view_job">View Job</string>
<string name="str_job_info">Job Info</string>
<string name="str_property_info">Property Info</string>
<string name="str_assignments">Assignments</string>
<string name="str_check">Check Ins / Check Outs</string>
<string name="str_expenses">Expenses</string>
<string name="str_manage_jobs">Manage Jobs</string>
<string name="str_job_info_cancel_tips">Are you sure you want to cancel this job? The system will immediately checkout anyone who has not checked out and cancel outstanding assignments if you proceed.</string>
<string name="str_job_info_on_hold_tips">Are you sure you want to put this job on hold? The system will immediately checkout anyone who has not checked out and cancel outstanding assignments if you proceed.</string>
</resources>
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="BaseAppTheme.Trans">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsTranslucent">true</item>
</style>
<style name="BaseAppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#ff0000</item>
<item name="colorPrimaryDark">#000000</item>
<item name="colorAccent">#000000</item>
</style>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!--3、对应外部内存卡根目录:Environment.getExternalStorageDirectory()-->
<external-path name="ext_root" path="/" />
</paths>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
       
<base-config cleartextTrafficPermitted="true" />
   
</network-security-config>
\ No newline at end of file
package com.rudian.homebozz
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}
#Fri Aug 23 17:25:10 CST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 29
defaultConfig {
minSdkVersion 16
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
}
ext.versions = [
play_services : '17.0.0',
// 统一管理支持包的版本号
suport_library: '28.0.0',
]
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation("com.google.android.gms:play-services-gcm:${versions.play_services}") {
// 剔除 play service 中包含的 v4 支持包
exclude group: 'com.android.support', module: 'support-v4'
}
// 引入版本一致的 v4 支持包
api 'androidx.appcompat:appcompat:1.1.0'
// implementation "com.android.support:support-v4:${versions.suport_library}"
// implementation "com.android.support:appcompat-v7:${versions.suport_library}"
// implementation "com.android.support:recyclerview-v7:${versions.suport_library}"
// implementation "com.android.support:cardview-v7:${versions.suport_library}"
// implementation "com.android.support:support-annotations:${versions.suport_library}"
// implementation 'com.android.support:animated vector drawable:28.0.0'
api 'com.google.android.material:material:1.0.0'
testImplementation 'junit:junit:4.12'
// androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
// api 'me.yokeyword:fragmentationx:1.3.3'
// api 'me.yokeyword:fragmentationx-swipeback:1.3.3'
api 'me.yokeyword:fragmentationx:1.0.2'
implementation 'me.yokeyword:fragmentationx-swipeback:1.0.2'
//网络请求依赖
api 'com.squareup.okio:okio:2.4.1'
api 'com.squareup.okhttp3:okhttp:4.2.2'
api 'com.squareup.retrofit2:retrofit:2.6.2'
api 'com.squareup.retrofit2:converter-scalars:2.6.2'
//loader依赖
api 'com.wang.avi:library:2.1.3'
//alibaba Json解析
api 'com.alibaba:fastjson:1.2.62'
//沉浸式状态栏
api 'com.github.niorgai:StatusBarCompat:2.1.3'
//圆形图片
api 'de.hdodenhof:circleimageview:3.0.1'
api 'com.github.bumptech.glide:glide:4.10.0'
api 'com.github.bumptech.glide:okhttp3-integration:4.10.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0'
// api 'com.github.arcadefire:nice-spinner:1.4.3'
api 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30'
api 'com.choices.divider:RecyclerView_Divider:1.0.0'
// api 'com.google.auto.value:auto-value-annotations:1.6'
// kapt "com.google.auto.value:auto-value:1.6"
//动态权限处理
implementation('com.github.hotchemi:permissionsdispatcher:3.1.0') {
exclude module: 'support-v13'
}
kapt 'com.github.hotchemi:permissionsdispatcher-processor:3.1.0'
//工具包
implementation 'com.blankj:utilcode:1.7.1'
//图片剪裁
implementation 'com.github.yalantis:ucrop:2.2.3-native'
// //二维码扫描
implementation 'me.dm7.barcodescanner:zbar:1.9.3'
}
# 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
package com.rudian.library;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.rudian.library.test", appContext.getPackageName());
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rudian.library">
<application
android:allowBackup="true"
android:label="@string/app_name"
android:supportsRtl="true">
<!--图片剪裁Activity-->
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
</application>
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<!-- <uses-permission-sdk-23 android:name=""-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- <uses-permission-->
<!-- android:name="android.permission.READ_EXTERNAL_STORAGE"-->
<!-- tools:node="remove" />-->
<!-- <uses-permission-->
<!-- android:name="android.permission.CAMERA"-->
<!-- tools:node="remove" />-->
<!-- <uses-permission-->
<!-- android:name="android.permission.WRITE_EXTERNAL_STORAGE"-->
<!-- tools:node="remove" />-->
</manifest>
package com.rudian.library.activites
import android.os.Bundle
import androidx.annotation.NonNull
import androidx.appcompat.app.AppCompatActivity
import android.view.MotionEvent
import me.yokeyword.fragmentation.*
import me.yokeyword.fragmentation.anim.FragmentAnimator
/**
* Created on 2019-08-20
* Created by 薛立民
* 实现单Activity多Fragment
* 此文件为主Activity
*/
abstract class ProxyActivity : AppCompatActivity(), ISupportActivity {
// private val DELEGATE = SupportActivityDelegate(this)
// abstract fun setRootDelegate(): HomeBozzDelegate
// override fun onCreate(savedInstanceState: Bundle?) {
// super.onCreate(savedInstanceState)
// DELEGATE.onCreate(savedInstanceState)
// initContainer(savedInstanceState)
// }
// private fun initContainer(savedInstanceState: Bundle?) {
// @SuppressLint("RestrictedApi") val container = ContentFrameLayout(this)
// container.id = R.id.delegate_container
// setContentView(container)
// if (savedInstanceState == null) {
// DELEGATE.loadRootFragment(R.id.delegate_container, setRootDelegate())
// }
// }
internal val mDelegate = SupportActivityDelegate(this)
override fun getSupportDelegate(): SupportActivityDelegate {
return mDelegate
}
/**
* Perform some extra transactions.
* 额外的事务:自定义Tag,添加SharedElement动画,操作非回退栈Fragment
*/
override fun extraTransaction(): ExtraTransaction {
return mDelegate.extraTransaction()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mDelegate.onCreate(savedInstanceState)
}
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
mDelegate.onPostCreate(savedInstanceState)
}
override fun onDestroy() {
mDelegate.onDestroy()
super.onDestroy()
}
/**
* Note: return mDelegate.dispatchTouchEvent(ev) || super.dispatchTouchEvent(ev);
*/
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
return mDelegate.dispatchTouchEvent(ev) || super.dispatchTouchEvent(ev)
}
/**
* 不建议复写该方法,请使用 [.onBackPressedSupport] 代替
*/
override fun onBackPressed() {
mDelegate.onBackPressed()
}
/**
* 该方法回调时机为,Activity回退栈内Fragment的数量 小于等于1 时,默认finish Activity
* 请尽量复写该方法,避免复写onBackPress(),以保证SupportFragment内的onBackPressedSupport()回退事件正常执行
*/
override fun onBackPressedSupport() {
mDelegate.onBackPressedSupport()
}
/**
* 获取设置的全局动画 copy
*
* @return FragmentAnimator
*/
override fun getFragmentAnimator(): FragmentAnimator {
return mDelegate.fragmentAnimator
}
/**
* Set all fragments animation.
* 设置Fragment内的全局动画
*/
override fun setFragmentAnimator(fragmentAnimator: FragmentAnimator) {
mDelegate.fragmentAnimator = fragmentAnimator
}
/**
* Set all fragments animation.
* 构建Fragment转场动画
*
*
* 如果是在Activity内实现,则构建的是Activity内所有Fragment的转场动画,
* 如果是在Fragment内实现,则构建的是该Fragment的转场动画,此时优先级 > Activity的onCreateFragmentAnimator()
*
* @return FragmentAnimator对象
*/
override fun onCreateFragmentAnimator(): FragmentAnimator {
return mDelegate.onCreateFragmentAnimator()
}
/**
* Causes the Runnable r to be added to the action queue.
*
*
* The runnable will be run after all the previous action has been run.
*
*
* 前面的事务全部执行后 执行该Action
*/
override fun post(runnable: Runnable) {
mDelegate.post(runnable)
}
/****************************************以下为可选方法(Optional methods) */
// 选择性拓展其他方法
fun loadRootFragment(containerId: Int, @NonNull toFragment: ISupportFragment) {
mDelegate.loadRootFragment(containerId, toFragment)
}
fun start(toFragment: ISupportFragment) {
mDelegate.start(toFragment)
}
/**
* @param launchMode Same as Activity's LaunchMode.
*/
fun start(toFragment: ISupportFragment, @ISupportFragment.LaunchMode launchMode: Int) {
mDelegate.start(toFragment, launchMode)
}
/**
* It is recommended to use [SupportFragment.startWithPopTo].
*
* @see .popTo
* @see .start
*/
fun startWithPopTo(toFragment: ISupportFragment, targetFragmentClass: Class<*>, includeTargetFragment: Boolean) {
mDelegate.startWithPopTo(toFragment, targetFragmentClass, includeTargetFragment)
}
/**
* Pop the fragment.
*/
fun pop() {
mDelegate.pop()
}
/**
* Pop the last fragment transition from the manager's fragment
* back stack.
*/
fun popTo(targetFragmentClass: Class<*>, includeTargetFragment: Boolean) {
mDelegate.popTo(targetFragmentClass, includeTargetFragment)
}
/**
* If you want to begin another FragmentTransaction immediately after popTo(), use this method.
* 如果你想在出栈后, 立刻进行FragmentTransaction操作,请使用该方法
*/
fun popTo(targetFragmentClass: Class<*>, includeTargetFragment: Boolean, afterPopTransactionRunnable: Runnable) {
mDelegate.popTo(targetFragmentClass, includeTargetFragment, afterPopTransactionRunnable)
}
fun popTo(targetFragmentClass: Class<*>, includeTargetFragment: Boolean, afterPopTransactionRunnable: Runnable, popAnim: Int) {
mDelegate.popTo(targetFragmentClass, includeTargetFragment, afterPopTransactionRunnable, popAnim)
}
/**
* 得到位于栈顶Fragment
*/
fun getTopFragment(): ISupportFragment {
return SupportHelper.getTopFragment(getSupportFragmentManager())
}
/**
* 获取栈内的fragment对象
*/
fun <T : ISupportFragment> findFragment(fragmentClass: Class<T>): T {
return SupportHelper.findFragment(getSupportFragmentManager(), fragmentClass)
}
}
\ No newline at end of file
package com.rudian.library.app
import com.rudian.library.util.storage.Preference
/**
* Created on 2019-08-21
* Created by xuelimin
*/
class AccountManager {
private enum class PHPSESSID {
PHPSESSID
}
private enum class UserData {
USER_ID,
EMAIL,
USER_NAME,
USER_IMAGES_STANDARD,
USER_IMAGES_THUMBNAIL,
USER_IMAGES_MEDIUM,
USER_IMAGES_HIGH,
MOBILE_PHONECC,
MOBILE_PHONE,
FIRST_NAME,
LAST_NAME,
ETHNIC_GIVEN_NAME,
ETHNIC_LAST_NAME,
LANGUAGE,
TIMEZONE_ID,
JOB_STATUS,
LOGIN_PASSWORD,
LOGIN_USER_NAME,
ROLE,
IS_MANAGER,
IS_REMEMBER_ME
}
companion object {
fun isManager(isRememberMe: Boolean) {
Preference.setAppFlag(UserData.IS_MANAGER.name, isRememberMe)
}
fun getIsManager(): Boolean {
return Preference.getAppFlag(UserData.IS_MANAGER.name)
}
fun setJobStatus(status: String) {
Preference.addCustomAppProfile(UserData.JOB_STATUS.name, status)
}
fun getJobStatus(): String {
return Preference.getCustomAppProfile(UserData.JOB_STATUS.name)
}
fun isRememberMe(isRememberMe: Boolean) {
Preference.setAppFlag(UserData.IS_REMEMBER_ME.name, isRememberMe)
}
fun getisRememberMe(): Boolean {
return Preference.getAppFlag(UserData.IS_REMEMBER_ME.name)
}
fun setLoginPassword(password: String) {
Preference.addCustomAppProfile(UserData.LOGIN_PASSWORD.name, password)
}
fun getLoginPassword(): String {
return Preference.getCustomAppProfile(UserData.LOGIN_PASSWORD.name)
}
fun setLoginUserName(userName: String) {
Preference.addCustomAppProfile(UserData.LOGIN_USER_NAME.name, userName)
}
fun getLoginUserName(): String {
return Preference.getCustomAppProfile(UserData.LOGIN_USER_NAME.name)
}
fun setEthnicGivenName(status: String) {
Preference.addCustomAppProfile(UserData.ETHNIC_GIVEN_NAME.name, status)
}
fun getEthnicGivenName(): String {
return Preference.getCustomAppProfile(UserData.ETHNIC_GIVEN_NAME.name)
}
fun setEthnicLastName(status: String) {
Preference.addCustomAppProfile(UserData.ETHNIC_LAST_NAME.name, status)
}
fun getEthnicLastName(): String {
return Preference.getCustomAppProfile(UserData.ETHNIC_LAST_NAME.name)
}
fun setPHPSESSID(id: String) {
Preference.addCustomAppProfile(PHPSESSID.PHPSESSID.name, id)
}
fun getPHPSESSID(): String {
return Preference.getCustomAppProfile(PHPSESSID.PHPSESSID.name)
}
fun setUserID(userId: String) {
Preference.addCustomAppProfile(UserData.USER_ID.name, userId)
}
fun getUserID(): String {
return Preference.getCustomAppProfile(UserData.USER_ID.name)
}
fun setEmail(email: String) {
Preference.addCustomAppProfile(UserData.EMAIL.name, email)
}
fun getEmail(): String {
return Preference.getCustomAppProfile(UserData.EMAIL.name)
}
fun setUserName(userName: String) {
Preference.addCustomAppProfile(UserData.USER_NAME.name, userName)
}
fun getUserName(): String {
return Preference.getCustomAppProfile(UserData.USER_NAME.name)
}
fun setFirstName(firstName: String) {
Preference.addCustomAppProfile(UserData.FIRST_NAME.name, firstName)
}
fun getFirstName(): String {
return Preference.getCustomAppProfile(UserData.FIRST_NAME.name)
}
fun setLastName(lastName: String) {
Preference.addCustomAppProfile(UserData.LAST_NAME.name, lastName)
}
fun getLastName(): String {
return Preference.getCustomAppProfile(UserData.LAST_NAME.name)
}
fun setUserMobilePhoneCC(mobilePhonecc: String) {
Preference.addCustomAppProfile(UserData.MOBILE_PHONECC.name, mobilePhonecc)
}
fun getUserMobilePhoneCC(): String {
return Preference.getCustomAppProfile(UserData.MOBILE_PHONECC.name)
}
fun setUserMobilePhone(mobilePhone: String) {
Preference.addCustomAppProfile(UserData.MOBILE_PHONE.name, mobilePhone)
}
fun getUserMobilePhone(): String {
return Preference.getCustomAppProfile(UserData.MOBILE_PHONE.name)
}
fun setUserUserImagesStandard(imagesStandard: String) {
Preference.addCustomAppProfile(UserData.USER_IMAGES_STANDARD.name, imagesStandard)
}
fun getUserImagesStandard(): String {
return Preference.getCustomAppProfile(UserData.USER_IMAGES_STANDARD.name)
}
fun setUserImagesThumbnail(imagesThumbnail: String) {
Preference.addCustomAppProfile(UserData.USER_IMAGES_THUMBNAIL.name, imagesThumbnail)
}
fun getUserImagesThumbnail(): String {
return Preference.getCustomAppProfile(UserData.USER_IMAGES_THUMBNAIL.name)
}
fun setUserImagesmedium(imagesMedium: String) {
Preference.addCustomAppProfile(UserData.USER_IMAGES_MEDIUM.name, imagesMedium)
}
fun getUserImagesmedium(): String {
return Preference.getCustomAppProfile(UserData.USER_IMAGES_MEDIUM.name)
}
fun setUserImagesHigh(imagesHigh: String) {
Preference.addCustomAppProfile(UserData.USER_IMAGES_HIGH.name, imagesHigh)
}
fun getUserImagesHigh(): String {
return Preference.getCustomAppProfile(UserData.USER_IMAGES_HIGH.name)
}
}
}
\ No newline at end of file
package com.rudian.library.app
enum class ConfigKeys {
API_HOST,
APPLICATION_CONTEXT,
CONFIG_READY,
LOADER_DELAYED,
INTERCEPTOR,
HANDLER,
ACTIVITY,
JAVASCRIPT_INTERFACE,
APP_CODE
}
package com.rudian.library.app
import android.app.Activity
import android.os.Handler
import okhttp3.Interceptor
import java.util.*
@Suppress("UNCHECKED_CAST")
class Configurator {
/* 参数集合*/
private val LATTE_CONFIGS = HashMap<Any, Any>()
//OKhttp中的拦截器集合
private val INTERCEPTORS = ArrayList<Interceptor>()
private val HANDLER = Handler()
private fun Configurator() {
LATTE_CONFIGS[ConfigKeys.CONFIG_READY] = false
LATTE_CONFIGS[ConfigKeys.HANDLER] = HANDLER
}
private object Holder {
internal val INSTANCE = Configurator()
}
internal fun getLatteConfigs(): HashMap<Any, Any> {
return LATTE_CONFIGS
}
fun configure() {
LATTE_CONFIGS[ConfigKeys.CONFIG_READY] = true//已准备好
}
companion object {
fun getInstance(): Configurator {
return Holder.INSTANCE
}
}
/**
* 设置服务器地址
*/
fun withApiHost(host: String): Configurator {
LATTE_CONFIGS[ConfigKeys.API_HOST] = host
return this
}
private fun checkConfiguration() {
val isReady = LATTE_CONFIGS[ConfigKeys.CONFIG_READY] as Boolean
if (!isReady) {
throw RuntimeException("Configuration is not ready,call configure")
}
}
/**
* 设置版本code
*/
fun withAppCode(appCode: Int): Configurator {
LATTE_CONFIGS[ConfigKeys.APP_CODE] = appCode
return this
}
/**
* 设置activity
*/
fun withActivity(activity: Activity): Configurator {
LATTE_CONFIGS[ConfigKeys.ACTIVITY] = activity
return this
}
internal fun <T> getConfiguration(key: Any): T {
checkConfiguration()
LATTE_CONFIGS[key] ?: throw NullPointerException("$key IS NULL")
return LATTE_CONFIGS[key] as T
}
/**
* 设置OKhttp中的拦截器
*/
fun withInterceptor(interceptor: Interceptor): Configurator {
INTERCEPTORS.add(interceptor)
LATTE_CONFIGS[ConfigKeys.INTERCEPTOR] = INTERCEPTORS
return this
}
fun withJavascriptInterface(name: String): Configurator {
LATTE_CONFIGS[ConfigKeys.JAVASCRIPT_INTERFACE] = name
return this
}
/**
* 设置Loader时长
*/
fun withLoaderDelayed(delayed: Long): Configurator {
LATTE_CONFIGS[ConfigKeys.LOADER_DELAYED] = delayed
return this
}
/**
* 设置OKhttp中的拦截器集合
*/
fun withInterceptors(interceptors: ArrayList<Interceptor>): Configurator {
INTERCEPTORS.addAll(interceptors)
LATTE_CONFIGS[ConfigKeys.INTERCEPTOR] = INTERCEPTORS
return this
}
}
package com.rudian.library.app
import android.content.Context
import android.os.Handler
import java.util.*
class HomeBozz {
companion object {
fun init(context: Context): Configurator {
getConfigurations()[ConfigKeys.APPLICATION_CONTEXT] = context.applicationContext
return Configurator.getInstance()
}
fun getApplicationContext(): Context {
return getConfigurations()[ConfigKeys.APPLICATION_CONTEXT] as Context
}
fun getConfigurator(): Configurator {
return Configurator.getInstance()
}
fun <T> getConfiguration(key: Any): T {
return getConfigurator().getConfiguration(key)
}
fun getConfigurations(): HashMap<Any, Any> {
return Configurator.getInstance().getLatteConfigs()
}
fun getHandler(): Handler {
return getConfiguration(ConfigKeys.HANDLER)
}
}
}
package com.rudian.library.delagete.base
/**
* Created on 2019-08-20
* Created by xuelimin
*/
abstract class HomeBozzDelegate : PermissionCheckerDelegate()
\ No newline at end of file
package com.rudian.library.delagete.base
import android.Manifest
import android.annotation.SuppressLint
import android.content.Intent
import android.net.Uri
import androidx.appcompat.app.AlertDialog
import android.widget.Toast
import com.rudian.library.ui.camera.CameraImageBean
import com.rudian.library.ui.camera.HomeBozzCamera
import com.rudian.library.ui.camera.RequestCodes
import com.rudian.library.ui.scanner.ScannerDelegate
import com.rudian.library.util.callback.CallbackManager
import com.rudian.library.util.callback.CallbackType
import com.yalantis.ucrop.UCrop
import me.yokeyword.fragmentation.ISupportFragment.RESULT_OK
import permissions.dispatcher.*
/**
* Created on 2019-08-20
* Created by xuelimin
*/
@RuntimePermissions
abstract class PermissionCheckerDelegate : BaseDelegate() {
@NeedsPermission(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
fun applyPermission() {
HomeBozzCamera.start(this)
}
@SuppressLint("NeedOnRequestPermissionsResult")
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
onRequestPermissionsResult(requestCode, grantResults)
}
@OnShowRationale(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
fun showRationalePermission(request: PermissionRequest) {
showRationaleDialog("需要拍照权限", request)
}
//扫描二维码(不直接调用)
@NeedsPermission(Manifest.permission.CAMERA)
internal fun startScan(delegate: BaseDelegate) {
delegate.supportDelegate.startForResult(ScannerDelegate(), RequestCodes.SCAN)
}
@OnPermissionDenied(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
fun permissionDenied() {
Toast.makeText(context, "不允许拍照", Toast.LENGTH_LONG).show()
}
@OnNeverAskAgain(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
fun neverAskAgainPermission() {
Toast.makeText(context, "永久拒绝权限", Toast.LENGTH_LONG).show()
}
@NeedsPermission(Manifest.permission.CAMERA)
fun applyCameraPermission() {
HomeBozzCamera.start(this)
}
@OnShowRationale(Manifest.permission.CAMERA)
fun cameraShow(request: PermissionRequest) {
showRationaleDialog("需要拍照权限", request)
}
@OnPermissionDenied(Manifest.permission.CAMERA)
fun cameraPermissionDenied() {
Toast.makeText(context, "不允许拍照", Toast.LENGTH_LONG).show()
}
@OnNeverAskAgain(Manifest.permission.CAMERA)
fun cameraPermissionNeverAskAgain() {
Toast.makeText(context, "永久拒绝权限", Toast.LENGTH_LONG).show()
}
private fun showRationaleDialog(messageResId: String, request: PermissionRequest) {
AlertDialog.Builder(context!!)
.setPositiveButton("同意使用") { dialog, which -> request.proceed() }
.setNegativeButton("拒绝使用") { dialog, which -> request.cancel() }
.setCancelable(false)
.setMessage(messageResId)
.show()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
when (requestCode) {
RequestCodes.TAKE_PHOTO -> {
val resultUri = CameraImageBean.instance.path
UCrop.of(resultUri!!, resultUri)
.withMaxResultSize(400, 400)
.start(context!!, this)
}
RequestCodes.PICK_PHOTO -> if (data != null) {
val pickPath = data.data
//从相册选择后需要有个路径存放剪裁过的图片
val pickCropPath = HomeBozzCamera.createCropFile().path
UCrop.of(pickPath!!, Uri.parse(pickCropPath))
.withMaxResultSize(400, 400)
.start(context!!, this)
}
RequestCodes.CROP_PHOTO -> {
val cropUri = UCrop.getOutput(data!!)
// //拿到剪裁后的数据进行处理
CallbackManager.instance.getCallback(CallbackType.ON_CROP)?.executeCallback(cropUri!!)
}
RequestCodes.CROP_ERROR -> Toast.makeText(context, "剪裁出错", Toast.LENGTH_SHORT).show()
else -> {
}
}
}
}
}
\ No newline at end of file
package com.rudian.library.net
/**
* Created on 2019-08-20
* Created by xuelimin
*/
enum class HttpMethod {
GET,
POST,
POST_RAW,
PUT,
PUT_RAW,
DELETE,
UPLOAD,
UPLOAD_IMAGE
}
\ No newline at end of file
package com.rudian.library.net
import android.content.Context
import com.rudian.library.net.callback.*
import com.rudian.library.net.download.DownloadHandler
import com.rudian.library.ui.HomeBozzLoader
import com.rudian.library.ui.LoaderStyle
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody
import retrofit2.Call
import retrofit2.Callback
import java.io.File
import java.util.*
/**
* Created on 2019-08-20
* Created by xuelimin
*/
class RestClient(url: String?, params: WeakHashMap<String, Any>, irequest: IRequest?, isuccess: ISuccess?,
ierror: IError?, ifailure: IFailure?, body: RequestBody?, loaderStyle: LoaderStyle?,
context: Context?, file: File?, downloadDir: String?, extension: String?, name: String?) {
private var URL: String? = null
private var PARAMS = RestCreator().getParams()
private var REQUEST: IRequest? = null
private var SUCCESS: ISuccess? = null
private var ERROR: IError? = null
private var FAILURE: IFailure? = null
private var BODY: RequestBody? = null
private var LOADER_STYLE: LoaderStyle? = null
private var CONTEXT: Context? = null
private var FILE: File? = null
private var DOWNLOAD_DIR: String? = null
private var EXTENSION: String? = null
private var NAME: String? = null
init {
this.URL = url
PARAMS.putAll(params)
this.REQUEST = irequest
this.SUCCESS = isuccess
this.ERROR = ierror
this.FAILURE = ifailure
this.BODY = body
this.LOADER_STYLE = loaderStyle
this.CONTEXT = context
this.FILE = file
this.DOWNLOAD_DIR = downloadDir
this.NAME = name
this.EXTENSION = extension
}
companion object {
fun builder(): RestClientBuilder {
return RestClientBuilder()
}
}
private fun request(method: HttpMethod) {
var service = RestCreator().getRestService()
var call: Call<String>? = null
if (REQUEST != null) {
REQUEST!!.onRequestStart()
}
if (LOADER_STYLE != null) {
CONTEXT?.let { HomeBozzLoader.showLoading(it, LOADER_STYLE!!) }
}
when (method) {
HttpMethod.GET -> call = service[URL!!, PARAMS]
HttpMethod.PUT -> call = service.put(URL!!, PARAMS)
HttpMethod.PUT_RAW -> call = service.putRaw(URL!!, BODY!!)
HttpMethod.POST -> call = service.post(URL!!, PARAMS)
HttpMethod.POST_RAW -> call = service.postRaw(URL!!, BODY!!)
HttpMethod.UPLOAD -> {
val requestBody = RequestBody.create(MultipartBody.FORM.toString().toMediaTypeOrNull(), FILE!!)
// val body = FormBody.Builder()
// body.add("meta[language]", Util.getLanguage())
// val hashStr = AccountManager.getUserID() + Util.getSecondTimestamp() + AccountManager.getPHPSESSID()
// body.add("meta[hash]", Util.sha512(hashStr))
// body.add("meta[user_id]", AccountManager.getUserID())
//// body.add("meta[PHPSESSID]", AccountManager.getPHPSESSID())
// body.add("meta[timestamp]", Util.getSecondTimestamp().toString())
// body.add("user_id", AccountManager.getUserID())
// if (maps != null && maps.size > 0) {
// for (key in maps.keys) {
// body.add(key, maps[key])
// }
// }
// this.mBody = body.build()
val body = MultipartBody.Part.createFormData("file", FILE!!.name, requestBody)
call = service.upload(URL!!, body)
}
HttpMethod.UPLOAD_IMAGE -> {
val requestBody = RequestBody.create(MultipartBody.FORM.toString().toMediaTypeOrNull(), FILE!!)
val body = MultipartBody.Part.createFormData("file", FILE!!.name, requestBody)
call = service.uploadImage(URL!!, BODY!!, body)
}
HttpMethod.DELETE -> call = service.delete(URL!!, PARAMS)
}
call!!.enqueue(getRequestCallback())
}
private fun getRequestCallback(): Callback<String> {
return RequestCallback(REQUEST, SUCCESS, ERROR, FAILURE, LOADER_STYLE)
}
fun get() {
request(HttpMethod.GET)
}
fun put() {
if (BODY == null) {
request(HttpMethod.PUT)
} else {
if (!PARAMS.isEmpty()) {
throw RuntimeException("params must be null!")
}
request(HttpMethod.PUT_RAW)
}
}
fun post() {
if (BODY == null) {
request(HttpMethod.POST)
} else {
if (!PARAMS.isEmpty()) {
throw RuntimeException("params must be null!")
}
request(HttpMethod.POST_RAW)
}
}
fun upLoad() {
request(HttpMethod.UPLOAD)
}
fun upLoadImage() {
request(HttpMethod.UPLOAD_IMAGE)
}
fun delete() {
request(HttpMethod.DELETE)
}
fun download() {
DownloadHandler(URL, REQUEST, SUCCESS, ERROR, FAILURE, DOWNLOAD_DIR, EXTENSION, NAME).handleDownload()
}
}
\ No newline at end of file
package com.rudian.library.net
import android.content.Context
import android.util.Log
import com.rudian.library.app.AccountManager
import com.rudian.library.net.callback.IError
import com.rudian.library.net.callback.IFailure
import com.rudian.library.net.callback.IRequest
import com.rudian.library.net.callback.ISuccess
import com.rudian.library.ui.LoaderStyle
import com.rudian.library.util.language.Util
import okhttp3.FormBody
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody
import java.io.File
import java.util.*
/**
* Created on 2019-08-20
* Created by xuelimin
*/
class RestClientBuilder {
private var mUrl: String? = null
private val PARAMS = RestCreator().getParams()
private var mIRequest: IRequest? = null
private var mISuccess: ISuccess? = null
private var mIError: IError? = null
private var mIFailure: IFailure? = null
private var mBody: RequestBody? = null
private var mContext: Context? = null
private var mLoaderStyle: LoaderStyle? = null
private var mFile: File? = null
private var mDownloadDir: String? = null
private var mExtension: String? = null
private var mName: String? = null
fun url(url: String): RestClientBuilder {
this.mUrl = url
return this
}
fun params(params: WeakHashMap<String, Any>): RestClientBuilder {
PARAMS.putAll(params)
return this
}
fun paramsClear(): RestClientBuilder {
PARAMS.clear()
return this
}
fun params(key: String, value: Any): RestClientBuilder {
PARAMS[key] = value
return this
}
fun raw(raw: String): RestClientBuilder {
this.mBody = RequestBody.create("application/json;charset=UTF-8".toMediaTypeOrNull(), raw)
return this
}
fun rawBodyforTextString(raw: String): RestClientBuilder {
this.mBody = RequestBody.create("application/x-www-form-urlencoded;charset=UTF-8".toMediaTypeOrNull(), raw)
return this
}
fun formDataParams(isUserId: Boolean, maps: HashMap<String, String>?): RestClientBuilder {
val body = FormBody.Builder()
body.add("meta[language]", Util.getLanguage())
if (isUserId) {
val hashStr = AccountManager.getUserID() + Util.getSecondTimestamp() + AccountManager.getPHPSESSID()
body.add("meta[hash]", Util.sha512(hashStr))
body.add("meta[user_id]", AccountManager.getUserID())
// body.add("meta[user_id]", "1004")
body.add("meta[timestamp]", Util.getSecondTimestamp().toString())
body.add("user_id", AccountManager.getUserID())
}
if (maps != null && maps.size > 0) {
for (key in maps.keys) {
body.add(key, maps[key]!!)
}
}
this.mBody = body.build()
Log.i("RestClientBuilder","")
return this
}
fun rawBodyForTextMap(maps: HashMap<String, String>): RestClientBuilder {
val stringBuffer = StringBuffer()
for (key in maps.keys) {
stringBuffer.append(key + "=" + maps[key] + "&")
}
var raw = stringBuffer.toString()
raw = raw.substring(0, raw.lastIndexOf("&"))
this.mBody = RequestBody.create("application/x-www-form-urlencoded;charset=UTF-8".toMediaTypeOrNull(), raw)
return this
}
fun success(iSuccess: ISuccess): RestClientBuilder {
this.mISuccess = iSuccess
return this
}
fun error(iError: IError): RestClientBuilder {
this.mIError = iError
return this
}
fun failure(iFailure: IFailure): RestClientBuilder {
this.mIFailure = iFailure
return this
}
fun file(file: File): RestClientBuilder {
this.mFile = file
return this
}
fun file(filePath: String): RestClientBuilder {
this.mFile = File(filePath)
return this
}
fun onRequest(iRequest: IRequest): RestClientBuilder {
this.mIRequest = iRequest
return this
}
fun loader(context: Context, loaderStyle: LoaderStyle): RestClientBuilder {
this.mContext = context
this.mLoaderStyle = loaderStyle
return this
}
fun loader(context: Context): RestClientBuilder {
this.mContext = context
this.mLoaderStyle = LoaderStyle.BallClipRotatePulseIndicator
return this
}
fun extension(extension: String): RestClientBuilder {
this.mExtension = extension
return this
}
fun dir(dir: String): RestClientBuilder {
this.mDownloadDir = dir
return this
}
fun name(name: String): RestClientBuilder {
this.mName = name
return this
}
fun build(): RestClient {
return RestClient(mUrl, PARAMS, mIRequest, mISuccess, mIError, mIFailure, mBody,
mLoaderStyle, mContext, mFile, mDownloadDir, mExtension, mName)
}
}
\ No newline at end of file
package com.rudian.library.net
import com.rudian.library.app.ConfigKeys
import com.rudian.library.app.HomeBozz
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.scalars.ScalarsConverterFactory
import java.util.*
import java.util.concurrent.TimeUnit
/**
* Created on 2019-08-20
* Created by xuelimin
*/
class RestCreator {
private object ParamsHolder {
val PARAMS = WeakHashMap<String, Any>()
}
fun getParams(): WeakHashMap<String, Any> {
return ParamsHolder.PARAMS
}
private object RetrofitHolder {
private val BASE_URL = HomeBozz.getConfigurations()[ConfigKeys.API_HOST] as String
internal val RETROFIT_CLIENT = Retrofit.Builder()
.baseUrl(BASE_URL)
.client(OKHttpHolder.OK_HTTP_CLIENT)
.addConverterFactory(ScalarsConverterFactory.create())
.build()
}
private object OKHttpHolder {
private val TIME_OUT = 60
private val INTERCEPTORS:ArrayList<Interceptor> = HomeBozz.getConfiguration(ConfigKeys.INTERCEPTOR)
private val BUILDER = OkHttpClient.Builder()
internal val OK_HTTP_CLIENT = addInterceptor()
.connectTimeout(TIME_OUT.toLong(), TimeUnit.SECONDS)
.build()
private fun addInterceptor(): OkHttpClient.Builder {
if (INTERCEPTORS.isEmpty()) {
for (interceptor in INTERCEPTORS) {
BUILDER.addInterceptor(interceptor)
}
}
return BUILDER
}
}
private object RestServiceHolder {
internal val REST_SERVICE = RetrofitHolder.RETROFIT_CLIENT.create(RestService::class.java)
}
fun getRestService(): RestService {
return RestServiceHolder.REST_SERVICE
}
}
\ No newline at end of file
package com.rudian.library.net
import okhttp3.MultipartBody
import okhttp3.RequestBody
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.http.*
/**
* Created on 2019-08-20
* Created by xuelimin
* retrofit2 网络请求服务
*/
interface RestService {
@GET
operator fun get(@Url url: String, @QueryMap params: Map<String, @JvmSuppressWildcards Any>): Call<String>
@FormUrlEncoded
@POST
fun post(@Url url: String, @FieldMap params: Map<String, @JvmSuppressWildcards Any>): Call<String>
@POST
fun postRaw(@Url url: String, @Body body: RequestBody): Call<String>
@FormUrlEncoded
@PUT
fun put(@Url url: String, @FieldMap params: Map<String, @JvmSuppressWildcards Any>): Call<String>
@PUT
fun putRaw(@Url url: String, @Body body: RequestBody): Call<String>
@DELETE
fun delete(@Url url: String, @QueryMap params: Map<String, @JvmSuppressWildcards Any>): Call<String>
@Streaming
@GET
fun download(@Url url: String, @QueryMap params: Map<String, @JvmSuppressWildcards Any>): Call<ResponseBody>
@Multipart
@POST
fun upload(@Url url: String, @Part file: MultipartBody.Part): Call<String>
@Multipart
@POST
fun uploadImage(@Url url: String, @Part("body") body: RequestBody, @Part file: MultipartBody.Part): Call<String>
}
\ No newline at end of file
package com.rudian.library.net.callback
/**
* Created on 2019-08-20
* Created by xuelimin
*/
interface IError {
fun onError(code: Int, msg: String)
}
\ No newline at end of file
package com.rudian.library.net.callback
/**
* Created on 2019-08-20
* Created by xuelimin
*/
interface IFailure{
fun onFailure()
}
\ No newline at end of file
package com.rudian.library.net.callback
/**
* Created on 2019-08-20
* Created by xuelimin
*/
interface IRequest {
fun onRequestStart()
fun onRequestDowning(process: Int)
fun onRequestEnd()
}
package com.rudian.library.net.callback
/**
* Created on 2019-08-20
* Created by xuelimin
*/
interface ISuccess {
fun onSuccess(response: String)
}
package com.rudian.library.net.callback
import android.os.Handler
import com.alibaba.fastjson.JSON
import com.rudian.library.app.ConfigKeys
import com.rudian.library.app.HomeBozz
import com.rudian.library.ui.HomeBozzLoader
import com.rudian.library.ui.LoaderStyle
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
/**
* Created on 2019-08-20
* Created by xuelimin
*/
class RequestCallback(request: IRequest?, success: ISuccess?, error: IError?, failure: IFailure?,
loaderStyle: LoaderStyle?) : Callback<String> {
private var REQUEST: IRequest? = null
private var SUCCESS: ISuccess? = null
private var ERROR: IError? = null
private var FAILURE: IFailure? = null
private var LOADER_STYLE: LoaderStyle? = null
private val HANDLER = Handler()
init {
this.REQUEST = request
this.SUCCESS = success
this.ERROR = error
this.FAILURE = failure
this.LOADER_STYLE = loaderStyle
}
override fun onResponse(call: Call<String>, response: Response<String>) {
if (response.isSuccessful) {
if (call.isExecuted) {
val strResponse = response.body()
val objects = JSON.parseObject(strResponse)
val returnCode = objects.getInteger("return_code")
if (returnCode != 0) {
if (ERROR != null) {
if (objects.containsKey("error")) {
val errorJson = objects.getJSONObject("error")
ERROR!!.onError(errorJson.getInteger("code"), errorJson.getString("message"))
} else {
ERROR!!.onError(0, "")
}
}
} else {
if (SUCCESS != null) {
SUCCESS!!.onSuccess(strResponse!!)
}
}
}
} else {
if (ERROR != null) {
ERROR!!.onError(response.code(), response.errorBody()!!.string())
}
}
stopLoading()
}
override fun onFailure(call: Call<String>, t: Throwable) {
FAILURE?.onFailure()
REQUEST?.onRequestEnd()
stopLoading()
}
private fun stopLoading() {
if (LOADER_STYLE != null) {
val delayed = HomeBozz.getConfiguration(ConfigKeys.LOADER_DELAYED) as Long
HANDLER.postDelayed({ HomeBozzLoader.stopLoading() }, delayed)
}
}
}
\ No newline at end of file
package com.rudian.library.net.download
import android.os.AsyncTask
import com.rudian.library.net.RestCreator
import com.rudian.library.net.callback.IError
import com.rudian.library.net.callback.IFailure
import com.rudian.library.net.callback.IRequest
import com.rudian.library.net.callback.ISuccess
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
/**
* Created on 2019-08-20
* Created by xuelimin
*/
class DownloadHandler(url: String?, request: IRequest?, success: ISuccess?, error: IError?,
failure: IFailure?, downloadDir: String?, extension: String?, name: String?) {
private var URL: String?=null
private var PARAMS = RestCreator().getParams()
private var REQUEST: IRequest?=null
private var SUCCESS: ISuccess?=null
private var ERROR: IError?=null
private var FAILURE: IFailure?=null
private var DOWNLOAD_DIR: String?=null
private var EXTENSION: String?=null
private var NAME: String?=null
init {
this.URL = url
this.REQUEST = request
this.SUCCESS = success
this.ERROR = error
this.FAILURE = failure
this.DOWNLOAD_DIR = downloadDir
this.EXTENSION = extension
this.NAME = name
}
fun handleDownload() {
if (REQUEST != null) {
REQUEST!!.onRequestStart()
}
RestCreator().getRestService().download(URL!!, PARAMS).enqueue(object : Callback<ResponseBody> {
override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
if (response.isSuccessful) {
var responseBody = response.body()
var task = SaveFileTask(REQUEST!!, SUCCESS!!)
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, DOWNLOAD_DIR, EXTENSION, responseBody, NAME)
//这里一定要注意判断,否则下载不全
if (task.isCancelled()) {
if (REQUEST != null) {
REQUEST!!.onRequestEnd()
}
}
} else {
if (ERROR != null) {
ERROR!!.onError(response.code(), response.message())
}
}
}
override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
if (FAILURE != null) {
FAILURE!!.onFailure()
}
}
})
}
}
\ No newline at end of file
package com.rudian.library.net.download
import android.content.Intent
import android.net.Uri
import android.os.AsyncTask
import android.os.Build
import androidx.core.content.FileProvider
import com.rudian.library.app.HomeBozz
import com.rudian.library.net.callback.IRequest
import com.rudian.library.net.callback.ISuccess
import com.rudian.library.util.file.FileUtil
import okhttp3.ResponseBody
import java.io.File
/**
* Created on 2019-08-20
* Created by xuelimin
*/
class SaveFileTask(request: IRequest, success: ISuccess) : AsyncTask<Any, Void, File>(){
private val REQUEST: IRequest?
private val SUCCESS: ISuccess?
init{
this.REQUEST = request
this.SUCCESS = success
}
override fun doInBackground(vararg params: Any?): File {
var downloadDir: String? = params[0] as String
var extension: String? = params[1] as String
val body = params[2] as ResponseBody
val name = params[3] as String
val `is` = body.byteStream()
if (downloadDir == null || downloadDir == "") {
downloadDir = "down_loads"
}
if (extension == null || extension == "") {
extension = ""
}
FileUtil.setRequest(REQUEST!!)
return FileUtil.writeToDisk(`is`, downloadDir, name)
}
override fun onPostExecute(file: File) {
super.onPostExecute(file)
SUCCESS?.onSuccess(file.path)
REQUEST?.onRequestEnd()
autoInstallApk(file)
}
private fun autoInstallApk(file: File) {
if (FileUtil.getExtension(file.path).equals("apk")) {
val intent = Intent()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val apkUri = FileProvider.getUriForFile(HomeBozz.getApplicationContext(),
HomeBozz.getApplicationContext().getPackageName() + ".fileprovider", file)
intent.action = Intent.ACTION_INSTALL_PACKAGE
intent.data = apkUri
intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
} else {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.action = Intent.ACTION_VIEW
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive")
}
HomeBozz.getApplicationContext().startActivity(intent)
}
}
}
\ No newline at end of file
package com.rudian.library.net.interceptors
import okhttp3.FormBody
import okhttp3.Interceptor
import java.util.*
/**
* Created on 2019-08-20
* Created by xuelimin
*/
abstract class BaseInterceptor : Interceptor {
protected fun getUrlParameters(chain: Interceptor.Chain): LinkedHashMap<String, String> {
val url = chain.request().url
val size = url.querySize
val params = LinkedHashMap<String, String>()
for (i in 0 until size) {
params[url.queryParameterName(i)] = url.queryParameterValue(i)!!
}
return params
}
private fun getUrlParameters(chain: Interceptor.Chain, key: String): String? {
val request = chain.request()
return request.url.queryParameter(key)
}
private fun getBodyparameters(chain: Interceptor.Chain): LinkedHashMap<String, String> {
val formBody = chain.request().body as FormBody?
val params = LinkedHashMap<String, String>()
val size = formBody!!.size
for (i in 0 until size) {
params[formBody.name(i)] = formBody.value(i)
}
return params
}
protected fun getBodyparameters(chain: Interceptor.Chain, key: String): String? {
return getBodyparameters(chain)[key]
}
}
\ No newline at end of file
package com.rudian.library.net.interceptors
import androidx.annotation.RawRes
import com.rudian.library.util.file.FileUtil
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaTypeOrNull
/**
* Created on 2019-08-20
* Created by xuelimin
*/
class DebugInterceptor(private val DEBUG_URL: String, private val DEBUG_RAW_ID: Int) : BaseInterceptor() {
private fun getResponse(chain: Interceptor.Chain, json: String): Response {
return Response.Builder().code(200).addHeader("Content-Type", "application/json")
.body(ResponseBody.create("application/json".toMediaTypeOrNull(), json))
.message("OK").request(chain.request()).protocol(Protocol.HTTP_1_1).build()
}
private fun debugResponse(chain: Interceptor.Chain, @RawRes rawId: Int): Response {
val json = FileUtil.getRawFile(rawId)
return getResponse(chain, json)
}
override fun intercept(chain: Interceptor.Chain): Response {
val url = chain.request().url.toString()
return if (url.contains(DEBUG_URL)) {
debugResponse(chain, DEBUG_RAW_ID)
} else chain.proceed(chain.request())
}
}
\ No newline at end of file
package com.rudian.library.ui.camera
import android.content.ContentValues
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Build
import android.provider.MediaStore
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.AppCompatButton
import android.view.Gravity
import android.view.View
import android.view.WindowManager
import com.blankj.utilcode.util.FileUtils
import com.rudian.library.R
import com.rudian.library.delagete.base.PermissionCheckerDelegate
import com.rudian.library.util.file.FileUtil
import java.io.File
/**
* Created on 2019-08-30
* Created by 薛立民
*/
class CameraHandler(private val DELEGATE: PermissionCheckerDelegate) : View.OnClickListener {
private val DIALOG: AlertDialog = AlertDialog.Builder(DELEGATE.context!!).create()
private val photoName: String
get() = FileUtil.getFileNameByTime("IMG", "png")
internal fun beginCameraDialog() {
DIALOG.show()
val window = DIALOG.window
if (window != null) {
window.setContentView(R.layout.dialog_camera_panel)
window.setGravity(Gravity.BOTTOM)
window.setWindowAnimations(R.style.AnimBottom)
window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
//设置属性
val params = window.attributes
params.width = WindowManager.LayoutParams.MATCH_PARENT
params.flags = WindowManager.LayoutParams.FLAG_DIM_BEHIND
params.dimAmount = 0.5f
window.attributes = params
window.findViewById<AppCompatButton>(R.id.photodialog_btn_cancel).setOnClickListener(this)
window.findViewById<AppCompatButton>(R.id.photodialog_btn_take).setOnClickListener(this)
window.findViewById<AppCompatButton>(R.id.photodialog_btn_native).setOnClickListener(this)
}
}
private fun takePhoto() {
val currentPhotoName = photoName
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
val tempFile = File(FileUtil.CAMERA_PHOTO_DIR, currentPhotoName)
//兼容7.0及以上的写法
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val contentValues = ContentValues(1)
contentValues.put(MediaStore.Images.Media.DATA, tempFile.path)
val uri = DELEGATE.context!!.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
//需要讲Uri路径转化为实际路径
val realFile = FileUtils.getFileByPath(FileUtil.getRealFilePath(DELEGATE.context!!, uri))
val realUri = Uri.fromFile(realFile)
CameraImageBean.instance.path = realUri
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
} else {
val fileUri = Uri.fromFile(tempFile)
CameraImageBean.instance.path = fileUri
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri)
}
DELEGATE.startActivityForResult(intent, RequestCodes.TAKE_PHOTO)
}
private fun pickPhoto() {
val intent = Intent()
intent.type = "image/*"
intent.action = Intent.ACTION_GET_CONTENT
intent.addCategory(Intent.CATEGORY_OPENABLE)
DELEGATE.startActivityForResult(Intent.createChooser(intent, "选择获取图片的方式"), RequestCodes.PICK_PHOTO)
}
override fun onClick(v: View) {
when (v.id) {
R.id.photodialog_btn_cancel -> DIALOG.cancel()
R.id.photodialog_btn_take -> {
takePhoto()
DIALOG.cancel()
}
R.id.photodialog_btn_native -> {
pickPhoto()
DIALOG.cancel()
}
}
}
}
package com.rudian.library.ui.camera
import android.net.Uri
/**
* Created on 2019-08-30
* Created by 薛立民
*/
class CameraImageBean {
var path: Uri? = null
companion object {
val instance = CameraImageBean()
}
}
package com.rudian.library.ui.camera
import android.net.Uri
import com.rudian.library.delagete.base.PermissionCheckerDelegate
import com.rudian.library.util.file.FileUtil
/**
* Created on 2019-08-30
* Created by 薛立民
*/
object HomeBozzCamera {
fun createCropFile(): Uri {
return Uri.parse(FileUtil.createFile("crop_image",
FileUtil.getFileNameByTime("IMG", "png")).path)
}
fun start(delegate: PermissionCheckerDelegate) {
CameraHandler(delegate).beginCameraDialog()
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment