I'm working on a proof-of-concept app so that I can implement the feature in a larger app I'm making. I'm a bit new to Java and Android Dev but hopefully this shouldn't be too simple or complex of a question.
Basically, I'm trying to read in a list of strings from a CSV file and make it usable in displaying the list on the app's Main Activity.
I'm using an external class for reading in CSV's. Here's the class code:
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; } }
Here's my main activity code:
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); } }
I'm not actually to the point of setting the mobileArray array yet. Right now I'm just trying to "extract" the information out of the List object myList...
Can someone explain to me how this is done? Maybe I'm just not understanding the List type completely. It seems like when resultList is returned in the CSVFile read method, it's returned as an List object consisting of String array objects. But I can't seem to get it to work like that.
Any help is appreciated!
FINAL EDIT (working code)
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
Now my prepArray function looks like the following:
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(); } }
Still produces the FileNotFoundException.
EDIT 2/3
Here's the log that's produced when I run the app on an actual phone with the strings.csv in a subfolder of strings (src\main\assets\strings\strings.csv) with the change you requested to the 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
A CSV file can be opened in any program, however, for most users, a CSV file is best viewed through a spreadsheet program, such as Microsoft Excel, OpenOffice Calc, or Google Docs.
On Android when you stop recording the file is sent to the operating system and then any apps which can handle file attachments will show as options to save. When this happens it it temporarily stored in the phone's Downloads folder.
Try OpenCSV - it will make your life easier.
First, add this package to your gradle
dependencies as follows
implementation 'com.opencsv:opencsv:4.6'
Then you can either do
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) { }
or
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(); }
If you want to package the .csv
file with the application and have it install on the internal storage when the app installs, create an assets
folder in your project src/main
folder (e.g., c:\myapp\app\src\main\assets\
), and put the .csv
file in there, then reference it like this in your activity:
String csvfileString = this.getApplicationInfo().dataDir + File.separatorChar + "csvfile.csv" File csvfile = new File(csvfileString);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With