0

It turns out that I want to export a sqlite database in android studio to a CSV file. The error it gives is that it cannot find the file or the directory. The specific error is the following: /storage/emulated/0/ExportarSQLiteCSV/Libros.csv: open failed: ENOENT (No such file or directory)

I have reviewed the permissions of the android manifest and I think I have the necessary ones.

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.biblioteca">
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.hardware.location.gps" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE " />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Biblioteca">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".Alta"
            android:exported="true"> </activity>
        <activity android:name=".Modificar"
            android:exported="true"> </activity>

    </application>


</manifest>

Also in the code I do a test to see if both the folder and the file exist and in both cases they tell me that they do exist. This is the main:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    conn = new ConexionSQLiteHelper(this, "bdlibros", null, 1);

    btnAlta = findViewById(R.id.btn_alta);
    btnOrdenarPor = findViewById(R.id.btn_ordenarPor);
    btnExportarDatos = findViewById(R.id.btn_exportarDatos);
    tvRegistros = findViewById(R.id.tv_registros);
    tvOrdenarPor = findViewById(R.id.tv_orden);

    pedirPermisos();
    numRegistros();
    consultarListaLibros();

    adaptador = new MiAdaptador(listaLibros, this, this);

    //crear objeto adaptador
    lm = new LinearLayoutManager(this);
    rv = findViewById(R.id.recyclerView);
    rv.setLayoutManager(lm);
    rv.setAdapter(adaptador);

    resultLauncher = registerForActivityResult(//Necesitamos el result launcher para poder invocarlo retornando datos
            new ActivityResultContracts.StartActivityForResult(),
            new ActivityResultCallback<ActivityResult>() {
                @Override
                public void onActivityResult(ActivityResult result) {
                    Intent data = result.getData();//Para acceder a los datos devueltos
                    if(result.getResultCode() == Activity.RESULT_OK){//Si ha sido result_ok devolvemos los parametros
                        if (data != null && (!data.getStringExtra("TITULO").equals(""))) {//Si no es nulo hacemos las acciones que sean con los datos devueltos
                            listaLibros.get(pos).setId(data.getIntExtra("ID", -1));
                            listaLibros.get(pos).setCategoria(data.getStringExtra("TIPO"));
                            listaLibros.get(pos).setTitulo(data.getStringExtra("TITULO"));
                            listaLibros.get(pos).setAutor(data.getStringExtra("AUTOR"));
                            listaLibros.get(pos).setIdioma(data.getStringExtra("IDIOMA"));
                            listaLibros.get(pos).setFormato(data.getStringExtra("FORMATO"));
                            listaLibros.get(pos).setFechaLecturaIni(data.getLongExtra("FECHA INICIO", -1));
                            listaLibros.get(pos).setFechaLecturaFin(data.getLongExtra("FECHA FIN", -1));
                            listaLibros.get(pos).setValoracion(data.getFloatExtra("VALORACION", -1));
                            listaLibros.get(pos).setPrestadoA(data.getStringExtra("PRESTADO"));
                            listaLibros.get(pos).setNotas(data.getStringExtra("NOTAS"));
                            adaptador.notifyDataSetChanged();
                        }
                    }
                }
            }
    );

    adaptador.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Toast.makeText(getApplicationContext(), "Selección: " +
                    listaLibros.get(rv.getChildAdapterPosition(view)).getTitulo(),
                    Toast.LENGTH_SHORT).show();
            pos = rv.getChildAdapterPosition(view);
            Intent actividad = new Intent(MainActivity.this, Modificar.class);
            actividad.putExtra("ID", listaLibros.get(pos).getId());
            actividad.putExtra("TIPO", listaLibros.get(pos).getCategoria());
            actividad.putExtra("TITULO", listaLibros.get(pos).getTitulo());
            actividad.putExtra("AUTOR", listaLibros.get(pos).getAutor());
            actividad.putExtra("IDIOMA", listaLibros.get(pos).getIdioma());
            actividad.putExtra("FORMATO", listaLibros.get(pos).getFormato());
            actividad.putExtra("FECHA INICIO", listaLibros.get(pos).getFechaLecturaIni());
            actividad.putExtra("FECHA FIN", listaLibros.get(pos).getFechaLecturaFin());
            actividad.putExtra("VALORACION", listaLibros.get(pos).getValoracion());
            actividad.putExtra("PRESTADO", listaLibros.get(pos).getPrestadoA());
            actividad.putExtra("NOTAS", listaLibros.get(pos).getNotas());
            resultLauncher.launch(actividad);
        }
    });
    
    adaptador.notifyDataSetChanged();

    btnAlta.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent actividad = new Intent(MainActivity.this, Alta.class);
            //resultLauncher.launch(actividad);
            startActivity(actividad);

            //Para redirigir a una página web
            //Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://code.tutsplus.com"));
            //startActivity(intent);
        }
    });

    btnOrdenarPor.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            FragmentoOrdenarPor fop = new FragmentoOrdenarPor();
            fop.show(getSupportFragmentManager(), "fop");
        }
    });

    btnExportarDatos.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            exportarDatos();
        }
    });

}

