Application mobile: Créer un simple sélecteur de fichiers dans Android

Dans le les fenêtres système d’exploitation, vous connaissez bien Sélecteur de fichiers. Il vous aide à choisir les fichiers disponibles sur votre ordinateur. Une question dans votre esprit est de savoir s’il y a ou non quelque chose de similaire dans Android?

Application mobile: Créer un simple sélecteur de fichiers dans Android

Malheureusement, Sélecteur de fichier n’est pas disponible dans Android. Mais ne vous inquiétez pas, dans cet article, je vais vous guider pour créer un Fragment du sélecteur de fichier qui simule un Sélecteur de fichier, que vous pourrez réutiliser dans vos projets.

Application mobile: Créer un simple sélecteur de fichiers dans Android

2- Exemple de sélecteur de fichiers Android

Exemple d’aperçu :

Application mobile: Créer un simple sélecteur de fichiers dans Android

Remarque : Vous avez besoin de quelques fichiers pour tester cet exemple sur le Émulateur Android. D’accord, sur le Explorateur de fichiers de périphérique copiez des fichiers dans la fenêtre « carte SD/Télécharger » dossier, comme dans l’illustration suivante :

Application mobile: Créer un simple sélecteur de fichiers dans Android

Tout d’abord, créez un nouveau projet sur Studio Android :

  • Fichier > Nouveau > Nouveau projet > Activité vide
    • Nom: FileChooserExample
    • Nom du paquet: org.o7planning.filechooserexemple
    • Langue: Java

Deuxièmement, ajoutez le code suivant à AndroidManifest.xml afin de dire Android que, « Veuillez autoriser cette application à accéder au stockage externe de l’appareil. »




AndroidManifest.xml





    

    
        
            
                

                
            
        
    


Noter: Android 6.0+ (API niveau 23+) nécessite un niveau de sécurité plus élevé, votre application doit donc demander à l’utilisateur l’autorisation d’être accessible au stockage externe de l’appareil (voir comment gérer dans l’exemple de code).

Fragment du sélecteur de fichier

Ensuite, créez un Fragment du sélecteur de fichier, alors vous pouvez utiliser ce fragment dans de nombreux autres endroits de votre projet.

Application mobile: Créer un simple sélecteur de fichiers dans Android

Cliquez avec le bouton droit sur le projet, puis sélectionnez :

  • Fichier > Nouveau > Fragment > Fragment (Vierge)
Application mobile: Créer un simple sélecteur de fichiers dans Android
Application mobile: Créer un simple sélecteur de fichiers dans Android
Application mobile: Créer un simple sélecteur de fichiers dans Android

Après cela, ouvrez fragment_file_chooser.xml concevoir Fragment du sélecteur de fichier.

Application mobile: Créer un simple sélecteur de fichiers dans Android

Ensuite, réglez identifiant et Texte pour les composants de l’interface :

Application mobile: Créer un simple sélecteur de fichiers dans Android

fragment_file_chooser.xml





    

    

FileChooserFragment.java


package org.o7planning.filechooserexample;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;

