From 523d780e2c11edcf815fa5b3eb5c4a20ac849b54 Mon Sep 17 00:00:00 2001 From: rosuh Date: Mon, 26 Nov 2018 17:47:37 +0800 Subject: [PATCH] =?UTF-8?q?:heavy=5Fminus=5Fsign:=20:fire:=20[Update]=20-?= =?UTF-8?q?=20=E7=A7=BB=E9=99=A4=E7=AC=AC=E4=B8=89=E6=96=B9=E5=BA=93=20RxP?= =?UTF-8?q?ermission=EF=BC=8C=E4=BD=BF=E7=94=A8=E5=8E=9F=E5=A7=8B=E7=9A=84?= =?UTF-8?q?=E6=9D=83=E9=99=90=E7=94=B3=E8=AF=B7=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- filepicker/build.gradle | 14 +-- .../me/rosuh/filepicker/FilePickerActivity.kt | 119 ++++++++++++------ .../filepicker/config/FilePickerManager.kt | 2 + .../me/rosuh/filepicker/utils/FileUtils.kt | 17 +++ 4 files changed, 105 insertions(+), 47 deletions(-) diff --git a/filepicker/build.gradle b/filepicker/build.gradle index 7a94227..bb82769 100644 --- a/filepicker/build.gradle +++ b/filepicker/build.gradle @@ -12,7 +12,7 @@ android { compileSdkVersion 28 defaultConfig { - minSdkVersion 22 + minSdkVersion 16 targetSdkVersion 28 versionCode 1 versionName "1.0" @@ -27,17 +27,17 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } - } +ext.supportLibVersion = '28.0.0' + dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'com.github.tbruyelle:rxpermissions:0.10.2' - implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.42' + implementation "com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.42" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'com.android.support:appcompat-v7:28.0.0' - implementation 'com.android.support:recyclerview-v7:28.0.0' - implementation 'com.android.support.constraint:constraint-layout:1.1.3' + implementation "com.android.support:appcompat-v7:${supportLibVersion}" + implementation "com.android.support:recyclerview-v7:${supportLibVersion}" + implementation "com.android.support.constraint:constraint-layout:1.1.3" testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' diff --git a/filepicker/src/main/java/me/rosuh/filepicker/FilePickerActivity.kt b/filepicker/src/main/java/me/rosuh/filepicker/FilePickerActivity.kt index 2a0201a..b3ab25c 100644 --- a/filepicker/src/main/java/me/rosuh/filepicker/FilePickerActivity.kt +++ b/filepicker/src/main/java/me/rosuh/filepicker/FilePickerActivity.kt @@ -4,11 +4,14 @@ import android.Manifest import android.app.Activity import android.content.ActivityNotFoundException import android.content.Intent +import android.content.pm.PackageManager import android.net.Uri import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.os.Environment import android.os.Environment.MEDIA_MOUNTED +import android.support.v4.app.ActivityCompat +import android.support.v4.content.ContextCompat import android.support.v7.widget.AppCompatButton import android.support.v7.widget.AppCompatImageButton import android.support.v7.widget.LinearLayoutManager @@ -19,7 +22,6 @@ import android.widget.CheckBox import android.widget.Toast import com.chad.library.adapter.base.BaseQuickAdapter import com.chad.library.adapter.base.BaseViewHolder -import com.tbruyelle.rxpermissions2.RxPermissions import me.rosuh.filepicker.bean.FileTypeEnum.COMPRESSED import me.rosuh.filepicker.bean.FileTypeEnum.DIR import me.rosuh.filepicker.bean.FileTypeEnum.IMAGE @@ -43,68 +45,105 @@ class FilePickerActivity : AppCompatActivity(), BaseQuickAdapter.OnItemClickList /** * 文件列表 */ - var mRvList: RecyclerView? = null + private var mRvList: RecyclerView? = null /** * 导航栏列表 */ - var mNavList: RecyclerView? = null + private var mNavList: RecyclerView? = null /** * 文件列表适配器 */ - var mListAdapter: BaseQuickAdapter? = null + private var mListAdapter: BaseQuickAdapter? = null /** * 导航栏列表适配器 */ - var mNavAdapter: BaseQuickAdapter? = null + private var mNavAdapter: BaseQuickAdapter? = null /** * 导航栏数据集 */ - var mNavDataSource = ArrayList() + private var mNavDataSource = ArrayList() /** * 文件夹为空时展示的空视图 */ - var mEmptyView: View? = null + private var mEmptyView: View? = null - var mBtnSelectedAll: AppCompatButton? = null - var mBtnConfirm: AppCompatButton? = null - var mBtnGoBack: AppCompatImageButton? = null - val mFilesIsChecked: AtomicBoolean? = AtomicBoolean(false) + private var mBtnSelectedAll: AppCompatButton? = null + private var mBtnConfirm: AppCompatButton? = null + private var mBtnGoBack: AppCompatImageButton? = null + private val mFilesIsChecked: AtomicBoolean? = AtomicBoolean(false) + + private val FILE_PICKER_PERMISSION_REQUEST_CODE = 10201 override fun onCreate(savedInstanceState: Bundle?) { setTheme(FilePickerManager.themeId) + super.onCreate(savedInstanceState) setContentView(R.layout.activity_file_picker) // 获取权限 - val rxPermissions = RxPermissions(this) - val dispose = rxPermissions - .request(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE) - .subscribe { - if (!it) { - Toast.makeText(this@FilePickerActivity, "未授予存储权限", Toast.LENGTH_SHORT).show() - finish() - } else { - Toast.makeText(this@FilePickerActivity, "已授予存储权限", Toast.LENGTH_SHORT).show() - if (Environment.getExternalStorageState() != MEDIA_MOUNTED) { - throw Throwable(IllegalStateException("外部存储不可用")) - } + if (setupPermission()) { + prepareLauncher() + } + } - // 根目录文件对象 - val rootFile = File(Environment.getExternalStorageDirectory().absoluteFile.toURI()) + private fun setupPermission(): Boolean { + val permissionStatus = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) + if (permissionStatus != PackageManager.PERMISSION_GRANTED) { + requestPermission() + return false + } + return true + } - // 文件列表数据集 - val listData = FileUtils.produceListDataSource(rootFile) - mNavDataSource = - FileUtils.produceNavDataSource( - mNavDataSource, - Environment.getExternalStorageDirectory().absolutePath - ) + /** + * 申请权限 + */ + private fun requestPermission() { + ActivityCompat.requestPermissions( + this@FilePickerActivity, + arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), + FILE_PICKER_PERMISSION_REQUEST_CODE + ) + } - initView(listData, mNavDataSource) + override fun onRequestPermissionsResult( + requestCode: Int, + permissions: Array, + grantResults: IntArray + ) { + when (requestCode) { + FILE_PICKER_PERMISSION_REQUEST_CODE -> { + if (grantResults.isEmpty() || grantResults[0] != PackageManager.PERMISSION_GRANTED) { + Toast.makeText(this@FilePickerActivity, "未授予存储权限", Toast.LENGTH_SHORT).show() + } else { + prepareLauncher() } } + } + } + + /** + * 在做完权限申请之后开始的真正的工作 + */ + private fun prepareLauncher() { + if (Environment.getExternalStorageState() != MEDIA_MOUNTED) { + throw Throwable(IllegalStateException("外部存储不可用")) + } + + // 根目录文件对象 + val rootFile = FileUtils.getRootFile() + + // 文件列表数据集 + val listData = FileUtils.produceListDataSource(rootFile) + mNavDataSource = + FileUtils.produceNavDataSource( + mNavDataSource, + Environment.getExternalStorageDirectory().absolutePath + ) + + initView(listData, mNavDataSource) } - fun initView(fileListData: ArrayList, fileNavData: ArrayList) { + private fun initView(fileListData: ArrayList, fileNavData: ArrayList) { mRvList = findViewById(R.id.rv_list_file_picker) mNavList = findViewById(R.id.rv_nav_file_picker) mBtnSelectedAll = findViewById(R.id.btn_selected_all_file_picker) @@ -115,7 +154,8 @@ class FilePickerActivity : AppCompatActivity(), BaseQuickAdapter.OnItemClickList mBtnConfirm!!.setOnClickListener(this) // 空视图 - mEmptyView = layoutInflater.inflate(R.layout.item_empty_view_file_picker, mRvList!!.parent as ViewGroup, false) + mEmptyView = + layoutInflater.inflate(R.layout.item_empty_view_file_picker, mRvList!!.parent as ViewGroup, false) // 列表适配器 mListAdapter = produceListAdapter(fileListData) // 导航栏适配器 @@ -188,7 +228,7 @@ class FilePickerActivity : AppCompatActivity(), BaseQuickAdapter.OnItemClickList } COMPRESSED -> { val sub = item.mFileName.substring(item.mFileName.lastIndexOf(".")) - intent.type = "application/" + sub + intent.type = "application/$sub" intent.data = Uri.parse(item.filePath) startActivity(intent) } @@ -209,11 +249,11 @@ class FilePickerActivity : AppCompatActivity(), BaseQuickAdapter.OnItemClickList * 从列表中时,需要获取目标文件夹在 nav 列表中的位置,如果没有则传入 -1 * TODO 进入下一个文件夹之前,需要先清空当前的选中状态?貌似不需要 */ - fun enterDirAndUpdateUI(iFileBean: IFileBean) { + private fun enterDirAndUpdateUI(iFileBean: IFileBean) { var pos = -1 for (data in mNavAdapter!!.data) { - if (data.dirPath.equals(iFileBean.filePath)) { + if (data.dirPath == iFileBean.filePath) { pos = mNavAdapter!!.data.indexOf(data) } } @@ -224,7 +264,7 @@ class FilePickerActivity : AppCompatActivity(), BaseQuickAdapter.OnItemClickList /** * 从导航栏中调用本方法,需要传入 pos,以便生产新的 nav adapter */ - fun enterDirAndUpdateUI(iFileBean: IFileBean, position: Int) { + private fun enterDirAndUpdateUI(iFileBean: IFileBean, position: Int) { // 获取文件夹文件 val nextFiles = File(iFileBean.filePath) // 获取列表的数据集 @@ -262,7 +302,6 @@ class FilePickerActivity : AppCompatActivity(), BaseQuickAdapter.OnItemClickList override fun onBackPressed() { super.onBackPressed() - } override fun onClick(v: View?) { diff --git a/filepicker/src/main/java/me/rosuh/filepicker/config/FilePickerManager.kt b/filepicker/src/main/java/me/rosuh/filepicker/config/FilePickerManager.kt index 73efcb2..28f120d 100644 --- a/filepicker/src/main/java/me/rosuh/filepicker/config/FilePickerManager.kt +++ b/filepicker/src/main/java/me/rosuh/filepicker/config/FilePickerManager.kt @@ -38,5 +38,7 @@ object FilePickerManager { var selfFilter: FileFilter?= null + var isUseSelfTheme:Boolean = false + var themeId:Int = R.style.FilePickerThemeRail } \ No newline at end of file diff --git a/filepicker/src/main/java/me/rosuh/filepicker/utils/FileUtils.kt b/filepicker/src/main/java/me/rosuh/filepicker/utils/FileUtils.kt index e3208b1..23cfccb 100644 --- a/filepicker/src/main/java/me/rosuh/filepicker/utils/FileUtils.kt +++ b/filepicker/src/main/java/me/rosuh/filepicker/utils/FileUtils.kt @@ -1,10 +1,12 @@ package me.rosuh.filepicker.utils +import android.os.Environment import me.rosuh.filepicker.bean.FileItemBean import me.rosuh.filepicker.bean.FileNavBean import me.rosuh.filepicker.bean.FileTypeEnum import me.rosuh.filepicker.bean.FileTypeEnum.DIR import me.rosuh.filepicker.config.FilePickerManager +import me.rosuh.filepicker.config.StorageMediaTypeEnum.EXTERNAL_STORAGE import java.io.File /** @@ -15,6 +17,21 @@ import java.io.File class FileUtils { companion object { + /** + * 根据配置参数获取根目录文件 + * @return File + */ + fun getRootFile():File{ + when(FilePickerManager.mediaStorageType){ + EXTERNAL_STORAGE -> { + return File(Environment.getExternalStorageDirectory().absoluteFile.toURI()) + } + else -> { + return File(Environment.getExternalStorageDirectory().absoluteFile.toURI()) + } + } + } + /** * 根据传入的文件名返回文件类型 * 判断的方式是根据文件的后缀名