Permission issue in reading file from external storage

I can read files from data directory. I want to allow user to copy files to the directory and the app reads them. My problem, when I build the app on Android phone I’ve no idea where the data directory is.
Alternatively, I’m trying to make my app to read from external /storage/emulated/0/ unfortunately I got AccessDeniedException (READ_EXTERNAL_STORAGE permission ticked). I’ve tried many suggested solutions for permission from internet without success.

Questions:

  1. Can someone point me to some samples to read file from external storage?
  2. Another solution, if I can find the data directory on the phone then I simply copy the files to there. Where is the directory?

Thanks in advance

Hi

This not my code I don’t remember where I got it I think it’s belong for @noel

I have other code you have to determined the folder of saved data inside sketch I am going to post it when I found it

For now see this code

String[] SaveData = new String[1];
String[] LoadData = new String[1];
String[] FileData = {"My text is in here"};
String FileName = "File1.txt";

void setup() {
  fullScreen();
  
  SaveData[0] = "No data saved yet";
  LoadData[0] = "No data loaded yet";
  
}

void draw() {
  background(255);
  
  //Save data section and graphics
  fill(255, 0, 0);
  stroke(0);
  strokeWeight(2);
  rect(0, 0, width, height/2);
  fill(0);
  textSize(25);
  text("Click here to save", width/2 - textWidth("Click here to save")/2, height/4 - 25);
  text(SaveData[0], width/2 - textWidth(SaveData[0])/2, height/4 + 25);
  
  //Save if mouse is pressed below the half of the screen height
  if (mousePressed && mouseY < height/2) {
    //save to the name FileName or make a new txt called FileName inside of the data folder
    
    //comment this out to save the text in the string you set above
    FileData[0] = str(round(random(10)));
    SaveData = FileData;
    saveStrings(FileName, FileData);
    background(0);
    println("Saved");
    
  }
  
  //Load data section and graphics
  fill(0, 255, 0);
  stroke(0);
  strokeWeight(2);
  rect(0, height/2, width, height/2);
  fill(0);
  textSize(25);
  text("Click here to load", width/2 - textWidth("Click here to load")/2, height/2 + height/4 - 25);
  text(LoadData[0], width/2 - textWidth(LoadData[0])/2, height/2 + height/4 + 25);
  
  //Load if mouse is Pressed above half of the screen height
  if (mousePressed && mouseY > height/2) {
    //load the file from the directory of FileName which is inside of the data folder
    LoadData = loadStrings(FileName);
    background(0);
    println("Loaded");
    
  }
  
}

I run it with APDE

Edit

imaginativeCODE

Mar '19

hi
1

Load Image in and outside data folder

2
Android Cannot get access to data folder

3

Android Mode saving and loading txt file

4

File contains a path separator

in this links your going to find out all you need

Thank you for all the information. I’ll go through it and see.
Currently, I’m still seeing loadStrings():

java.lang.IllegalArgumentException: File /storage/emulated/0/twinkBOSS/env.txt contains a path separator

which I had before. I also tried ‘//’ without success.

I also tried:

I added:

println( listFile[i]);

in the ‘else’ section and didn’t see any file listed at all. It basically goes through all directories recursively without listing any files. Probably, missing permission in accessing files. I’ve also found articles about permission changes in Android 10 and some older solutions won’t work any more. Can this be a reason?

Hi

I have used load and save from this link

You can try load from the link

This is the save code it’s working fine on Android APDE and android mode processing

This code generates 2 folders automatic even they not existing



import java.io.BufferedWriter;
import java.io.FileWriter;
import android.os.Environment;

PImage save;
PGraphics square;

String s = "myImage.png";
String outFilename = "out.txt";

