はうすてんぼぶ

コードかいてて疑問に思ったことや、興味あることをつらつらと暇なときに書く場所、ここはそんな場所

保存先フォルダの任意設定について

MayViewerで画像の保存先を今までは2つぐらいの選択肢しか無かったんだけど、
ちょっと保存先を自由に選びたい、って要望をそろそろ1年ぐらい寝かしてたので実装しよう、と思ったのでトライしてみますた

とりあえずファイルを除くフォルダ一覧取得→一個下の階層へ→一覧取得→(ループ)
みたいな処理をして、Android上でこれやるならDialogに表示すればいいのかなーと考えて、Google先生に聞いてみたところ

以下のサイト様が引っかかったので、参照してかりかり書きました
Androidでファイル選択ダイアログを使う (理ろぐ)
http://relog.xii.jp/archives/2010/07/android.html

■20110616 androidフォルダ一覧からフォルダ選択(ダイアログ) - developer_of_Tyam
https://sites.google.com/site/developeroftyam/yoshiya/20110616-androidforuda-yi-lankara-xuan-ze-daiarogu

×かりかり書いた
ほとんどコピペ

上記のサイト様に書いてある方法でも必要十分なんですが、
「フォルダを一つ階層上に戻る」、
ってのと
「[OK]ボタンじゃなくて選択肢の一つに「このフォルダにする」」
って機能を入れたかったのでそこだけ変えました

こんな感じに動くので、とりあえずスクショとソースだけ貼ってみます
今回はPreferenceActivityから飛んでくるようにしてるため、
保存先フォルダが変更されたときに、summaryを変えたかったのでListenerでごりごり変えてます

スクショはこんな感じ
f:id:Silent-Bob:20110706023837p:image
f:id:Silent-Bob:20110706023838p:image
f:id:Silent-Bob:20110706023839p:image
f:id:Silent-Bob:20110706023840p:image
f:id:Silent-Bob:20110706023841p:image

1.PreferenceActivityから設定可能なようにしてる
2.とりあえず元あるやつと自由選択できる項目をDialogを表示
3.「それ以外」を押すと任意設定用のDialogを表示 ROOTはSDカード直下
4.DCIMを押したとこのスクショ ここで「このフォルダにする」を押すと
5.prefにフォルダパスを入れておいて、こんな感じにsummaryは変わる

ぐちゃぐちゃなソースはこんな感じ

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.DialogInterface.OnClickListener;
import android.content.SharedPreferences.Editor;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.widget.Toast;
public class SettingOfFolderForSavingImageUtil {
    public static final String PREF_NAME = "FOLDER_PATH_FOR_SAVING_IMAGE";
    private static final String ROOT_PATH = Environment.getExternalStorageDirectory().getPath()+"/";
    public static final String DEFAULT_FOLDER_PATH = ROOT_PATH+"MayVieweLite/SaveImg/";
    private static ChangeSummaryListener csListener;

    public static void openDialog(final Context context,ChangeSummaryListener listener){
        csListener = listener;

        //まず3or4択のダイアログを表示
        AlertDialog.Builder ad = new AlertDialog.Builder(context);
        ad.setTitle("保存先のフォルダを選択");
        String items = {"/MayViewerLite/SaveImg/","/download/","これ以外"};
        ad.setItems(items, new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                switch(which){
                case 0:
                    setFolderPathToPref(context,ROOT_PATH+"MayViewerLite/SaveImg/");
                    break;
                case 1:
                    setFolderPathToPref(context,ROOT_PATH+"download/");
                    break;
                case 2:
                    openFreeSelectDialog(context,ROOT_PATH);
                    break;
                }
            }
        });

        ad.create().show();
    }

    private static void setFolderPathToPref(Context context,String path){
        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);

        Editor e = pref.edit();
        e.putString(PREF_NAME,path);
        e.commit();

        if(csListener != null){
            csListener.changeSummaryOfPreferenceScreen("setting_of_folder_for_saving_image","現在の保存先:"+path);
        }
    }

    private static void openFreeSelectDialog(final Context context,final String parentPath){
        AlertDialog.Builder ad = new AlertDialog.Builder(context);

        ad.setTitle(parentPath);
        try{
            File files = new File(parentPath).listFiles();
           
            ArrayList<String> pathList = new ArrayList<String>();

            for (File file : files) {
                if(file.isDirectory()){
                    //ディレクトリの場合
                    pathList.add(file.getName() + "/");
                }
            }

            Collections.sort(pathList);//ソート
            pathList.add(0,"このフォルダを保存先にする");
            pathList.add(1,"←一つ前に戻る");

            //配列に変換
            final String items = (String)pathList.toArray(new String[0]);
            ad.setItems(items,
                    new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    switch(which){
                    case 0:
                        setFolderPathToPref(context,parentPath);
                        break;
                    case 1:
                        if(parentPath.equals(ROOT_PATH)){
                            Toast.makeText(context,"これ以上戻れません",Toast.LENGTH_SHORT).show();
                            openFreeSelectDialog(context,parentPath);
                        }else{
                            //parentの一つ前のパスを取得
                            String grandparentPath = parentPath.substring(0,parentPath.length()-1);
                            grandparentPath = grandparentPath.substring(0,grandparentPath.lastIndexOf("/")+1);
                            openFreeSelectDialog(context,grandparentPath);
                        }
                        break;
                    default:
                        openFreeSelectDialog(context,parentPath+""+items[which]);
                        break;
                    }
                }
            });
        }catch(Exception e){
            e.printStackTrace();
        }
        ad.create().show();
    }

    //summaryを更新する
    public interface ChangeSummaryListener{
        public void changeSummaryOfPreferenceScreen(String prefKey,String folderPath);
    }

}


PreferenceActivityはこんな感じにしてsummaryを動的に変えてます

public class MyPreferenceActivity extends PreferenceActivity implements SettingOfFolderForSavingImageUtil.ChangeSummaryListener{

//〜〜〜〜省略〜〜〜〜

        PreferenceScreen settingOfFolderForSavingImagePs = (PreferenceScreen)findPreference("setting_of_folder_for_saving_image");
        settingOfFolderForSavingImagePs.setOnPreferenceClickListener(
                new OnPreferenceClickListener(){
                    @Override
                    public boolean onPreferenceClick(Preference preference) {
                        SettingOfFolderForSavingImageUtil.openDialog(MyPreferenceActivity.this,MyPreferenceActivity.this);
                        return true;
                    }     
                }
            );

        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
        settingOfFolderForSavingImagePs.setSummary("現在の保存先:"+pref.getString(SettingOfFolderForSavingImageUtil.PREF_NAME,SettingOfFolderForSavingImageUtil.DEFAULT_FOLDER_PATH));

//〜〜〜〜省略〜〜〜〜

@Override
    public void changeSummaryOfPreferenceScreen(String prefKey, String folderPath) {
        PreferenceScreen prefScreen = (PreferenceScreen)findPreference(prefKey);
        prefScreen.setSummary(folderPath);
    }
}

要所要所を変えれば動くとは思うので、良かったら使ってみてください

しかしあれだね
2年くらい前から全然ソース書く力が上がってないよね(´・ω:;.:...