wake-up-neo.net

CSV-Datei in Android-App lesen

Ich arbeite an einer Proof-of-Concept-App, damit ich die Funktion in einer größeren App implementieren kann, die ich mache. Ich bin ein bisschen neu in Java und Android Dev, aber hoffentlich sollte dies nicht zu einfach oder komplex sein.

Grundsätzlich versuche ich, eine Liste von Zeichenfolgen aus einer CSV-Datei einzulesen und für die Anzeige der Liste in der Hauptaktivität der App nutzbar zu machen.

Ich verwende eine externe Klasse zum Lesen in CSVs. Hier ist der Klassencode:

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

Hier ist mein Hauptaktivitätscode:

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

    }

}

Ich bin noch nicht so weit, das mobileArray-Array noch festzulegen. Ich versuche gerade, die Informationen aus dem List-Objekt myList zu "extrahieren" ...

Kann mir jemand erklären, wie das gemacht wird? Vielleicht verstehe ich den Listentyp nicht vollständig. Es scheint, als würde resultList in der CSVFile-Lesemethode als List-Objekt zurückgegeben, das aus String-Array-Objekten besteht. Aber ich kann nicht scheinen, dass es so funktioniert.

Jede Hilfe wird geschätzt!

FINIT EDIT (Arbeitscode)

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

    }

EDIT

Nun sieht meine prepArray-Funktion wie folgt aus:

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

    }

Erzeugt weiterhin die FileNotFoundException.

EDIT 2/3

Hier ist das Protokoll, das erstellt wird, wenn ich die App auf einem Telefon mit den Zeichenfolgen.csv in einem Unterordner mit Zeichenfolgen (src\main\assets\strings\strings.csv) mit der von Ihnen angeforderten Änderung des Codes ausführen:

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
8

Probieren Sie OpenCSV - es wird Ihnen das Leben leichter machen.

Fügen Sie dieses Paket zunächst wie folgt zu Ihren gradle-Abhängigkeiten hinzu

compile 'com.opencsv:opencsv:3.9'

Dann kannst du entweder tun

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) {

}

oder

CSVReader reader = new CSVReader(new FileReader("yourfile.csv"));
List myEntries = reader.readAll();

Nach Kommentar bearbeiten

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

Wenn Sie die .csv-Datei mit der Anwendung verpacken möchten und sie bei der Installation der App auf dem internen Speicher installieren lässt, erstellen Sie einen assets-Ordner in Ihrem Projekt src/main-Ordner (z. B. c:\myapp\app\src\main\assets\), legen Sie die .csv-Datei dort ab und verweisen Sie darauf so in Ihrer Aktivität:

String csvfileString = this.getApplicationInfo().dataDir + File.separatorChar + "csvfile.csv"
File csvfile = new File(csvfileString);
18
buradd

Das folgende Snippet liest eine CSV-Datei aus dem Ordner raw resources (die beim Kompilieren in Ihre .apk-Datei gepackt wird). 

Android erstellt standardmäßig nicht den Ordner raw. Erstellen Sie in Ihrem Projekt unter res/raw einen Raw-Ordner und kopieren Sie Ihre CSV-Datei in diesen Ordner. Behalten Sie den Namen der CSV-Datei in Kleinbuchstaben und konvertieren Sie sie in ein Textformat, wenn Sie dazu aufgefordert werden. Mein CSV-Dateiname lautet welldata.csv.

Im Snippet ist WellData die Modellklasse (mit Konstruktor, Getter und Setter) und wellDataList die ArrayList zum Speichern der Daten.

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

Neuer Kodierer für Android Studio. Ich habe nachgeforscht, wie man CSV-Dateien liest, und dies funktioniert am besten für meine Bedürfnisse. (s0, s1 usw. Zeichenfolgen wurden zu Beginn meines Programms definiert).

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

Hier ist ein einfacher Weg, der für mich funktioniert hat.

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 +
            '}';
}

}

Erstellen Sie zunächst das Verzeichnis für Ihre CSV-Quelldatei:
app -> res (Rechtsklick) -> Neu -> Android-Ressourcenverzeichnis -> Ressourcentyp (roh) -> OK 

Kopieren Sie dann Ihre .csv-Datei und fügen Sie sie in das neu erscheinende Verzeichnis ein:
raw (Rechtsklick) -> Im Explorer anzeigen

Hier ist die Quelldatei, die ich für das Projekt verwendet habe:
data.csv

Wenn Sie immer noch einen Fehler haben, finden Sie hier einen Link zum vollständigen Projekt:
Quellcode

Hoffe es hilft, viel Spaß :)

0

Das hat bei mir in Kotlin geklappt. Sie müssen die Datei myfile.csv im Ordner res/raw ablegen und sie erstellen, falls sie nicht vorhanden ist.

val inputStream: InputStream = resources.openRawResource(R.raw.myfile)
val reader = BufferedReader(InputStreamReader(inputStream, Charset.forName("UTF-8")))
reader.readLines().forEach {

    //get a string array of all items in this line
    val items = it.split(",")

    //do what you want with each item
}
0
wazawoo