安卓Intent选择CSV文件进行导入

10

我想将一个特定的CSV文件导入数据库。我使用aFileChooser库选择文件,但是CSV文件中的数据没有被导入。我错在哪里?谢谢。

@Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch(requestCode) {


     case ACTIVITY_CHOOSE_FILE1: {
           if (resultCode == RESULT_OK){
               Uri uri = data.getData();
                File file1 = com.ipaulpro.afilechooser.utils.FileUtils.getFile(uri);
                proImportCSV(file1);
            }
          }
      }
    }



ricevi_csv= (Button) findViewById(R.id.but_ricevi_csv);
    ricevi_csv.setOnClickListener(new OnClickListener() {
         @Override
         public void onClick(View v) {

         Intent chooseFile;
          Intent intent;
          chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
          chooseFile.setType("application/image");
            intent = Intent.createChooser(chooseFile, "Choose a CSV");
            startActivityForResult(intent, ACTIVITY_CHOOSE_FILE1);
          }
        });
    }


private void proImportCSV(File from){

 File root = Environment.getExternalStorageDirectory();
 File exportDir = new File(root.getAbsolutePath());
 File csvFile = new File(exportDir, getString(R.string.app_name)+".csv");

  try {
ContentValues cv = new ContentValues();
// reading CSV and writing table
CSVReader dataRead = new CSVReader(new FileReader(csvFile));
String[] vv = null;
while((vv = dataRead.readNext())!=null) {
   cv.clear();
   SimpleDateFormat currFormater  = new SimpleDateFormat("dd-MM-yyyy");
   SimpleDateFormat postFormater = new SimpleDateFormat("yyyy-MM-dd");

      String eDDte;
        try {
            Date nDate = currFormater.parse(vv[0]);
            eDDte = postFormater.format(nDate);
            cv.put(Table.DATA,eDDte);
        }
         catch (Exception e) {
        }
 cv.put(Table.C,vv[1]);
 cv.put(Table.E,vv[2]);
 cv.put(Table.U,vv[3]);
 cv.put(Table.C,vv[4]);
 SQLiteDatabase db = mHelper.getWritableDatabase();
  db.insert(Table.TABLE_NAME,null,cv);

dataRead.close();

捕获(Exception e){ Log.e("TAG",e.toString()); }


你是否收到了任何异常?我唯一奇怪的事情是你得到了“application/image”,而不是使用“text/csv”和Intent.ACTION_GET_CONTENT,而不是Intent.CATEGORY_OPENABLE。你甚至可能想要使用“new File(data.getData().getPath())”而不是“com.ipaulpro.afilechooser.utils.FileUtils.getFile(uri);” - 我昨天刚做了这个重要的CSV的东西,这对我来说似乎正常工作。你的读取看起来还不错,虽然在进入while循环之前,你可能需要调用dataRead.readNext()以确保跳过标题行(如果有的话)。 - Cruceo
你能给我展示一下你的代码吗?Intent.CATEGORY_OPENABLE 对我不起作用。 - user2847219
好的,我会把它作为答案发布。请给我一点时间从GitHub上获取它。 - Cruceo
顺便说一句,我之前关于删除ACTION_GET_CONTENT的想法是错误的。 - Cruceo
4个回答

12

使用类型为"text/csv"且类别为CATEGORY_OPENABLE的Intent打开:

private void selectCSVFile(){
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("text/csv");
    startActivityForResult(Intent.createChooser(intent, "Open CSV"), ACTIVITY_CHOOSE_FILE1);
}

现在在你的onActivityResult方法中:

case ACTIVITY_CHOOSE_FILE1: {
       if (resultCode == RESULT_OK){
            proImportCSV(new File(data.getData().getPath());
        }
      }
  }

现在我们需要修改您的proImportCSV方法,使其使用我们传回的实际文件:

private void proImportCSV(File from){
  try {
    // Delete everything above here since we're reading from the File we already have
    ContentValues cv = new ContentValues();
    // reading CSV and writing table
    CSVReader dataRead = new CSVReader(new FileReader(from)); // <--- This line is key, and why it was reading the wrong file

    SQLiteDatabase db = mHelper.getWritableDatabase(); // LEt's just put this here since you'll probably be using it a lot more than once
    String[] vv = null;
    while((vv = dataRead.readNext())!=null) {
       cv.clear();
       SimpleDateFormat currFormater  = new SimpleDateFormat("dd-MM-yyyy");
       SimpleDateFormat postFormater = new SimpleDateFormat("yyyy-MM-dd");

       String eDDte;
        try {
            Date nDate = currFormater.parse(vv[0]);
            eDDte = postFormater.format(nDate);
            cv.put(Table.DATA,eDDte);
        }
        catch (Exception e) {
        }
         cv.put(Table.C,vv[1]);
         cv.put(Table.E,vv[2]);
         cv.put(Table.U,vv[3]);
         cv.put(Table.C,vv[4]);
          db.insert(Table.TABLE_NAME,null,cv);
    } dataRead.close();

    } catch (Exception e) { Log.e("TAG",e.toString());

    }
}

3
intent.setType("text/csv");在普通文件浏览器上无效,我可以从其中选择任何文件。但它对于仅显示.csv文件的Dropbox应用程序有影响。如何在常规文件浏览器中实现相同效果? - Jemshit Iskenderov
5
尝试使用 intent.setType("text/comma-separated-values");。该语句用于设置意图类型为“text/comma-separated-values”。 - tabina

1

前面的回答已经很完美了,但你需要更改两个地方。

使用类型 "/" 打开意图,因为在 Android 的文件管理器中,如果我们使用 "text/csv",它不允许选择 csv 文件:

private void selectCSVFile(){
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("*/*");
    startActivityForResult(Intent.createChooser(intent, "Open CSV"),             ACTIVITY_CHOOSE_FILE1);
}

现在在您的onActivityResult中,修剪文件路径,因为文件路径包含存储或/storage之前的垃圾路径。因此,您需要删除这些字符,以使您的csv阅读器找到路径:
case ACTIVITY_CHOOSE_FILE1: {
       if (resultCode == RESULT_OK){
            proImportCSV(new File(data.getData().getPath().substring(15));
        }
      }
  }

更多关于文件路径的信息


1
                intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                intent.addCategory(Intent.CATEGORY_OPENABLE);
                intent.setType("text/comma-separated-values");
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                startActivityForResult(intent, CREATE_FILE);
            

1
目前你的回答不够清晰。请编辑并添加更多细节,以帮助其他人理解它如何回答所提出的问题。你可以在帮助中心找到有关如何撰写好答案的更多信息。 - Community

1

我收集了所有可能的答案:

1- 基于MIME类型:intent.setType("text/csv"); 适用于SDK_INT <= 25

2- intent.setType("text/*"); 显示所有文本格式

3- intent.setType("*/*"); 显示所有格式 @Towsif Ahamed Labib

4- intent.setType("text/comma-separated-values"); @tabina

但是以下这些类型不起作用:

intent.setType("*/.csv");

intent.setType("text");

intent.setType("aplication/csv");

intent.setType("text/*cvs");


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接