Android + KOTLIN: найти папки и сохранить их имена в виде строкового массива - PullRequest
0 голосов
/ 21 октября 2018

У меня есть 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.

Не удалось отправить фотографии, потому что, похоже, у меня здесь недостаточно репутации.

1 Ответ

0 голосов
/ 21 октября 2018

В Android вы должны строго указывать путь к папке, которую вы хотите просмотреть.Начальная точка может быть Environment.getExternalStorageDirectory() - основной каталог общего / внешнего хранилища.

Тогда вы можете получить список файлов с методом dir.listFiles().Если вам нужно как-то его отфильтровать (например, иметь только каталоги), вы можете добавить FileFilter : dir.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 метод.


Я создал пример того, как его можно использовать вместе.Вам нужно создать действие и добавить фрагмент внутри: DirListFragment

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)
    }
}

фрагмент_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>

Надеюсь, это поможет понять основы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...