メモ > 技術 > IDE: AndroidStudio > アプリの作成(XMLレイアウト / パーミッション)
アプリの作成(XMLレイアウト / パーミッション)
■パーミッション
Marshmallow端末で、Permission利用確認をする。
http://qiita.com/mattak/items/82ba07259cfe3a2ce4b1
Android6では AndroidManifest.xml でのパーミッション指定を行った上で、
protectionLevel が dangerous 以上のパーミッションについてはさらに権限の確認を行う必要がある
■ファイル一覧を表示
以下で新規にプロジェクトを作成
プロジェクトの選択: Empty Activity
プロジェクトの名前: filelist
ビューバインディングを使えるようにする
build.gradle を変更したら「Sync Now」をクリック
マニフェストファイルを編集し、インターネットに接続できるようにする
追加場所は、ルートであるmanifestの直下でいい
manifests/AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
ビューにRecyclerViewを配置する
activity_main.xml を開き、最初から表示されているTextViewを削除し、
「Containers」内の「RecyclerView」をドラッグ&ドロップで中央に配置する
上下左右を画面の端に接続し、マージンは0にする
また、以下の設定を行う
id: filesView
layout_width: match_parent
layout_height: match_parent
リスト用のレイアウトを作成する
プロジェクトウインドウのツリーで「app → res → layout」を右クリックし、
「New → Layout resource file」を選択する
「New Resource File」ダイアログが開くので、「File name」に「list_file_cell」と入力して「OK」をクリックする
作成された list_file_cell.xml を開き、
「Text」内の「TextView」をドラッグ&ドロップで中央に配置する
上下左右を画面の端に接続し、マージンは8にする
また、以下の設定を行う
id: fileView
layout_width: wrap_content
layout_height: wrap_content
親のConstraintLayoutに以下の設定を行う
layout_width: match_parent
layout_height: wrap_content
リスト用のアダプタを作成する
プロジェクトウインドウのツリーで「app → java → org.refirio.filelist」を右クリックし、
「New → Kotlin Class/File」を選択する
「New Kotlin Class/File」ダイアログが開くので、「File name」に「FileAcapter」と入力してEnterを入力する
作成された FileAcapter を開き、以下を入力する
package org.refirio.filelist
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import java.io.File
class FileAdapter(
context: Context,
private val files: List<File>,
private val onItemClicked: (File) -> Unit
) : RecyclerView.Adapter<FileAdapter.FileViewHolder>() {
// レイアウトからViewを生成するInflater
private val inflater = LayoutInflater.from(context)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FileViewHolder {
// Viewを生成する
val view = inflater.inflate(R.layout.list_file_cell, parent, false)
// ViewHolderを作る
val viewHolder = FileViewHolder(view)
// Viewをタップしたときの処理
view.setOnClickListener {
/*
// アダプター上の家を得る
val position = viewHolder.adapterPosition
// 位置に応じたデータを得る
val timeZone = timeZones[position]
*/
// コールバックを呼び出す
onItemClicked(files[viewHolder.adapterPosition])
}
return viewHolder
}
override fun getItemCount() = files.size
override fun onBindViewHolder(holder: FileViewHolder, position: Int) {
// 位置に応じたデータを得る
val file = files[position].name
// 表示内容を更新する
holder.file.text = file
}
// Viewへの参照を持っておくViewHolder
class FileViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val file = view.findViewById<TextView>(R.id.fileView)
}
}
さらに、MainActivity を以下のように変更
package org.refirio.filelist
import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.os.Environment
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import org.refirio.filelist.databinding.ActivityMainBinding
import java.io.File
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private var currentDir : File = Environment.getExternalStorageDirectory()
private lateinit var recyclerView: RecyclerView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
binding.filesView.layoutManager = LinearLayoutManager(
this,
LinearLayoutManager.VERTICAL,
false
)
// パーミッションを確認
if (hasPermission()) {
// ファイル一覧を表示
showFiles()
}
}
private fun showFiles() {
val adapter = FileAdapter(
this,
currentDir.listFiles().toList()
) { file ->
if (file.isDirectory) {
currentDir = file
showFiles()
} else {
// Toastで表示
Toast.makeText(this, file.absolutePath, Toast.LENGTH_SHORT).show();
}
}
// リストにアダプタをセット
binding.filesView.adapter = adapter
// アプリバーに表示中のディレクトリのパスを設定する
title = currentDir.path
}
private fun hasPermission() : Boolean {
// パーミッションを持っているか確認
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
// 持っていないならパーミッションを要求
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 1)
return false
}
return true
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
//super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (!grantResults.isEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
showFiles()
} else {
finish()
}
}
override fun onBackPressed() {
if (currentDir != Environment.getExternalStorageDirectory()) {
currentDir = currentDir.parentFile
showFiles()
} else {
super.onBackPressed()
}
}
}