【问题标题】:Android + KOTLIN: find folders and store their names as string arrayAndroid + KOTLIN:查找文件夹并将其名称存储为字符串数组
【发布时间】:2018-10-21 14:32:41
【问题描述】:

我有一个 PHP 脚本,它能够自动查找文件夹并将它们的名称作为字符串发送到客户端,以便它们可以在innerHTML 按钮中使用。我想在我的 Android 应用中使用 Android Studio 和 Kotlin 做完全相同的事情,但我没有找到任何具体的方法来做到这一点。

这是获取所有文件夹名称并将它们存储为数组的 PHP 代码:

$_SESSION['$folders'] =[] #initiates array
$_SESSION['$folders'] = array_filter(glob('*'), 'is_dir'); #finds subfolders in the root folder and stores their names

但是,文件夹和 PHP 脚本都在同一个目录中,因此除了 array_filter 及其消除参数 glob('*')is_dir 之外,不需要进一步的路径字符串处理,如您在上面的代码中所见,并且这就是我在 Kotlin 中寻找的“魔力”。

无法发送图片,因为我似乎在这里没有足够的声誉。

【问题讨论】:

  • 整理格式。

标签: android kotlin directory


【解决方案1】:

在 Android 中,您应该严格指定要查看的文件夹的路径。 起点可以是Environment.getExternalStorageDirectory() - 主要的共享/外部存储目录。

然后您可以使用方法dir.listFiles() 获取文件列表。如果您需要以某种方式过滤它(例如只有目录),您可以添加一个 FileFilterdir.listFiles(FileFilter { it.isDirectory })

另一个重要的事情是您必须具有读取外部存储的权限。因此,您应该添加到您的 Manifest.xml

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

从 Android 6.0 开始,您应该另外请求此权限:

Fragment.requestPermissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), READ_STORAGE_RC)

并在 Fragment.onRequestPermissionsResult 方法中处理结果。


我创建了如何一起使用它的示例。 您需要创建活动并在其中添加一个片段: 目录列表片段

class DirListFragment : Fragment() {

    private val adapter by lazy { DirListAdapter { dir = it } }
    private var dir: File by observable(Environment.getExternalStorageDirectory()) { _, _, _ -> onNewParent() }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
        inflater.inflate(R.layout.fragment_dir_list, container, false)

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        checkPermissionReadStorage(requireActivity())
        list.adapter = adapter
        up.setOnClickListener { dir = dir.parentFile }
        onNewParent()
    }

    private fun onNewParent() {
        parent.text = dir.absolutePath
        adapter.items = dir.listFiles(FileFilter { it.isDirectory })?.toList() ?: emptyList()
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == READ_STORAGE_RC && permissionGranted(requireActivity())) onNewParent()
    }

    private fun checkPermissionReadStorage(activity: Activity) {
        if (!permissionGranted(activity)) {
            requestPermissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), READ_STORAGE_RC)
        }
    }

    private fun permissionGranted(activity: Activity) =
        ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED

    private companion object {
        const val READ_STORAGE_RC = 123
    }
}

DirListAdapter

class DirListAdapter(private val clickListener: (file: File) -> Unit) :
    RecyclerView.Adapter<DirListAdapter.ViewHolder>() {

    var items by Delegates.observable(listOf<File>()) { _, _, _ -> notifyDataSetChanged() }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(parent)

    override fun getItemCount() = items.size

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.caption.text = items[position].name
        holder.caption.setOnClickListener { clickListener(items[position]) }
    }

    class ViewHolder(parent: ViewGroup) : RecyclerView.ViewHolder
        (LayoutInflater.from(parent.context).inflate(android.R.layout.simple_list_item_1, parent, false)) {

        val caption: TextView = itemView.findViewById(android.R.id.text1)
    }
}

fragment_dir_list.xml

<RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto"
        android:padding="8dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <Button
            android:id="@+id/up"
            android:text="UP"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

    <TextView
            android:id="@+id/parent"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/up"
            android:layout_marginBottom="8dp"
            android:singleLine="true"
            android:ellipsize="start"
            tools:text="Parent dir"/>

    <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/list"
            android:layout_below="@id/parent"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>

</RelativeLayout>

希望这将有助于理解基础。

【讨论】:

  • 嗨,Dima S。非常感谢您的宝贵时间和帮助!在我尝试获取文件夹名称(最终将用于完成其文件的路径)期间,我意识到资产是我正在寻找的,因为我希望我的文件夹包含子文件夹并且一切都应该是一部分的应用程序文件夹,所以我的解决方案是创建一个资产文件夹并调用我的子文件夹,如下所示: val rootpath = resources.assets.list(pic_folders) // pic_folder 是包含我需要将其名称存储为数组的子文件夹的目录显示在按钮中。再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-23
  • 1970-01-01
  • 1970-01-01
  • 2013-03-21
  • 2018-07-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多