kotlinでandroid入門 外部ストレージ


### 1. 補足
端末内でアプリ外からアクセス可能なストレージという意味で
SDも含まれますが、SDの事を指しているわけでありません
SDを指定してアクセスする方法もあるようですが、アンドロイドのバージョンも関係するようで、今回はパスしてます
整理出来たら上げてみます   
    
### 2. パーミション　Android 6.0 未満
   Android 6.0 (APIレベル23)未満は、パーミッションはインストール時に確認
   なので、インストールされているということは承認されている
   AndroidManifest.xml にパーミションを宣言しておく

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

### 3. パーミション　Android 6.0 以降
   APIレベル23以降は動的にパーミションを承認
   端末、アプリで承認、未承認をインストール後に設定可能

#### 3.1. 設定の確認
  現在の設定を確認

```
   if ( PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
     // 設定済
  }
```  

#### 3.2. 拒否 & 「今後確認しない」
  拒否が確定いている場合の判断

```
   if ( PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(this, Manifest.permission.PERMISSION_DENIED)) {
      if (false == ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
         // [今後表示しない]指定 -> 拒否確定
      }
    }
```  

#### 3.3. 未許可時、確認
・リクエス
   
```
    // リクエスト識別用のユニークな値
    val REQUEST_PERMISSIONS_ID = 1000
    // リクエスト用 
    val reqPermissions = ArrayList<String>()
    // リクエスト に追加
    reqPermissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
    // パーミション確認 
    ActivityCompat.requestPermissions(this, reqPermissions.toTypedArray(), REQUEST_PERMISSIONS_ID)
```    

・結果

```
    // 承認の結果(オペレータの操作)をこのコールバックで判断
    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
        if (requestCode == REQUEST_PERMISSIONS_ID) {
            // 識別IDでリクエストを判断
            if (grantResults.isNotEmpty()) {
                // 処理された
                for (i in permissions.indices) {
                    // 複数リクエストがあった場合
                    if (permissions[i] == Manifest.permission.WRITE_EXTERNAL_STORAGE) {
                        // 外部ストレージのパーミッション
                        if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                            // 許可
                        } else {
                            // 拒否
                        }
                    }
                }    
            }    
        }        
    } 
```

#### 3.3. 実行前の確認
実際にアクセス可能かアクセス前に確認だけできるようにしておくと便利

```
    // 読み書き可能な外部ストレージがあるかどうかをチェック
    private val isExternalStorageWritable: Boolean
        get() {
            val state = Environment.getExternalStorageState()
            return Environment.MEDIA_MOUNTED == state
        }

    // 外部ストレージが読み取り可能かどうかをチェック
    private val isExternalStorageReadable: Boolean
        get() {
            val state = Environment.getExternalStorageState()
            return Environment.MEDIA_MOUNTED == state || Environment.MEDIA_MOUNTED_READ_ONLY == state
        }
```

#### 3.4. ファイル名
外部ストレージでは、フルパスでのアクセスのようです

```
    val mydirName = "ext" // 保存フォルダー
    val ExtFileName = "tmp.txt" // ファイル名

        // 現在の外部ストレージのログ・ファイル名(パス含め)
    private val extFilePath: String
        get() {
            val myDir = Environment.getExternalStorageDirectory().getPath() +"/"+mydirName
            return  myDir+"/"+ getString(ExtFileName)
        }
```

### 4. 書き込み

```
// 外部ストレージのファイルにデータを追加
    val saveData : String = "保存データ"

    // フォルダーを使用する場合、あるかを確認
    val myDir = File(Environment.getExternalStorageDirectory(), mydirName)
    if (!myDir.exists()) {
        // なければ、フォルダーを作る
        myDir.mkdirs()
    }

    val file = File(extFilePath)
    try {
        FileOutputStream(file, true).use({ fileOutputStream ->
            OutputStreamWriter(fileOutputStream, "UTF-8").use({ outputStreamWriter ->
                BufferedWriter(outputStreamWriter).use({ bw ->
                    bw.write(saveData+"\n")
                    bw.flush()
                })
            })
        })
    } catch (e: Exception) {
        e.printStackTrace()
    }
```
   
### 5. 読込

```
    val dataList : ArrayList<String> = ArrayList<String>()
    try {
        FileInputStream(extFilePath).use { fileInputStream ->
            InputStreamReader(fileInputStream, "UTF8").use { inputStreamReader ->
                BufferedReader(inputStreamReader).use { reader ->
                    for (lineBuffer in reader.readLines()) {
                        dataList.add(lineBuffer)
                    }
                }
            }
        }
   } catch (e: Exception) {
       e.printStackTrace()
   }
```        

### 5. 削除

```
   try {
        val fl = File(extFilePath)
        fl.delete()
   } catch ( e : IOException) {
        e.printStackTrace();
   }
``` 

今回で一応ストレージへのアクセスは制覇（かな）

あ、SDの指定が残ってるか