import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class FileChooserFragment extends Fragment {

    private static final int MY_REQUEST_CODE_PERMISSION = 1000;
    private static final int MY_RESULT_CODE_FILECHOOSER = 2000;

    private Button buttonBrowse;
    private EditText editTextPath;

    private static final String LOG_TAG = "AndroidExample";

    @Override
    public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_file_chooser, container, false);

        this.editTextPath = (EditText) rootView.findViewById(R.id.editText_path);
        this.buttonBrowse = (Button) rootView.findViewById(R.id.button_browse);

        this.buttonBrowse.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                askPermissionAndBrowseFile();
            }

        });
        return rootView;
    }

    private void askPermissionAndBrowseFile()  {
        // With Android Level >= 23, you have to ask the user
        // for permission to access External Storage.
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { // Level 23

            // Check if we have Call permission
            int permisson = ActivityCompat.checkSelfPermission(this.getContext(),
                    Manifest.permission.READ_EXTERNAL_STORAGE);

            if (permisson != PackageManager.PERMISSION_GRANTED) {
                // If don't have permission so prompt the user.
                this.requestPermissions(
                        new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                        MY_REQUEST_CODE_PERMISSION
                );
                return;
            }
        }
        this.doBrowseFile();
    }

    private void doBrowseFile()  {
        Intent chooseFileIntent = new Intent(Intent.ACTION_GET_CONTENT);
        chooseFileIntent.setType("*/*");
        // Only return URIs that can be opened with ContentResolver
        chooseFileIntent.addCategory(Intent.CATEGORY_OPENABLE);

        chooseFileIntent = Intent.createChooser(chooseFileIntent, "Choose a file");
        startActivityForResult(chooseFileIntent, MY_RESULT_CODE_FILECHOOSER);
    }

    // When you have the request results
    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {

        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        //
        switch (requestCode) {
            case MY_REQUEST_CODE_PERMISSION: {

                // Note: If request is cancelled, the result arrays are empty.
                // Permissions granted (CALL_PHONE).
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    Log.i( LOG_TAG,"Permission granted!");
                    Toast.makeText(this.getContext(), "Permission granted!", Toast.LENGTH_SHORT).show();

                    this.doBrowseFile();
                }
                // Cancelled or denied.
                else {
                    Log.i(LOG_TAG,"Permission denied!");
                    Toast.makeText(this.getContext(), "Permission denied!", Toast.LENGTH_SHORT).show();
                }
                break;
            }
        }
    }


    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case MY_RESULT_CODE_FILECHOOSER:
                if (resultCode == Activity.RESULT_OK ) {
                    if(data != null)  {
                        Uri fileUri = data.getData();
                        Log.i(LOG_TAG, "Uri: " + fileUri);

                        String filePath = null;
                        try {
                            filePath = FileUtils.getPath(this.getContext(),fileUri);
                        } catch (Exception e) {
                            Log.e(LOG_TAG,"Error: " + e);
                            Toast.makeText(this.getContext(), "Error: " + e, Toast.LENGTH_SHORT).show();
                        }
                        this.editTextPath.setText(filePath);
                    }
                }
                break;
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    public String getPath()  {
        return this.editTextPath.getText().toString();
    }
}

Une fois que vous avez le FileChooserFragment, vous pouvez l’utiliser n’importe où dans le projet.

Application mobile: Créer un simple sélecteur de fichiers dans Android
Application mobile: Créer un simple sélecteur de fichiers dans Android

Ensemble identifiant et Texte pour les composants de l’interface :

Application mobile: Créer un simple sélecteur de fichiers dans Android

activité_main.xml





    

    

MainActivity.java


package org.o7planning.filechooserexample;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private FileChooserFragment fragment;
    private Button buttonShowInfo;

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

        FragmentManager fragmentManager = this.getSupportFragmentManager();
        this.fragment = (FileChooserFragment) fragmentManager.findFragmentById(R.id.fragment_fileChooser);

        this.buttonShowInfo = this.findViewById(R.id.button_showInfo);

        this.buttonShowInfo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showInfo();
            }
        });
    }

    private void showInfo()  {
        String path = this.fragment.getPath();
        Toast.makeText(this, "Path: " + path, Toast.LENGTH_LONG).show();
    }
}

FileUtils.java


package org.o7planning.filechooserexample;

import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.provider.OpenableColumns;
import android.text.TextUtils;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

public class FileUtils {

    private static final String LOG_TAG = "FileUtils";

    private static Uri contentUri = null;

