[JAVA] Implémentation facile de la navigation de fichiers Android

introduction

Android n'avait pas d'interface utilisateur standard de navigation dans les fichiers, il fallait donc l'implémenter individuellement. Le nouveau cadre d'accès au stockage a facilité l'implémentation de la lecture et de l'écriture de fichiers, je m'en souviendrai donc. Vous pouvez accéder à GoogleDrive, à la carte SD et au stockage partagé interne. L'exemple que j'ai créé est une application qui charge, modifie et enregistre des fichiers texte.

la mise en oeuvre

J'ai sélectionné "Activité de base" comme activité et j'ai écrit tout le code dans l'activité principale. Le nom du projet était "FileSample". La description relative à FloatingButton a été supprimée.

Description du code Java

MainActivity.java


package xx.xx.xx.xx.filesample;

import android.content.ClipData;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.DocumentsContract;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.Toast;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.OutputStream;

public class MainActivity extends AppCompatActivity implements View.OnTouchListener {

    static final int REQUEST_OPEN_FILE = 1001;
    static final int REQUEST_CREATE_FILE = 1002;
    static final int REQUEST_DELETE_FILE = 1003;
    enum Mode {OPEN, CREATE, DELETE};
    EditText editText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        editText = findViewById(R.id.edit_text);
        editText.setOnTouchListener(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        switch (id) {
            case R.id.action_load:
                startFileBrowser(Mode.OPEN);
                return true;
            case R.id.action_save:
                startFileBrowser(Mode.CREATE);
                return true;
            case R.id.action_delete:
                startFileBrowser(Mode.DELETE);
                return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private void startFileBrowser(Mode mode) {
        Intent intent = null;
        try {
            switch (mode) {
                case OPEN:
                    intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                    intent.setType("text/plain");   //TEXT file only
                    intent.addCategory(Intent.CATEGORY_OPENABLE);
                    startActivityForResult(Intent.createChooser(intent, "Open a file"), REQUEST_OPEN_FILE);
                    break;
                case CREATE:
                    intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
                    intent.setType("text/plain");   //TEXT file only
                    intent.putExtra(Intent.EXTRA_TITLE, "newfile.txt");
                    intent.addCategory(Intent.CATEGORY_OPENABLE);
                    startActivityForResult(Intent.createChooser(intent, "Create a file"), REQUEST_CREATE_FILE);
                    break;
                case DELETE:
                    intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                    intent.setType("text/plain");   //TEXT file only
                    intent.addCategory(Intent.CATEGORY_OPENABLE);
                    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
                    startActivityForResult(Intent.createChooser(intent, "Delete a file"), REQUEST_DELETE_FILE);
                    break;
                default:
            }
        } catch (android.content.ActivityNotFoundException ex) {
            // Potentially direct the user to the Market with a Dialog
            Toast.makeText(this, "Please install a File Browser/Manager", Toast.LENGTH_LONG).show();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // File load
        if (requestCode == REQUEST_OPEN_FILE) {
            if (resultCode == RESULT_OK && data != null) {
                Uri uri = data.getData();
                if (uri != null) {
                    editText.setText(loadStrFromUri(uri));
                }
            }
        }
        // File save
        else if (requestCode == REQUEST_CREATE_FILE) {
            if (resultCode == RESULT_OK && data != null) {
                Uri uri = data.getData();
                if (uri != null) {
                    saveStrToUri(uri, editText.getText().toString());
                }
            }
        }
        // File delete
        else if (requestCode == REQUEST_DELETE_FILE) {
            if (resultCode == RESULT_OK && data != null) {
                ClipData clipData = data.getClipData();
                if(clipData==null){  // single selection
                    Uri uri = data.getData();
                    deleteUri(uri);
                }else {  // multiple selection
                    for (int i = 0; i < clipData.getItemCount(); i++) {
                        Uri uri = clipData.getItemAt(i).getUri();
                        deleteUri(uri);
                    }
                }
            }
        }
    }

    String loadStrFromUri(Uri uri) {
        String str = "";
        Boolean loop=true;
        try {
            if (uri.getScheme().equals("content")) {
                InputStream iStream = getContentResolver().openInputStream(uri);
                if(iStream==null) loop=false;
                ByteArrayOutputStream bout = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                while (loop) {
                    int len = iStream.read(buffer);
                    if (len < 0) break;
                    bout.write(buffer, 0, len);
                }
                str = bout.toString();
            } else {
                Toast.makeText(this, "Unknown scheme", Toast.LENGTH_LONG).show();
            }
        } catch (Exception e) {
            Toast.makeText(this, "Cannot read the file:" + e.toString(), Toast.LENGTH_LONG).show();
        }
        return str;
    }

    void saveStrToUri(Uri uri, String str) {
        try {
            if (uri.getScheme().equals("content")) {
                OutputStream oStream = getContentResolver().openOutputStream(uri);
                if(oStream!=null) oStream.write(str.getBytes());
            } else {
                Toast.makeText(this, "Unknown scheme", Toast.LENGTH_LONG).show();
            }
        } catch (Exception e) {
            Toast.makeText(this, "Cannot write the file:" + e.toString(), Toast.LENGTH_LONG).show();
        }
    }

    void deleteUri(Uri uri) {
        try {
            DocumentsContract.deleteDocument(getContentResolver(), uri);
        } catch(FileNotFoundException e){
            Toast.makeText(this, "Cannot find the file:" + e.toString(), Toast.LENGTH_LONG).show();
        }
    }

    //Voici le code pour réafficher le clavier virtuel avec le toucher.
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        view.performClick();
        switch (motionEvent.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if(view == editText) showKeyboard();
                break;
        }
        return false;
    }
    void showKeyboard() {
        InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
        if(inputMethodManager != null) inputMethodManager.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
    }
}

L'appel de Intent.ACTION_OPEN_DOCUMENT ou Intent.ACTION_CREATE_DOCUMENT fait apparaître l'interface utilisateur de navigation de fichiers. Lorsque l'utilisateur sélectionne un fichier texte dans l'interface utilisateur, l'URI correspondant est renvoyé, qui est utilisé pour lire et écrire le fichier.

Description du fichier de mise en page

Dans "Activité de base", deux fichiers de mise en page "activity_main.xml" et "content_main.xml" sont créés correspondant à MainActivity.java. Parmi eux, décrivez content_main.xml comme suit et affichez l'interface utilisateur d'affichage / d'édition de texte en plein écran.

content_main.xml


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".MainActivity"
    tools:showIn="@layout/activity_main">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <EditText
            android:id="@+id/edit_text"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:inputType="textMultiLine"
            android:textIsSelectable="true" />
    </ScrollView>

</android.support.constraint.ConstraintLayout>

Description du menu

Vous pouvez sélectionner LIRE et ÉCRIRE pour les fichiers dans le menu principal. Sélectionnez LIRE pour lire le texte du fichier et l'afficher à l'écran. Sélectionnez WRITE pour écrire le texte affiché à l'écran dans un fichier.

menu_main.xml


<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="me.osdn.users.watanaby.filesample.MainActivity">
    <item
        android:id="@+id/action_load"
        android:orderInCategory="100"
        android:title="Load"
        app:showAsAction="never" />
    <item
        android:id="@+id/action_save"
        android:orderInCategory="100"
        android:title="Save"
        app:showAsAction="never" />
    <item
        android:id="@+id/action_delete"
        android:orderInCategory="100"
        android:title="Delete"
        app:showAsAction="never" />
</menu>

capture d'écran

Mode opératoire

Lorsque vous démarrez l'application, l'écran d'édition s'affiche. Appelez Charger, Enregistrer et Supprimer à partir de l'icône de menu en haut à droite de l'écran (Capture d'écran 1). Sur l'écran de navigation de fichiers, vous pouvez sélectionner le stockage dans le menu en haut à gauche (captures d'écran 2 et 3). Dans Enregistrer, vous pouvez soit saisir le nom du fichier pour en créer un nouveau, soit toucher le nom du fichier existant pour le réécrire (Capture d'écran 4). Avec Charger et Supprimer, le champ de saisie de clé n'apparaît pas (Capture d'écran 5). Avec Supprimer, vous pouvez sélectionner plusieurs fichiers en appuyant longuement sur (Capture d'écran 6). Si vous touchez «Ouvrir» en haut de l'écran après la sélection, la suppression sera exécutée.

Recommended Posts

Implémentation facile de la navigation de fichiers Android
[Android] Implémentation de ListView à défilement latéral à l'aide de RecyclerView
Un moyen simple de créer une implémentation de java.util.stream.Stream
Implémentation de la fonction de recherche
Implémentation appliquée de l'espace de chat
Mise en œuvre de la fonction de pagénation
Définition des constantes Android
Implémentation de la suppression d'ajax dans Rails
Implémentation d'une fonction similaire (Ajax)
Implémentation de la fonction de prévisualisation d'image
[Java] Implémentation du réseau Faistel
Implémentation de XLPagerTabStrip avec TabBarController
[Rails] Implémentation de la fonction de catégorie
Collection de la bibliothèque Android de "Mercariatte"
Mise en œuvre de la fonction déroulante de catégorie
[Java] [Android] Lire le fichier ini
[Rails] Implémentation de la fonction tutoriel
[Rails] Implémentation d'une fonction similaire
Liste des emplacements des fichiers hôtes
Implémentation Java de tri-tree
Implémentation de HashMap avec kotlin