2020 May 04.
2020 May 03.
参照元
https://yyyank.blogspot.com/2015/03/androidintent.html
https://alasixosaka.hatenablog.com/entry/2019/06/23/210006
端末内のファイルを一覧表示して選択
Intent.ACTION_GET_CONTENT へ startActivityForResult() すれば端末内のファイラが起動し、選択したファイルパスを取得できる。
すべてのファイルの表示
Intentに type = "*/*" とセットする。
前方のアスタリスクでMIME-Typeにすべてのタイプを、後方のアスタリスクでMIME-SubTypeにすべてのタイプを指定している。
デコード
取得したファイルパスを URLDecoder.decode(FILE_PATH, "utf-8") でデコードし、端末のパスに合ったものに再構成する。
class MainActivity : AppCompatActivity() { private lateinit var strSdParentDir: String private lateinit var strSdFullDir: String private val GET_FILE_CODE: Int = 1100 private val REQUEST_PERMISSION_EX_STORAGE = 2100 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // レイアウト上のボタンに、ファイル選択を行うメソッドを起動するリスナをセット buttonGetFile.setOnClickListener { onClick(buttonGetFile) } // 外部記憶装置へのパーミッション要求 ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), REQUEST_PERMISSION_EX_STORAGE) // 外部記憶装置パーミッション取得後 override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<String>, grantResults: IntArray) { if (requestCode == REQUEST_PERMISSION_EX_STORAGE) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { Toast.makeText(applicationContext, "ex-storage-permission true", Toast.LENGTH_LONG).show() // 外部記憶装置のパスを取得 strSdFullDir = getFullPathExtStorage(this) strSdParentDir = getFullPathExtStorage(this).replace("^.+/".toRegex(),"") } } } } fun onClick(view: View?) { if ( buttonGetFile == view ) { // レイアウト上のボタンへのクリック val getFileIntent = Intent(Intent.ACTION_GET_CONTENT) getFileIntent.type = "*/*" startActivityForResult(getFileIntent, GET_FILE_CODE) } } override fun onActivityResult(requestCode: Int , resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data ) try { if (requestCode == GET_FILE_CODE && resultCode == RESULT_OK) { // ファイラでファイルパスを取得した時 val filePath: String = data!!.getDataString() // ファイルパス文字列をプログラム扱える正しいものにする // ・URLDecoder.decodeで文字列をデコードする // ・パスを再構成する // ファイラから取得したファイルパス(decodedFilePath) /aaa/bbb/ccc/ddd // 外部記憶装置のパス(strSdFullDir) /xxx/ccc // 共通に含まれるccc(strSdParentDir)をキーに正しいファイルパス(/xxx/ccc/ddd)を取得する val decodedFilePath: String = URLDecoder.decode(filePath, "utf-8"). replace("^.*${strSdParentDir}".toRegex(), "${strSdFullDir}"). replace(":", "/") // File型インスタンス取得 val myFile = File(decodedFilePath) // インプットストリーム型インスタンス取得 val myFileInStream = FileInputStream(myFile) } } catch (e: UnsupportedEncodingException) { // 例外処理 } } // 外部記憶装置のパスを取得する protected fun getFullPathExtStorage(appContext: Context?): String { // android端末内の外部ストーリッジ確認 val sdCardFilesDirPaths = SdCardDirPaths.getSdCardFilesDirPathListForLollipop(appContext) // sort sdCardFilesDirPaths order by shorter length of path Collections.sort(sdCardFilesDirPaths, CompStringLength()) // get top path in array-sdCardFilesDirPaths val externalPath = sdCardFilesDirPaths[0] // get complete full path return externalPath.replace("/Android.*$".toRegex(), "") } }
SdCardDirPaths.java
public class SdCardDirPaths { /** * SDカードのfilesディレクトリパスのリストを取得する。 * Android5.0以上対応。 * * @param Context * @return List<String>: SDカードのfilesディレクトリパスのリスト */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) public static List<String> getSdCardFilesDirPathListForLollipop(Context context) { List<String> sdCardFilesDirPathList = new ArrayList<>(); // 外部ストーリッジのディレクトリのFile型配列を取得 // getExternalFilesDirs()はAndroid4.4から利用可能 File[] dirArr = context.getExternalFilesDirs(null); for (File dir : dirArr) { if (dir != null) { String path = dir.getAbsolutePath(); // isExternalStorageRemovableはAndroid5.0から利用できるAPI。 // 取り外し可能かどうか(SDカードかどうか)を判定している。 if (Environment.isExternalStorageRemovable(dir)) { // 取り外し可能であればSDカード。 // このパスをパスリストに加える if (!sdCardFilesDirPathList.contains(path)) { sdCardFilesDirPathList.add(path); } } } } return sdCardFilesDirPathList; } }