    /**
     * Get a file path from a Uri. This will get the the path for Storage Access
     * Framework Documents, as well as the _data field for the MediaStore and
     * other file-based ContentProviders.
*
* Callers should check whether the path is local before assuming it * represents a local file. * * @param context The context. * @param uri The Uri to query. */ @SuppressLint("NewApi") public static String getPath(final Context context, final Uri uri) { // Check here to KITKAT or new version final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; String selection = null; String[] selectionArgs = null; // DocumentProvider if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { // ExternalStorageProvider if (isExternalStorageDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; String fullPath = getPathFromExtSD(split); if (fullPath != "") { return fullPath; } else { return null; } } // DownloadsProvider else if (isDownloadsDocument(uri)) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { final String id; Cursor cursor = null; try { cursor = context.getContentResolver().query(uri, new String[]{MediaStore.MediaColumns.DISPLAY_NAME}, null, null, null); if (cursor != null && cursor.moveToFirst()) { String fileName = cursor.getString(0); String path = Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName; if (!TextUtils.isEmpty(path)) { return path; } } } finally { if (cursor != null) { cursor.close(); } } id = DocumentsContract.getDocumentId(uri); if (!TextUtils.isEmpty(id)) { if (id.startsWith("raw:")) { return id.replaceFirst("raw:", ""); } String[] contentUriPrefixesToTry = new String[] { "content://downloads/public_downloads", "content://downloads/my_downloads" }; for (String contentUriPrefix : contentUriPrefixesToTry) { try { final Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.valueOf(id)); // final Uri contentUri = ContentUris.withAppendedId( // Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(context, contentUri, null, null); } catch (NumberFormatException e) { // In Android 8 and Android P the id is not a number return uri.getPath().replaceFirst("^/document/raw:", "").replaceFirst("^raw:", ""); } } } } else { final String id = DocumentsContract.getDocumentId(uri); final boolean isOreo = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O; if (id.startsWith("raw:")) { return id.replaceFirst("raw:", ""); } try { contentUri = ContentUris.withAppendedId( Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); } catch (NumberFormatException e) { e.printStackTrace(); } if (contentUri != null) { return getDataColumn(context, contentUri, null, null); } } } // MediaProvider else if (isMediaDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; Uri contentUri = null; if ("image".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } selection = "_id=?"; selectionArgs = new String[]{split[1]}; return getDataColumn(context, contentUri, selection, selectionArgs); } else if (isGoogleDriveUri(uri)) { return getDriveFilePath(uri, context); } } // MediaStore (and general) else if ("content".equalsIgnoreCase(uri.getScheme())) { if (isGooglePhotosUri(uri)) { return uri.getLastPathSegment(); } if (isGoogleDriveUri(uri)) { return getDriveFilePath(uri, context); } if( Build.VERSION.SDK_INT == Build.VERSION_CODES.N) { // return getFilePathFromURI(context,uri); return getMediaFilePathForN(uri, context); // return getRealPathFromURI(context,uri); } else { return getDataColumn(context, uri, null, null); } } // File else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return null; } /** * Check if a file exists on device * * @param filePath The absolute file path */ private static boolean fileExists(String filePath) { File file = new File(filePath); return file.exists(); } /** * Get full file path from external storage * * @param pathData The storage type and the relative path */ private static String getPathFromExtSD(String[] pathData) { final String type = pathData[0]; final String relativePath = "/" + pathData[1]; String fullPath = ""; // on my Sony devices (4.4.4 & 5.1.1), `type` is a dynamic string // something like "71F8-2C0A", some kind of unique id per storage // don't know any API that can get the root path of that storage based on its id. // // so no "primary" type, but let the check here for other devices if ("primary".equalsIgnoreCase(type)) { fullPath = Environment.getExternalStorageDirectory() + relativePath; if (fileExists(fullPath)) { return fullPath; } } // Environment.isExternalStorageRemovable() is `true` for external and internal storage // so we cannot relay on it. // // instead, for each possible path, check if file exists // we'll start with secondary storage as this could be our (physically) removable sd card fullPath = System.getenv("SECONDARY_STORAGE") + relativePath; if (fileExists(fullPath)) { return fullPath; } fullPath = System.getenv("EXTERNAL_STORAGE") + relativePath; if (fileExists(fullPath)) { return fullPath; } return fullPath; } private static String getDriveFilePath(Uri uri, Context context) { Uri returnUri = uri; ContentResolver contentResolver = context.getContentResolver(); Cursor returnCursor = contentResolver.query(returnUri, null, null, null, null); // Get the column indexes of the data in the Cursor, // move to the first row in the Cursor, get the data, // and display it. int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE); returnCursor.moveToFirst(); String name = (returnCursor.getString(nameIndex)); String size = (Long.toString(returnCursor.getLong(sizeIndex))); File file = new File(context.getCacheDir(), name); try { InputStream inputStream = context.getContentResolver().openInputStream(uri); FileOutputStream outputStream = new FileOutputStream(file); int read = 0; int maxBufferSize = 1 * 1024 * 1024; int bytesAvailable = inputStream.available(); // int bufferSize = 1024; int bufferSize = Math.min(bytesAvailable, maxBufferSize); final byte[] buffers = new byte[bufferSize]; while ((read = inputStream.read(buffers)) != -1) { outputStream.write(buffers, 0, read); } Log.e("File Size", "Size " + file.length()); inputStream.close(); outputStream.close(); Log.e("File Path", "Path " + file.getPath()); Log.e("File Size", "Size " + file.length()); } catch (Exception e) { Log.e(LOG_TAG, e.getMessage()); } return file.getPath(); } private static String getMediaFilePathForN(Uri uri, Context context) { Uri returnUri = uri; Cursor returnCursor = context.getContentResolver().query(returnUri, null, null, null, null); // Get the column indexes of the data in the Cursor, // move to the first row in the Cursor, get the data, // and display it. int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE); returnCursor.moveToFirst(); String name = (returnCursor.getString(nameIndex)); String size = (Long.toString(returnCursor.getLong(sizeIndex))); File file = new File(context.getFilesDir(), name); try { InputStream inputStream = context.getContentResolver().openInputStream(uri); FileOutputStream outputStream = new FileOutputStream(file); int read = 0; int maxBufferSize = 1 * 1024 * 1024; int bytesAvailable = inputStream.available(); //int bufferSize = 1024; int bufferSize = Math.min(bytesAvailable, maxBufferSize); final byte[] buffers = new byte[bufferSize]; while ((read = inputStream.read(buffers)) != -1) { outputStream.write(buffers, 0, read); } Log.e("File Size", "Size " + file.length()); inputStream.close(); outputStream.close(); Log.e("File Path", "Path " + file.getPath()); Log.e("File Size", "Size " + file.length()); } catch (Exception e) { Log.e(LOG_TAG, e.getMessage()); } return file.getPath(); } private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; final String column = "_data"; final String[] projection = {column}; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { final int index = cursor.getColumnIndexOrThrow(column); return cursor.getString(index); } } finally { if (cursor != null) { cursor.close(); } } return null; } /** * @param uri - The Uri to check. * @return - Whether the Uri authority is ExternalStorageProvider. */ private static boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } /** * @param uri - The Uri to check. * @return - Whether the Uri authority is DownloadsProvider. */ private static boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); } /** * @param uri - The Uri to check. * @return - Whether the Uri authority is MediaProvider. */ private static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); } /** * @param uri - The Uri to check. * @return - Whether the Uri authority is Google Photos. */ private static boolean isGooglePhotosUri(Uri uri) { return "com.google.android.apps.photos.content".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is Google Drive. */ private static boolean isGoogleDriveUri(Uri uri) { return "com.google.android.apps.docs.storage".equals(uri.getAuthority()) // || "com.google.android.apps.docs.storage.legacy".equals(uri.getAuthority()); } }

#Créer #simple #sélecteur #fichiers #dans #Android