SDカード内のファイルの読み書き

http://d.hatena.ne.jp/shokai/20100601/1275418503 ではandroidのContext.openFileInput, Context.openFileOutputを使ったがSDカードを読み書きするにはjava.io.FileとFileInputStream, FileOutputStreamを使わなければならないらしい。


とりあえずAndroid2.1をターゲットで。


参考

Environment.getExternalStorageDirectory()

でSDカードがマウントされているディレクトリの位置が取れる。
そもそもSDカードがマウントされているかどうかは

Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)

がtrueになるかどうかで判定できる。

this.getPackageName()

でアプリの名前が取得できる。sdカードの下にこれを使ってディレクトリを作るのが作法らしいが、別に他のディレクトリの下にも書き込めてしまう(linuxだから当たり前か)


ついでにSDカードが無かったらダイアログを出すことにした。
八角研究所 : Android で再開する Java プログラミング(14) - ダイアログを制するものがAndroidを制する!



書き込めたスクリーンショット
Android File Explorer

package org.shokai.test;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.util.*;
import android.view.*;
import android.view.View.OnClickListener;
import android.widget.*;

import java.io.OutputStream;
import java.util.*;
import java.io.*;

public class Test extends Activity implements OnClickListener{
    
    private Button buttonList, buttonSave, buttonLoad;
    private TextView textView;
    private EditText editText;
    private File dataDir;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        this.buttonList = (Button) this.findViewById(R.id.ButtonList);
        this.buttonSave = (Button) this.findViewById(R.id.ButtonSave);
        this.buttonLoad = (Button) this.findViewById(R.id.ButtonLoad);
        this.textView = (TextView) this.findViewById(R.id.TextView);
        this.editText = (EditText) this.findViewById(R.id.EditText);
        
        this.buttonList.setOnClickListener(this);
        this.buttonLoad.setOnClickListener(this);
        this.buttonSave.setOnClickListener(this);
        String status = Environment.getExternalStorageState();
        if (status.equals(Environment.MEDIA_MOUNTED)) {
            dataDir = new File(Environment.getExternalStorageDirectory(), this.getPackageName());
            dataDir.mkdirs();
        }
        else{
            new AlertDialog.Builder(this).setMessage("SDカードが必要です").setPositiveButton("OK", null).show();
        }
    }

    public void onClick(View v) {
        switch(v.getId()){
        case R.id.ButtonList :
            Log.v("button", "onClick");
            File[] files = dataDir.listFiles();
            String str = "";
            for(File f : files){
                Log.v("file list", f.getPath());
                str += f.getName() + ",";
            }
            this.textView.setText(str);
            break;
        case R.id.ButtonSave :
            Log.v("buttonSave", "書き込み開始");
            try{
                saveStr(new File(this.dataDir, "tmp.txt"), editText.getText().toString());
            }
            catch(Exception e){
                Log.e("saveStr", e.toString());
            }
            break;
        case R.id.ButtonLoad :
            Log.v("buttonLoad", "読み出し開始");
            try{
                editText.setText(loadStr(new File(this.dataDir, "tmp.txt")));
            }
            catch(Exception e){
                Log.e("loadStr", e.toString());
            }
            break;
        }
    }
    
    
    // Fileを指定して開く
    public String loadStr(File file) throws Exception{
        try{
            InputStream is = new FileInputStream(file);
            byte[] bytes = new byte[is.available()];
            is.read(bytes);
            is.close();
            return new String(bytes);
        }
        catch(Exception e){
            throw e;
        }
    }
    
    // Fileを指定して保存
    public void saveStr(File file, String str) throws Exception{
        try{
            OutputStream os = new FileOutputStream(file);
            os.write(str.getBytes());
            os.close();
        }
        catch(Exception e){
            throw e;
        }
    }
    
    
}