void setup(){
  // Write some text to the file
  //for(int i=0; i<100; i++){
   appendTextToFile(outFilename, "Text" +"trrdfghjhgdssdfhText");
 
// size(600, 400);
  square = createGraphics(600, 480);
  square.beginDraw();
  square.fill(0, 0, 150);
  square.rect(0, 0, 600, 480);
  square.endDraw();
  image(square, 0, 0);
  save = get(0, 0, 600, 400);
  saveImage(s);
 
  
  
  //} 
}

void saveImage(String s) {
   try
      {
     String directory = new String(Environment.getExternalStorageDirectory().getAbsolutePath() + "/imgFolder");
     File imgFolder = new File(directory);
      if (!imgFolder.exists()) {
      boolean success = true;
       success = imgFolder.mkdirs();
    }
     save.save(directory + "/" + s);
         println("File saved successfully.");
 } 
     catch (Exception e) 
        {
       println("Error while saving file: " + e);
  }
}


void appendTextToFile(String filename, String text){
 
 for(int i=0; i<100; i++){
    //appendTextToFile(outFilename, "Text" + i);
   }
 
  File f = new File("/storage/emulated/0/Folder/jaf.txt");
  if(!f.exists()){
    createFile(f);
  }
  try {
   
   
    PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f, true)));
    out.println(text);
    out.close();
  }catch (IOException e){
      e.printStackTrace();
  }
}


void createFile(File f){
  File parentDir = f.getParentFile();
  try{
    parentDir.mkdirs(); 
    f.createNewFile();
  }catch(Exception e){
    e.printStackTrace();
  }
}    

After compile to APP go to APP info to make sure that permission is allowed

When you run the app you can see the created folders

The blue marked folders generated after running the app each folder include file one txt file the other image file

Hi

This is @noel code he is one of the best

From the same link this load from folder but folder and file must be existing creat the folder and put inside it PNG file or jpg

// Tested on Lollipop and Android 10
// Do not forget to give READ/WRITE permission

import android.os.Environment;
import android.Manifest; 
import android.content.pm.PackageManager; 
import android.os.Build; 
import android.os.Build.VERSION_CODES; 
import processing.core.PConstants;
import android.app.Activity; 

String image_folder = "test"; // Must be an existing folder
PImage img;
boolean image_loaded;
Activity activity; 

void setup() {
  size(displayWidth, displayHeight);
  background(0, 0, 200); 
  textAlign(CENTER);
  String str = "Click to load image.";
  textSize(12);
  float twf = width/textWidth(str);
  textSize(8*twf);
  text(str, width/2, height/2);
  activity = this.getActivity();
  if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { 
    requestParticularPermission();
  }
  imageMode(CENTER);
}

void draw() {
  if (image_loaded) {
    if (img != null) {
      background(0, 0, 200); 
      image(img, width/2, height/2);
    } else {
      text("Image could not be found", width/2, height/2);
    }
  }
}

void mousePressed() {
  loadMyImage("e.png");
}

void loadMyImage(String s) {
  try {
    String directory = new String(Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+image_folder+"/");
    img = loadImage(directory+s);
    image_loaded = true;
  } 
  catch (Exception e) {
    background(0, 0, 200);
    text("Image could not be found.", width/2, height/2);
  }
}

private static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; 
private void requestParticularPermission() { 
  activity.requestPermissions(PERMISSIONS_STORAGE, 2020);
}

public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 
  switch (requestCode) { 
  case 2020: 
    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
      println("permissions granted");
    } else { 
      println("permissions not granted");
    } 
    break; 
  default: 
    activity.onRequestPermissionsResult(requestCode, permissions, grantResults);
  }
}


I have used both save and load in one code in my project

@jafal Just tested above code. That works. Thanks so much. I’ll work on that.

I tried to modify the above code to load a text file:

void loadEnv( String f) {
  String dir = new String(Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+image_folder+"/");
  try {
    println( dir+f);
    String[] LoadData = loadStrings( dir+ f);
  } 
  catch (Exception e) {
    background(0, 0, 200);
    text("File not found", width/2, height/2);
  }
}

I got this is the console:

permissions granted
/storage/emulated/0/twinkBOSS/env.txt

