[JAVA] Einfache Implementierung des Durchsuchens von Android-Dateien

Einführung

Android hatte keine Standard-Benutzeroberfläche zum Durchsuchen von Dateien, daher musste diese einzeln implementiert werden. Das neue Framework für den Speicherzugriff hat es einfach gemacht, Lese- und Schreibdateien zu implementieren, daher werde ich dies berücksichtigen. Sie können auf GoogleDrive, SD-Karte und internen gemeinsam genutzten Speicher zugreifen. Das von mir erstellte Beispiel ist eine App, die Textdateien lädt, bearbeitet und speichert.

Implementierung

Ich habe "Basisaktivität" als Aktivität ausgewählt und den gesamten Code in der Hauptaktivität geschrieben. Der Projektname war "FileSample". Die Beschreibung zu FloatingButton wurde gelöscht.

Java-Codebeschreibung

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();
        }
    }

    //Unten finden Sie den Code zum erneuten Anzeigen der virtuellen Tastatur mit Berührung.
    @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);
    }
}

Durch Aufrufen von Intent.ACTION_OPEN_DOCUMENT oder Intent.ACTION_CREATE_DOCUMENT wird die Benutzeroberfläche zum Durchsuchen von Dateien aufgerufen. Wenn der Benutzer eine Textdatei in der Benutzeroberfläche auswählt, wird der entsprechende URI zurückgegeben, der zum Lesen und Schreiben der Datei verwendet wird.

Beschreibung der Layoutdatei

In "Basic Activity" werden zwei Layoutdateien "activity_main.xml" und "content_main.xml" entsprechend MainActivity.java erstellt. Beschreiben Sie unter anderem content_main.xml wie folgt und zeigen Sie die Benutzeroberfläche zum Anzeigen / Bearbeiten von Text im Vollbildmodus an.

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>

Menübeschreibung

Sie können im Hauptmenü READ und WRITE für Dateien auswählen. Wählen Sie LESEN, um den Text aus der Datei zu lesen und auf dem Bildschirm anzuzeigen. Wählen Sie SCHREIBEN, um den auf dem Bildschirm angezeigten Text in eine Datei zu schreiben.

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>

Bildschirmfoto

Funktionsweise

Wenn Sie die App starten, wird der Bearbeitungsbildschirm angezeigt. Rufen Sie über das Menüsymbol oben rechts auf dem Bildschirm Laden, Speichern und Löschen auf (Screenshot 1). Auf dem Bildschirm zum Durchsuchen von Dateien können Sie Speicher aus dem Menü oben links auswählen (Screenshots 2 und 3). Unter Speichern können Sie entweder den Dateinamen eingeben, um einen neuen zu erstellen, oder den vorhandenen Dateinamen berühren, um ihn neu zu schreiben (Screenshot 4). Beim Laden und Löschen wird das Tasteneingabefeld nicht angezeigt (Screenshot 5). Mit Löschen können Sie durch langes Drücken mehrere Dateien auswählen (Screenshot 6). Wenn Sie nach der Auswahl oben auf dem Bildschirm auf "Öffnen" tippen, wird der Löschvorgang ausgeführt.

Recommended Posts

Einfache Implementierung des Durchsuchens von Android-Dateien
[Android] Implementierung von SideVolling ListView mit RecyclerView
Einfache Möglichkeit, eine Implementierung von java.util.stream.Stream zu erstellen
Implementierung der Suchfunktion
Angewandte Implementierung von Chat-Space
Implementierung der Pagenationsfunktion
Definition von Android-Konstanten
Implementierung der Ajax-Entfernung in Rails
Implementierung einer ähnlichen Funktion (Ajax)
Implementierung der Bildvorschau
[Java] Implementierung des Faistel-Netzwerks
Implementierung von XLPagerTabStrip mit TabBarController
[Rails] Implementierung der Kategoriefunktion
Android-Bibliothekssammlung von "Mercariatte"
Implementierung der Kategorie-Pulldown-Funktion
[Java] [Android] INI-Datei lesen
[Rails] Implementierung der Tutorial-Funktion
[Rails] Implementierung einer ähnlichen Funktion
Liste der Speicherorte der Hosts
Java-Implementierung von Tri-Tree
Implementierung von HashMap mit Kotlin