Implémenter un sélecteur de fichiers dans Android et copier le fichier sélectionné vers un autre emplacement
Je suis en train de mettre en œuvre un Sélecteur de Fichiers dans mon projet Android. Ce que j'ai pu faire jusqu'à présent est :
Intent chooseFile;
Intent intent;
chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.setType("*/*");
intent = Intent.createChooser(chooseFile, "Choose a file");
startActivityForResult(intent, PICKFILE_RESULT_CODE);
Et puis dans mon onActivityResult()
switch(requestCode){
case PICKFILE_RESULT_CODE:
if(resultCode==-1){
Uri uri = data.getData();
String filePath = uri.getPath();
Toast.makeText(getActivity(), filePath,
Toast.LENGTH_LONG).show();
}
break;
}
C'est l'ouverture d'un sélecteur de fichiers, mais ce n'est pas ce que je veux. Par exemple, je veux sélectionner un fichier (.txt), puis obtenir que File
et ensuite de l'utiliser. Avec ce code, j'ai pensé que je voudrais obtenir le chemin d'accès complet mais il n'arrive pas; par exemple, j'obtiens: /document/5318/
. Mais avec ce chemin je ne peux pas obtenir le fichier. J'ai créé une méthode appelée PathToFile()
qui renvoie un File
:
private File PathToFile(String path) {
File tempFileToUpload;
tempFileToUpload = new File(path);
return tempFileToUpload;
}
Ce que je suis en train de faire est de laisser l'utilisateur choisir un File
à partir de n'importe où signifie DropBox
Drive
SDCard
Mega
etc... Et je ne trouve pas le moyen de le faire correctement, j'ai essayé d'obtenir le Path
puis obtenir un File
par cette Path
... mais il ne fonctionne pas, donc je pense que c'est mieux de le File
lui-même, et puis avec cette File
par programmation je Copy
ce ou Delete
.
MODIFIER (code Actuel)
Mon Intent
Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.addCategory(Intent.CATEGORY_OPENABLE);
chooseFile.setType("text/plain");
startActivityForResult(
Intent.createChooser(chooseFile, "Choose a file"),
PICKFILE_RESULT_CODE
);
Là j'ai une question car je ne sais pas ce qui est pris en charge comme text/plain
mais je vais enquêter sur ce sujet, mais il n'a pas d'importance pour le moment.
Sur mon onActivityResult()
j'ai utilisé la même que @Lukas Knuth répondremais je ne sais pas si je peux Copy
ce File
à l'autre partie de mon SDcard
je suis waitting pour sa réponse.
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICKFILE_RESULT_CODE && resultCode == Activity.RESULT_OK){
Uri content_describer = data.getData();
//get the path
Log.d("Path???", content_describer.getPath());
BufferedReader reader = null;
try {
//open the user-picked file for reading:
InputStream in = getActivity().getContentResolver().openInputStream(content_describer);
//now read the content:
reader = new BufferedReader(new InputStreamReader(in));
String line;
StringBuilder builder = new StringBuilder();
while ((line = reader.readLine()) != null){
builder.append(line);
}
//Do something with the content in
text.setText(builder.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
getPath()
de @Y. S.
Je suis en train de faire ceci :
String[] projection = { MediaStore.Files.FileColumns.DATA };
Cursor cursor = getActivity().getContentResolver().query(content_describer, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(projection[0]);
cursor.moveToFirst();
cursor.close();
Log.d( "PATH-->",cursor.getString(column_index));
Est d'obtenir un NullPointerException
:
java.lang.RuntimeException: Échec de remise résultat ResultInfo{qui=null, demande=131073, résultat=-1, data=Intention { dat=file:///chemin d'accès type=text/plain flg=0x3 }} à l'activité {info.androidhive.tabsswipe/info.androidhive.tabsswipe.MainActivity2}: java.lang.NullPointerException
MODIFIER avec le code de travail grâce à @Y. S.@Lukas Knuthet @CommonsWare.
C'est le Intent
où je n'acceptons que les fichiers text/plain
.
Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.addCategory(Intent.CATEGORY_OPENABLE);
chooseFile.setType("text/plain");
startActivityForResult(
Intent.createChooser(chooseFile, "Choose a file"),
PICKFILE_RESULT_CODE
);
Sur mon onActivityResult()
- je créer un URI
où je reçois les données de la Intent
j'ai créer un File
où j'ai enregistrer le chemin absolu faire content_describer.getPath();
puis-je garder le nom du chemin d'accès de l'utiliser dans un TextView
avec content_describer.getLastPathSegment();
(qui était génial @Y. S. ne connaissais pas cette fonction), et je créer un deuxième File
que j'ai appelé destination
et j'envoie le AbsolutePath
pour créer ce File
.
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICKFILE_RESULT_CODE && resultCode == Activity.RESULT_OK){
Uri content_describer = data.getData();
String src = content_describer.getPath();
source = new File(src);
Log.d("src is ", source.toString());
String filename = content_describer.getLastPathSegment();
text.setText(filename);
Log.d("FileName is ",filename);
destination = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Test/TestTest/" + filename);
Log.d("Destination is ", destination.toString());
SetToFolder.setEnabled(true);
}
}
Aussi j'ai créé une fonction qui vous devez envoyer le source file
et destination file
que nous avons créé précédemment pour le copier dans le nouveau dossier.
private void copy(File source, File destination) throws IOException {
FileChannel in = new FileInputStream(source).getChannel();
FileChannel out = new FileOutputStream(destination).getChannel();
try {
in.transferTo(0, in.size(), out);
} catch(Exception e){
Log.d("Exception", e.toString());
} finally {
if (in != null)
in.close();
if (out != null)
out.close();
}
}
Aussi j'ai créé une fonction qui me dit si ce dossier existe ou pas (je dois envoyer le destination file
si elle n'existe pas, je créer ce dossier et si ce n'est pas que je ne fais pas rien.
private void DirectoryExist (File destination) {
if(!destination.isDirectory()) {
if(destination.mkdirs()){
Log.d("Carpeta creada","....");
}else{
Log.d("Carpeta no creada","....");
}
}
Merci encore pour votre aide, j'espère que vous profitez de ce code fait avec chacun de vous les gars 🙂
source d'informationauteur Skizo-ozᴉʞS
Vous devez vous connecter pour publier un commentaire.
ÉTAPE 1 - Utiliser l'Implicite
Intent
:De choisir un fichier à partir de l'appareil, vous devez utiliser un implicite
Intent
ÉTAPE 2 - Obtenir le chemin absolu du fichier:
Pour obtenir le chemin d'accès au fichier à partir d'un
Uri
essayez d'abord à l'aide deoù
data
est leIntent
retourné dansonActivityResult()
.Si cela ne fonctionne pas, utilisez la méthode suivante:
Au moins l'une de ces deux méthodes devraient vous permettre de les corriger, chemin d'accès complet.
ÉTAPE 3 - Copier le fichier:
Ce que vous voulez, je crois, est de copier un fichier d'un emplacement à un autre.
Pour ce faire, il est absolument nécessaire d'avoir le le chemin absolu du fichier de la source et de la destination des lieux.
Tout d'abord, obtenir le chemin absolu du fichier à l'aide de mon
getPath()
méthode ouuri.getPath()
:ou
Ensuite, créez deux
File
objets comme suit:où
CustomFolder
est le répertoire sur votre disque dur externe où vous souhaitez copier le fichier.Puis utilisez la méthode suivante pour copier un fichier d'un endroit à un autre:
De l'essayer. Cela devrait fonctionner.
Remarque: Vis-a-vis de celui de Lukas réponse - ce qu'il a fait, est d'utiliser une méthode appelée
openInputStream()
qui renvoie la contenu d'unUri
siUri
représente un fichier ou d'une URL.Une autre approche prometteuse - le
FileProvider
:Il existe un autre moyen par lequel il est possible d'obtenir un fichier d'une autre application. Si une application partage ses fichiers par le biais de la
FileProvider
il est alors possible d'obtenir uneFileDescriptor
objet qui détient des informations spécifiques sur ce fichier.Pour ce faire, utilisez la commande suivante
Intent
:et dans votre
onActivityResult()
:où
mInputPFD
est unParcelFileDescriptor
.Références:
1. Commune Intentions - Stockage de Fichiers.
2.
FileChannel
.3.
FileProvider
.4. Demander un Fichier Partagé.
Comme @CommonsWare déjà noté, Android vous donne une
Uri
qui est un concept plus abstrait qu'un chemin-fichier.Il peut désigner un simple fichier-chemin de trop, mais il peut aussi décrire une ressource qui est accessible par une application (comme
content://media/external/audio/media/710
).Si vous souhaitez que votre utilisateur de choisir n'importe quel fichier à partir du téléphone pour lire à partir de votre application, vous pouvez le faire en demandant le fichier (comme vous l'avez fait correctement), puis utilisez la
ContentResolver
pour obtenir unInputStream
pour laUri
qui est renvoyé par le sélecteur.Voici un exemple:
Important: Certains fournisseurs (comme Dropbox) magasin/cache leurs données sur le stockage externe. Vous aurez besoin d'avoir la
android.permission.READ_EXTERNAL_STORAGE
-autorisation déclaré dans votre manifeste, sinon vous obtiendrezFileNotFoundException
même si le fichier est là.Mise à jour: Oui, vous pouvez copier le fichier en lecture à partir d'un flux et d'écriture à un autre:
La suppression d'un fichier n'est probablement pas possible, puisque le fichier n'est pas appartiennent pour vous, il appartient à la demande, il a partagé avec vous. À cet effet, l'application propriétaire est responsable de la suppression du fichier.
Un
Uri
n'est pas un fichier. UnUri
est plus proche de l'URL du serveur Web. Il est opaque adresse, qui n'a de sens que pour le "serveur" (ou dans ce cas, leContentProvider
).Tout comme vous utilisez un
InputStream
de lire dans les octets représenté par une URL de site Web, vous utilisez unInputStream
de lire dans les octets représenté par leUri
. Vous recevez un tel flux de données en appelantopenInputStream()
sur unContentResolver
.Passer l'URI retourné dans onActivityResult dans cette méthode