これまでの総括(一旦 その2)(アンドロイド地図アプリの開発その17)

前回は、JavaクラスでGithubに上がっているmapsforgeのサンプルプログラムを一部変更したものについてまで書きました。

alasixosaka.hatenablog.com

今回は、Javaクラスで、自分で作成したものについて書きます。
その前に、前回の記事の訂正。コピペだけのJavaクラスは実はもう一つあって、Setting.javaもコピペオンリーでした。前回の記事も修正してあります。

自分で作ったJavaクラスは次のものたちです。

  • MainActivity.java
  • FileListDaialog.java

MainActivity.java

MainActivityというといかにも、アプリの本体のようですが、実は単なるメニュー画面です。だいたい、地図アプリというと、起動すると地図が画面に出てくるところを想像してしまいますが、メニューをどうするか考えて、結局起動時にメニュー画面を表示し、地図はサブ画面で表示する形にしました。どうせ、初めにGPXファイルとかを選んだりするので、メニュー画面からスタートしても不便はないと考えたためです。こうすると、地図画面からメニュー画面に戻るときも戻るボタンを押せばよいのでシンプルに操作できます。
MainActivty.javaソースコードです。

public class MainActivity extends Activity implements RadioGroup.OnCheckedChangeListener,FileListDialog.onFileListDialogListener{

    private final static int PERMISSION_REQUEST_CODE = 1;
    private final static int PERMISSION_GPS_CODE = 1001;
    private final static int CHOSE_FILE_CODE = 1002;
    public static Uri launchUrl;

    private SamplesApplication setGPS;

    private static String MAP_FILE = "";
    private static String Path ="";
    String sdPath = Environment.getExternalStorageDirectory().getPath();
    String fillter = "map";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setGPS=(SamplesApplication)getApplication();

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)  {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION,},
                    1001);
            //return;
        }

        final int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
        if (permission != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
        } else {
            clickWait();
        }
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch(requestCode) {
            case PERMISSION_REQUEST_CODE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    clickWait();
                    return;
                }
            case PERMISSION_GPS_CODE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){

                    if(ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)
                            != PackageManager.PERMISSION_GRANTED){
                        return;
                    }

                }

            default:

        }

        // アプリを終了
        this.finish();
    }
    private void clickWait(){

        Button btClick = findViewById(R.id.btRotationalView);
        Button btMFS = findViewById(R.id.btMapFileSelect);
        Button btGPX = findViewById(R.id.btGPXSelect);
        Button btPOI = findViewById(R.id.btPOISelect);
        BtListener listener = new BtListener();
        btClick.setOnClickListener(listener);
        btMFS.setOnClickListener(listener);
        btGPX.setOnClickListener(listener);
        btPOI.setOnClickListener(listener);
        RadioGroup group = (RadioGroup)findViewById(R.id.radiogroup);
        group.setOnCheckedChangeListener((RadioGroup.OnCheckedChangeListener) this);
        if(setGPS.getGPScondition()==false){
            group.check(R.id.rbOff);
        }else {
            group.check(R.id.rbOn);
        }
    }

    private class BtListener implements View.OnClickListener {
        @Override
        public void onClick(View view){
            //Intent SMV = new Intent(getApplicationContext(),SimplestMapViewer.class);
            //startActivity(SMV);
            int id = view.getId();

            switch (id) {

                case R.id.btRotationalView:
                    Intent RMV = new Intent(getApplicationContext(),RotateMapViewer.class);
                    startActivity(RMV);
                    break;
                case R.id.btMapFileSelect:
                    SharedPreferences preferences = getSharedPreferences("DATA", Context.MODE_PRIVATE);
                    MAP_FILE = preferences.getString(fillter, "berlin.map");
                    Path = preferences.getString("path", sdPath);

                    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                    intent.setType("file/*");
                    startActivityForResult(intent, CHOSE_FILE_CODE);


                    break;
                case R.id.btGPXSelect:
                    preferences = getSharedPreferences("DATA", Context.MODE_PRIVATE);
                    Path = preferences.getString("path", sdPath);
                    fillter = "gpx";
                    FileListDialog dlg = new FileListDialog(MainActivity.this);
                    dlg.setOnFileListDialogListener(MainActivity.this);
                    dlg.show(Path,Path,fillter);
                    break;

                case  R.id.btPOISelect:
                    preferences = getSharedPreferences("DATA", Context.MODE_PRIVATE);
                    Path = preferences.getString("path", sdPath);
                    fillter = "poi";
                    FileListDialog dlg2 = new FileListDialog(MainActivity.this);
                    dlg2.setOnFileListDialogListener(MainActivity.this);
                    dlg2.show(Path,Path,fillter);


            }


        }
    }
    @Override
    public void onClickFileList(File file) {
        if (file == null) {
            Toast.makeText(this, "ファイルが取得できませんでした", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, file.getName(), Toast.LENGTH_SHORT).show();
            SharedPreferences preferences = getSharedPreferences("DATA", Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = preferences.edit();
            editor.putString(fillter, file.getName());
            //editor.putString("path", file.getPath());
            editor.apply();

        }
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
        try {
            if (requestCode == CHOSE_FILE_CODE && resultCode == RESULT_OK){
                String filePath = data.getDataString();
                filePath = filePath.substring(filePath.indexOf("storage"));
                String decodefilePath = URLDecoder.decode(filePath, "utf-8");

                File file = new File(decodefilePath);
                String mapfile = (String) file.getName();
                String fpath = decodefilePath.substring(0,decodefilePath.indexOf(mapfile));

                String ext = mapfile.substring(mapfile.indexOf(".")+1);

                if (ext.equals("map")){
                    SharedPreferences preferences = getSharedPreferences("DATA", Context.MODE_PRIVATE);
                    SharedPreferences.Editor editor = preferences.edit();
                    editor.putString("map", mapfile);
                    editor.putString("path", fpath);
                    editor.apply();
                } else {
                    Toast.makeText(this, "not map file", Toast.LENGTH_SHORT).show();
                }

                Toast.makeText(MainActivity.this, mapfile, Toast.LENGTH_SHORT).show();
            }
        } catch (UnsupportedEncodingException e){
            e.printStackTrace();
        }
    }
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        if (checkedId == R.id.rbOn){
            setGPS.setGPScondition(true);

        }else{
            setGPS.setGPScondition(false);
        }

    }
}