But got “File not found” on the screen.
When I tried to load an image all went well. Permission to read external media should be okay. However it doesn’t want to read text file.

I let the Exception printed out:
java.lang.IllegalArgumentException: File /storage/emulated/0/twinkBOSS/env.txt contains a path separator

Looks like I’m back to following situation which I wasn’t able to resolve:

I tried to work around the path separator issue by using File and Scanner:

void loadEnv( String f) {
  String dir = new String(Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+image_folder+"/");
  File file = new File( dir+f);
  
  try {
    println( dir+f);
    Scanner sc = new Scanner(file);
    println(sc.next());
  } 
  catch (Exception e) {
    println(e);
    text("File not found", width/2, height/2);
  }
}

Then it returns permission error:

java.io.FileNotFoundException: /storage/emulated/0/twinkBOSS/env.txt: open failed: EACCES (Permission denied)

Hi

This example from APDE I just changed the path



String[] lines;
int index = 0;
String filepath = "/storage/emulated/0/test/positions.txt/";
void setup() {
  size(800, 800);
  background(0);
  stroke(255);
  frameRate(12);
  lines =  loadStrings(filepath);

    
}

void draw() {
  if (index < lines.length) {
    String[] pieces = split(lines[index], '\t');
    if (pieces.length == 2) {
      int x = int(pieces[0]) * 2;
      int y = int(pieces[1]) * 2;
      point(x, y);
    }
    // Go to the next line for the next run through draw()
    index = index + 1;
  }
}


This is text save

import java.io.BufferedWriter;
import java.io.FileWriter;
import android.os.Environment;


String outFilename = "out.txt";

void setup() {
size(600, 400);
  for (int i=0; i<10; i++) {
    appendTextToFile(outFilename, "fine " +i ); 
  }
}
void appendTextToFile(String filename, String text) {
  File f = new File("/storage/emulated/0/save/out.txt");
  if (!f.exists()) {
    createFile(f);
  }
  try {
    PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f, true)));
    out.println(text);
    out.close();
  }
  catch (IOException e) {
    e.printStackTrace();
  }
}
void createFile(File f) {
  File parentDir = f.getParentFile();
  try {
    parentDir.mkdirs(); 
    f.createNewFile();
  }
  catch(Exception e) {
    e.printStackTrace();
  }
}


I tried above codes with following permissions:

    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

I got:

java.io.FileNotFoundException: /storage/emulated/0/twinkBOSS/out.txt: open failed: EPERM (Operation not permitted)

When I ran it with an existing file I got:

java.io.FileNotFoundException: /storage/emulated/0/twinkBOSS/env.txt: open failed: EACCES (Permission denied)

I was hoping if it can’t create file at least it can append to existing file.

Does this has something to do with my Processing IDE 3.5.4 and Android 11?
I tried to run Processing4. Unfortunately, the IDE itself is facing some errors.

codes working fine i am using Processing IDE 3.5.4

and test them with APDE also

I can see that you are compiling your code on tablet (APDE), right?
I’m doing on Win10 with USB debugging.

i run this on both

import java.io.BufferedWriter;
import java.io.FileWriter;
import android.os.Environment;


String outFilename = "out.txt";

void setup() {
size(600, 400);
  for (int i=0; i<10; i++) {
    appendTextToFile(outFilename, "fine " +i ); 
  }
}
void appendTextToFile(String filename, String text) {
  File f = new File("/storage/emulated/0/save/out.txt");
  if (!f.exists()) {
    createFile(f);
  }
  try {
    PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f, true)));
    out.println(text);
    out.close();
  }
  catch (IOException e) {
    e.printStackTrace();
  }
}
void createFile(File f) {
  File parentDir = f.getParentFile();
  try {
    parentDir.mkdirs(); 
    f.createNewFile();
  }
  catch(Exception e) {
    e.printStackTrace();
  }
}

Just tried it on my phone APDE, same error?
What are your permission settings?