Este error me volvió loco, después de repasar el código una y otra vez, buscar información en otros foros y páginas webs, pude comprobar que el código estaba correcto. El problema era que a partir de la API 23, es necesario otorgar permisos a las aplicaciones para poder acceder al almacenamiento externo (incluye tanto memoria interna del teléfono como tarjeta SD).

Para dar permiso, en el dispositivo móvil en Ajustes, hay que buscar Permisos de Aplicaciones->Almacenamiento y activar el permiso para la aplicación en cuestión.

También podemos poner el siguiente código en el MainActivity.java, para que al iniciar la aplicación nos pida la autorización para acceder al Almacenamiento externo:

 


public class MainActivity extends AppCompatActivity {
private static final int PERMISO_STORAGE = 1 ; //variable para permiso de almacenamiento

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

//Este código es para dar permiso a la aplicación a guardar en el almacenamiento externo del movil
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);

if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {

if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {

} else {

ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISO_STORAGE);

}
}
//Fin código para dar permiso a la aplicación

} //fin onCreate

//Código para dar permiso a la aplicación a guardar en el almacenamiento externo del movil
@Override
public void onRequestPermissionsResult(int requestCode,String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISO_STORAGE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {

} else {

}
return;
}
}
}

} //fin Activity

Con el código anterior, al iniciar la aplicación por primera vez nos saldrá una ventana como la siguiente:

 

 

Desde entonces por si acaso, trabajo con dos emuladores uno con la API 22 y otro con API 25. 

Alguna vez, mientras estamos programando nos podemos encontrar con un error como aparece en la imagen de abajo:

Para solucionar el problema, normalmente basta con hacer estos dos pasos desde las opciones del menú de Android Studio:

  • Build->Clean Project.
  • Build->Rebuild Project.