This is the function where I want to export:

public void exportarDatos() {
    File carpeta = new File(Environment.getExternalStorageDirectory() + "/ExportarSQLiteCSV");

    boolean isCreateCarpeta = false;
    if(!carpeta.exists()) {
        isCreateCarpeta = carpeta.mkdir();
        Toast.makeText(MainActivity.this, "Existe la carpeta", Toast.LENGTH_SHORT).show();
    }

    File archivo = new File(carpeta, "Libros.csv");
    boolean isCreate = false;
    if(!archivo.exists()) {
        isCreate = archivo.mkdir();
        Toast.makeText(MainActivity.this, "Existe", Toast.LENGTH_SHORT).show();
    }
    else {
        Toast.makeText(MainActivity.this, "No existe", Toast.LENGTH_SHORT).show();
    }

    checkExternalStoragePermission();

    try {
        FileWriter fileWriter = new FileWriter(archivo);
        conn = new ConexionSQLiteHelper(this, "bdlibros", null, 1);
        SQLiteDatabase db = conn.getWritableDatabase();
        Toast.makeText(MainActivity.this, "Buenas", Toast.LENGTH_SHORT).show();

        Cursor fila = db.rawQuery("SELECT * FROM " + Utilidades.TABLA_LIBROS, null);
        Toast.makeText(MainActivity.this, fila.toString() + " a " + fila.getCount(), Toast.LENGTH_SHORT).show();
        if(fila != null && fila.getCount() != 0) {
            fila.moveToFirst();
            do {
                fileWriter.append(fila.getInt(0) + " \n");
                fileWriter.append(fila.getString(1) + " \n");
                fileWriter.append(fila.getString(2) + " \n");
                fileWriter.append(fila.getString(3) + " \n");
            } while(fila.moveToNext());
        }
        else {
            Toast.makeText(MainActivity.this, "No hay registros", Toast.LENGTH_SHORT).show();
        }

        fila.close();
        db.close();
        fileWriter.close();
        Toast.makeText(MainActivity.this, "Se creó exitosamente el archivo CSV", Toast.LENGTH_SHORT).show();
    }
    catch(Exception e) {
        Log.i("Mensaje", e.getMessage());
        Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
    }
}

Here are the methods where I give the permissions manually:

public void pedirPermisos() {
    if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(MainActivity.this, new String[] {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE }, 0);
    }
}

private void checkExternalStoragePermission() {
    int permissionCheck = ContextCompat.checkSelfPermission(
            this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
        Log.i("Mensaje", "No se tiene permiso para leer.");
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 225);
    } else {
        Log.i("Mensaje", "Se tiene permiso para leer!");
    }
}

I would like to know why this error occurs and how I could solve it. Thank you very much in advance for the answers.

  • I added this line on the manifest android:requestLegacyExternalStorage="true". The explication is here: https://stackoverflow.com/questions/5453708/android-how-to-use-environment-getexternalstoragedirectory – Marquez_32 Jan 29 '22 at 11:08

0 Answers0