起動するとこういう感じの画面が出ます。

f:id:alasixOsaka:20200315125949j:plain
起動時のメニュー画面
できることは、地図ファイルの選択、GPSによる位置情報を反映させるかどうか(GPSのON/OFFではない)、GPXファイルの選択、POIファイルの選択(中身の形式はGPXと同じ)、地図画面への移行となります。

FileListDialog.java

メニュー画面でファイルを選ぶボタンが3つありますが、そのうち地図ファイルの選択については、ファイルマネージャーアプリを呼び出して、そこから選択するようにしています。こいつはファイルの場所を明示してやる役割も兼ねているためです。したがって、当たり前ですが、まず初めに地図ファイルを選択する必要があります。その他のファイルGPXやPOIは同じディレクトリに置いておく必要があります。これらのファイルのディレクトリ、ファイル名はSharedPreferenceに書き込まれているので、いったん選択した後、変更がなければ毎回選びなおす必要はありません。
そして、GPXやPOIを選ぶときは、ディレクトリが決まっているので、そのディレクトリの中から、対応する拡張子のファイルを選択して表示するようにしています。そして、画面のクリックで選択が完了します。
それを行っているのが、FiliListDialogです。ソースコードは次になります。

public class FileListDialog extends Activity implements View.OnClickListener, DialogInterface.OnClickListener {

    private Context _parent = null;
    private File[] _dialog_file_list;
    private onFileListDialogListener _listener = null;
    private int _select_count = -1;
    private boolean _is_directory_select = false;
    private String fill = "";
    private ArrayList<String> arrayList ;
    private File [] finalFileList;


    public int item=0;
    final String[] items = {"Data1", "Data2", "Data3", "Data4","Data5","Data6","Data7","Data8","Data9","Data10","Data11","Data12","Data13","Data14","Data15"};
    private onFileListDialogListener listener;

    public void setDirectorySelect(boolean is){
        _is_directory_select = is;
    }

    public boolean isDirectorySelect(){
        return _is_directory_select;
    }

    public FileListDialog(Context context){
        _parent = context;
    }

    public void show (String path, String title,String fillter) {
        fill = fillter;
        arrayList = new ArrayList<>();
        try {
            _dialog_file_list = new File(path).listFiles();
            if(_dialog_file_list==null){
                if(_listener!=null){
                    //_listener.onClickFileList(null);
                }
            }else {
                //String[] list = new String[_dialog_file_list.length];
                finalFileList = new File[_dialog_file_list.length];
                int count = 0;
                String name = "";

                for (File file : _dialog_file_list){
                    if(file.isDirectory()||file.getName().endsWith(fill)) {
                        name = file.getName();
                        if (file.isDirectory()) {
                            name = name + "/";
                        }
                        arrayList.add(name);
                        finalFileList[count] = file;
                        count++;
                    }
                }
                String [] array = arrayList.toArray(new String[arrayList.size()]);
                new AlertDialog.Builder(_parent).setTitle(title).setItems(array,this).show();
            }
        }catch (SecurityException se){

        }catch (Exception e){

        }




    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        _select_count = which;
        if((_dialog_file_list==null)||(_listener==null)){

        }else {
            //File file = _dialog_file_list[which];
            File file = finalFileList[which];
            if(file.isDirectory() && !isDirectorySelect()){
                show(file.getAbsolutePath(), file.getPath(),fill);
            }else {
                _listener.onClickFileList(file);
            }
        }

    }

    @Override
    public void onClick(View v) {

    }


    public void setOnFileListDialogListener(onFileListDialogListener listener) {
        _listener = listener;
    }



    public interface onFileListDialogListener{
        public void onClickFileList(File file);
    }
}

このクラスは自分で作ったといいよりもネットの記事を参考にほとんどまねしたようなものなので、あまり胸を張って作ったとは言えないです。

次回は、Javaクラス以外のファイルについて書いてみます。