Je travaille sur une application de validation de principe afin de pouvoir implémenter cette fonctionnalité dans une application plus grande que je suis en train de créer. Je suis un peu nouveau sur Java et Android Dev, mais j'espère que cela ne devrait pas être une question trop simple ou complexe.
En gros, j'essaie de lire une liste de chaînes à partir d'un fichier CSV et de le rendre utilisable pour afficher la liste sur l'activité principale de l'application.
J'utilise une classe externe pour lire en CSV. Voici le code de la classe:
CSVFile.Java
package com.yourtechwhiz.listdisplay;
import Android.util.Log;
import Java.io.BufferedReader;
import Java.io.IOException;
import Java.io.InputStream;
import Java.io.InputStreamReader;
import Java.util.ArrayList;
import Java.util.List;
public class CSVFile {
InputStream inputStream;
public CSVFile(InputStream inputStream){
this.inputStream = inputStream;
}
public List read(){
List resultList = new ArrayList();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try {
String csvLine;
while ((csvLine = reader.readLine()) != null) {
String[] row = csvLine.split(",");
resultList.add(row);
Log.d("VariableTag", row[0].toString());
}
}
catch (IOException ex) {
throw new RuntimeException("Error in reading CSV file: "+ex);
}
finally {
try {
inputStream.close();
}
catch (IOException e) {
throw new RuntimeException("Error while closing input stream: "+e);
}
}
return resultList;
}
}
Voici mon code d'activité principale:
MainActivity.Java
package com.yourtechwhiz.listdisplay;
import Android.support.v7.app.AppCompatActivity;
import Android.os.Bundle;
import Android.util.Log;
import Android.widget.ArrayAdapter;
import Android.widget.ListView;
import Java.io.BufferedReader;
import Java.io.IOException;
import Java.io.InputStream;
import Java.io.InputStreamReader;
import Java.util.ArrayList;
import Java.util.List;
public class MainActivity extends AppCompatActivity {
// Array of strings that's used to display on screen
String[] mobileArray = {"Android","IPhone","WindowsMobile","Blackberry",
"WebOS","Ubuntu","Windows7","Max OS X"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
prepArray();
//Display List on Activity
ArrayAdapter adapter = new ArrayAdapter<String>(this,
R.layout.activity_listview, mobileArray);
ListView listView = (ListView) findViewById(R.id.mobile_list);
listView.setAdapter(adapter);
}
//Get list of strings from CSV ready to use
private void prepArray() {
InputStream inputStream = getResources().openRawResource(R.raw.strings);
CSVFile csvFile = new CSVFile(inputStream);
List myList = csvFile.read();
//This is where it has an error
//Set first array in myList to this new array myArray
String[] myArray = myList.get(0);
}
}
Je ne suis pas encore sur le point de définir le tableau mobileArray. En ce moment, j'essaye juste d'extraire les informations de l'objet List myList ...
Quelqu'un peut-il m'expliquer comment cela est fait? Peut-être que je ne comprends pas tout à fait le type de liste. Il semble que lorsque resultList est renvoyé dans la méthode de lecture CSVFile, il est renvoyé sous forme d'objet List composé d'objets de tableau String. Mais je n'arrive pas à le faire fonctionner comme ça.
Toute aide est appréciée!
FINAL EDIT (code de travail)
private void prepArray() {
try{
CSVReader reader = new CSVReader(new InputStreamReader(getResources().openRawResource(R.raw.strings)));//Specify asset file name
String [] nextLine;
while ((nextLine = reader.readNext()) != null) {
// nextLine[] is an array of values from the line
System.out.println(nextLine[0] + nextLine[1] + "etc...");
Log.d("VariableTag", nextLine[0]);
}
}catch(Exception e){
e.printStackTrace();
Toast.makeText(this, "The specified file was not found", Toast.LENGTH_SHORT).show();
}
}
MODIFIER
Maintenant, ma fonction prepArray ressemble à ceci:
private void prepArray() {
try{
String csvfileString = this.getApplicationInfo().dataDir + File.separatorChar + "strings.csv"
File csvfile = new File(csvfileString);
CSVReader reader = new CSVReader(new FileReader("csvfile.getAbsolutePath()"));
String [] nextLine;
while ((nextLine = reader.readNext()) != null) {
// nextLine[] is an array of values from the line
System.out.println(nextLine[0] + nextLine[1] + "etc...");
}
}catch(FileNotFoundException e){
e.printStackTrace();
Toast.makeText(this, "The specified file was not found", Toast.LENGTH_SHORT).show();
}
}
Produit toujours l’exception FileNotFoundException.
EDIT 2/3
Voici le journal généré lorsque je lance l'application sur un téléphone réel avec strings.csv dans un sous-dossier de chaînes (src\main\assets\strings\strings.csv) avec la modification que vous avez demandée au code:
03/27 17:44:01: Launching app
$ adb Push C:\Users\Roy\AndroidStudioProjects\ListDisplay\app\build\outputs\apk\app-debug.apk /data/local/tmp/com.yourtechwhiz.listdisplay
$ adb Shell pm install -r "/data/local/tmp/com.yourtechwhiz.listdisplay"
pkg: /data/local/tmp/com.yourtechwhiz.listdisplay
Success
$ adb Shell am start -n "com.yourtechwhiz.listdisplay/com.yourtechwhiz.listdisplay.MainActivity" -a Android.intent.action.MAIN -c Android.intent.category.LAUNCHER -D
Connecting to com.yourtechwhiz.listdisplay
D/HyLog: I : /data/font/config/sfconfig.dat, No such file or directory (2)
D/HyLog: I : /data/font/config/dfactpre.dat, No such file or directory (2)
D/HyLog: I : /data/font/config/sfconfig.dat, No such file or directory (2)
W/ActivityThread: Application com.yourtechwhiz.listdisplay is waiting for the debugger on port 8100...
I/System.out: Sending WAIT chunk
I/dalvikvm: Debugger is active
I/System.out: Debugger has connected
I/System.out: waiting for debugger to settle...
Connected to the target VM, address: 'localhost:8609', transport: 'socket'
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: debugger has settled (1498)
I/dalvikvm: Could not find method Android.view.Window$Callback.onProvideKeyboardShortcuts, referenced from method Android.support.v7.view.WindowCallbackWrapper.onProvideKeyboardShortcuts
W/dalvikvm: VFY: unable to resolve interface method 16152: Landroid/view/Window$Callback;.onProvideKeyboardShortcuts (Ljava/util/List;Landroid/view/Menu;I)V
D/dalvikvm: VFY: replacing opcode 0x72 at 0x0002
W/dalvikvm: VFY: unable to find class referenced in signature (Landroid/view/SearchEvent;)
I/dalvikvm: Could not find method Android.view.Window$Callback.onSearchRequested, referenced from method Android.support.v7.view.WindowCallbackWrapper.onSearchRequested
W/dalvikvm: VFY: unable to resolve interface method 16154: Landroid/view/Window$Callback;.onSearchRequested (Landroid/view/SearchEvent;)Z
D/dalvikvm: VFY: replacing opcode 0x72 at 0x0002
I/dalvikvm: Could not find method Android.view.Window$Callback.onWindowStartingActionMode, referenced from method Android.support.v7.view.WindowCallbackWrapper.onWindowStartingActionMode
W/dalvikvm: VFY: unable to resolve interface method 16158: Landroid/view/Window$Callback;.onWindowStartingActionMode (Landroid/view/ActionMode$Callback;I)Landroid/view/ActionMode;
D/dalvikvm: VFY: replacing opcode 0x72 at 0x0002
I/dalvikvm: Could not find method Android.content.res.TypedArray.getChangingConfigurations, referenced from method Android.support.v7.widget.TintTypedArray.getChangingConfigurations
W/dalvikvm: VFY: unable to resolve virtual method 455: Landroid/content/res/TypedArray;.getChangingConfigurations ()I
D/dalvikvm: VFY: replacing opcode 0x6e at 0x0002
I/dalvikvm: Could not find method Android.content.res.TypedArray.getType, referenced from method Android.support.v7.widget.TintTypedArray.getType
W/dalvikvm: VFY: unable to resolve virtual method 477: Landroid/content/res/TypedArray;.getType (I)I
D/dalvikvm: VFY: replacing opcode 0x6e at 0x0008
I/dalvikvm: Could not find method Android.widget.FrameLayout.startActionModeForChild, referenced from method Android.support.v7.widget.ActionBarContainer.startActionModeForChild
W/dalvikvm: VFY: unable to resolve virtual method 16589: Landroid/widget/FrameLayout;.startActionModeForChild (Landroid/view/View;Landroid/view/ActionMode$Callback;I)Landroid/view/ActionMode;
D/dalvikvm: VFY: replacing opcode 0x6f at 0x0002
I/dalvikvm: Could not find method Android.content.Context.getColorStateList, referenced from method Android.support.v7.content.res.AppCompatResources.getColorStateList
W/dalvikvm: VFY: unable to resolve virtual method 269: Landroid/content/Context;.getColorStateList (I)Landroid/content/res/ColorStateList;
D/dalvikvm: VFY: replacing opcode 0x6e at 0x0006
I/dalvikvm: Could not find method Android.content.res.Resources.getDrawable, referenced from method Android.support.v7.widget.ResourcesWrapper.getDrawable
W/dalvikvm: VFY: unable to resolve virtual method 418: Landroid/content/res/Resources;.getDrawable (ILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
D/dalvikvm: VFY: replacing opcode 0x6e at 0x0002
I/dalvikvm: Could not find method Android.content.res.Resources.getDrawableForDensity, referenced from method Android.support.v7.widget.ResourcesWrapper.getDrawableForDensity
W/dalvikvm: VFY: unable to resolve virtual method 420: Landroid/content/res/Resources;.getDrawableForDensity (IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
D/dalvikvm: VFY: replacing opcode 0x6e at 0x0002
E/dalvikvm: Could not find class 'Android.graphics.drawable.RippleDrawable', referenced from method Android.support.v7.widget.AppCompatImageHelper.hasOverlappingRendering
W/dalvikvm: VFY: unable to resolve instanceof 140 (Landroid/graphics/drawable/RippleDrawable;) in Landroid/support/v7/widget/AppCompatImageHelper;
D/dalvikvm: VFY: replacing opcode 0x20 at 0x000c
W/System.err: Java.io.FileNotFoundException: /csvfile.getAbsolutePath(): open failed: ENOENT (No such file or directory)
W/System.err: at libcore.io.IoBridge.open(IoBridge.Java:462)
W/System.err: at Java.io.FileInputStream.<init>(FileInputStream.Java:78)
W/System.err: at Java.io.FileInputStream.<init>(FileInputStream.Java:105)
W/System.err: at Java.io.FileReader.<init>(FileReader.Java:66)
W/System.err: at com.yourtechwhiz.listdisplay.MainActivity.prepArray(MainActivity.Java:43)
W/System.err: at com.yourtechwhiz.listdisplay.MainActivity.onCreate(MainActivity.Java:26)
W/System.err: at Android.app.Activity.performCreate(Activity.Java:5287)
W/System.err: at Android.app.Instrumentation.callActivityOnCreate(Instrumentation.Java:1087)
W/System.err: at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2145)
W/System.err: at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2231)
W/System.err: at Android.app.ActivityThread.access$700(ActivityThread.Java:139)
W/System.err: at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1401)
W/System.err: at Android.os.Handler.dispatchMessage(Handler.Java:102)
W/System.err: at Android.os.Looper.loop(Looper.Java:137)
W/System.err: at Android.app.ActivityThread.main(ActivityThread.Java:5082)
W/System.err: at Java.lang.reflect.Method.invokeNative(Native Method)
W/System.err: at Java.lang.reflect.Method.invoke(Method.Java:515)
W/System.err: at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:782)
W/System.err: at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:598)
W/System.err: at dalvik.system.NativeStart.main(Native Method)
W/System.err: Caused by: libcore.io.ErrnoException: open failed: ENOENT (No such file or directory)
W/System.err: at libcore.io.Posix.open(Native Method)
W/System.err: at libcore.io.BlockGuardOs.open(BlockGuardOs.Java:110)
W/System.err: at libcore.io.IoBridge.open(IoBridge.Java:446)
W/System.err: ... 19 more
I/Adreno-EGL: <qeglDrvAPI_eglInitialize:385>: EGL 1.4 QUALCOMM build: ()
OpenGL ES Shader Compiler Version: E031.24.00.01
Build Date: 12/27/13 Fri
Local Branch: qualcomm_only
Remote Branch:
Local Patches:
Reconstruct Branch:
D/OpenGLRenderer: Enabling debug mode 0
D/OpenGLRenderer: GL error from OpenGLRenderer: 0x502
E/OpenGLRenderer: GL_INVALID_OPERATION
Essayez OpenCSV - cela vous facilitera la vie.
Tout d’abord, ajoutez ce paquet à vos dépendances gradle
comme suit
compile 'com.opencsv:opencsv:3.9'
Ensuite, vous pouvez soit faire
import com.opencsv.CSVReader;
import Java.io.IOException;
import Java.io.FileReader;
...
try {
CSVReader reader = new CSVReader(new FileReader("yourfile.csv"));
String[] nextLine;
while ((nextLine = reader.readNext()) != null) {
// nextLine[] is an array of values from the line
System.out.println(nextLine[0] + nextLine[1] + "etc...");
}
} catch (IOException e) {
}
ou
CSVReader reader = new CSVReader(new FileReader("yourfile.csv"));
List myEntries = reader.readAll();
try {
File csvfile = new File(Environment.getExternalStorageDirectory() + "/csvfile.csv");
CSVReader reader = new CSVReader(new FileReader("csvfile.getAbsolutePath()"));
String[] nextLine;
while ((nextLine = reader.readNext()) != null) {
// nextLine[] is an array of values from the line
System.out.println(nextLine[0] + nextLine[1] + "etc...");
}
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "The specified file was not found", Toast.LENGTH_SHORT).show();
}
Si vous souhaitez conditionner le fichier .csv
avec l'application et l'installer sur le stockage interne lors de l'installation de l'application, créez un dossier assets
dans votre dossier project src/main
(par exemple, c:\myapp\app\src\main\assets\
) et insérez-y le fichier .csv
, puis faites référence comme ça dans ton activité:
String csvfileString = this.getApplicationInfo().dataDir + File.separatorChar + "csvfile.csv"
File csvfile = new File(csvfileString);
L'extrait suivant lit un fichier CSV à partir du dossier raw
resources (qui sera compressé dans votre fichier .apk
lors de la compilation).
Android par défaut ne crée pas le dossier raw
. Créez un dossier brut sous res/raw
dans votre projet et copiez-y votre fichier CSV. Conservez le nom du fichier CSV en minuscule et convertissez-le au format texte à la demande. Mon nom de fichier CSV est welldata.csv
.
Dans l'extrait, WellData
est la classe de modèle (avec constructeur, getter et setter) et wellDataList
est la ArrayList
pour stocker les données.
private void readData() {
InputStream is = getResources().openRawResource(R.raw.welldata);
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, Charset.forName("UTF-8")));
String line = "";
try {
while ((line = reader.readLine()) != null) {
// Split the line into different tokens (using the comma as a separator).
String[] tokens = line.split(",");
// Read the data and store it in the WellData POJO.
WellData wellData = new WellData();
wellData.setOwner(tokens[0]);
wellData.setApi(tokens[1]);
wellData.setLongitude(tokens[2]);
wellData.setLatitude(tokens[3]);
wellData.setProperty(tokens[4]);
wellData.setWellName(tokens[5]);
wellDataList.add(wellData);
Log.d("MainActivity" ,"Just Created " + wellData);
}
} catch (IOException e1) {
Log.e("MainActivity", "Error" + line, e1);
e1.printStackTrace();
}
}
Nouveau codeur pour Android Studio. J'ai recherché comment lire les fichiers CSV et cela répond le mieux à mes besoins. (s0, s1, etc. Les chaînes ont été définies au début de mon programme).
File fileDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File fileToGet = new File(fileDirectory,"aFileName.csv");
try {
BufferedReader br = new BufferedReader(new FileReader(fileToGet));
String line;
while ((line = br.readLine()) !=null) {
String[] tokens = line.split(",");
s0=tokens[0].toString(); s1=tokens[1].toString(); s2=tokens[2].toString();
s3=tokens[3].toString(); s4=tokens[4].toString(); s5=tokens[5].toString();
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Voici un moyen simple, qui a fonctionné pour moi.
MainActivity.Java
// Do not forget to call readWeatherData() in onCreate or wherever you need to :)
// Defining ordered collection as WeatherSample class
private List<WeatherSample> weatherSamples = new ArrayList<>();
private void readWeatherData() {
// Read the raw csv file
InputStream is = getResources().openRawResource(R.raw.data);
// Reads text from character-input stream, buffering characters for efficient reading
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, Charset.forName("UTF-8"))
);
// Initialization
String line = "";
// Initialization
try {
// Step over headers
reader.readLine();
// If buffer is not empty
while ((line = reader.readLine()) != null) {
Log.d("MyActivity","Line: " + line);
// use comma as separator columns of CSV
String[] tokens = line.split(",");
// Read the data
WeatherSample sample = new WeatherSample();
// Setters
sample.setMonth(tokens[0]);
sample.setRainfall(Double.parseDouble(tokens[1]));
sample.setSumHours(Integer.parseInt(tokens[2]));
// Adding object to a class
weatherSamples.add(sample);
// Log the object
Log.d("My Activity", "Just created: " + sample);
}
} catch (IOException e) {
// Logs error with priority level
Log.wtf("MyActivity", "Error reading data file on line" + line, e);
// Prints throwable details
e.printStackTrace();
}
}
WeatherSample.Java
public class WeatherSample {
private String month;
private double rainfall;
private int sumHours;
public String getMonth() {
return month;
}
public void setMonth(String month) {
this.month = month;
}
public double getRainfall() {
return rainfall;
}
public void setRainfall(double rainfall) {
this.rainfall = rainfall;
}
public int getSumHours() {
return sumHours;
}
public void setSumHours(int sumHours) {
this.sumHours = sumHours;
}
@Override
public String toString() {
return "WeatherSample{" +
"month='" + month + '\'' +
", rainfall=" + rainfall +
", sumHours=" + sumHours +
'}';
}
}
En ce qui concerne votre fichier CSV source, commencez par créer un répertoire:
app -> res (clic droit) -> Nouveau -> Répertoire des ressources Android -> Type de ressource (raw) -> OK
Ensuite, copiez et collez votre fichier .csv dans ce nouveau répertoire:
raw (clic droit) -> Afficher dans l'explorateur
Voici le fichier source que j'ai utilisé pour le projet:
data.csv
Si vous avez encore des erreurs, voici un lien vers le projet complet:
Code source
J'espère que ça aide, amusez-vous :)