Recent

Author Topic: [SOLVED] WRITE_EXTERNEL_STORAGE Failed in ANDROID 14  (Read 10406 times)

Guser979

  • Jr. Member
  • **
  • Posts: 64
[SOLVED] WRITE_EXTERNEL_STORAGE Failed in ANDROID 14
« on: April 09, 2024, 01:46:05 am »
I can't get "WRITE EXTERNEL STORAGE" permission

my MANIFEST

  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:remove="android:maxSdkVersion" tools:ignore="ScopedStorage"/>


Inside the APP I am using:

        manifestPermissions[1]:= 'android.permission.WRITE_EXTERNAL_STORAGE" tools:remove="android:maxSdkVersion" tools:ignore="ScopedStorage';


I keep getting permission denied error

ANDROID 14
« Last Edit: April 13, 2024, 08:42:36 pm by Guser979 »

maxerist

  • New Member
  • *
  • Posts: 28
Re: WRITE_EXTERNEL_STORAGE Failed
« Reply #1 on: April 09, 2024, 10:26:03 am »
I can't get "WRITE EXTERNEL STORAGE" permission
.....

I keep getting permission denied error

ANDROID 14


I'm not sure this is LAMW-specific issue. You didn't provide details about the location you're trying to write, but you may trying reading answers to  googling result [ WRITE_EXTERNAL_STORAGE "android 12..14" site:stackoverflow.com "permission denied" ] shows many useful answers where mostly Android 11+ restricts usage of this setting. The quote from the docs  usually mentioned  in the answers is

Quote
If your app targets Android 11, both the WRITE_EXTERNAL_STORAGE permission and the WRITE_MEDIA_STORAGE privileged permission no longer provide any additional access.

jmpessoa

  • Hero Member
  • *****
  • Posts: 2317
Re: WRITE_EXTERNEL_STORAGE Failed
« Reply #2 on: April 10, 2024, 07:28:09 pm »
Quote
AppPublicFoldersAccessDemo1   <---------------------------------it worked

Yes, This is a requirement Android > 10 ... It's the best we got for Android > 10 ....

(and with each new version more restrictions are placed on access to "public" folders........)
Lamw: Lazarus Android Module Wizard
https://github.com/jmpessoa/lazandroidmodulewizard

Guser979

  • Jr. Member
  • **
  • Posts: 64
Re: WRITE_EXTERNEL_STORAGE Failed
« Reply #3 on: April 10, 2024, 10:12:06 pm »
Quote
AppPublicFoldersAccessDemo1   <---------------------------------it worked

Yes, This is a requirement Android > 10 ... It's the best we got for Android > 10 ....

(and with each new version more restrictions are placed on access to "public" folders........)


This is really bad.
I have this app (made entirely in LAWM) that fails whenever I have to perform operations where I need to use folders outside of it.

In short, the app maintains a database with locations and objects found in them.

In order not to lose this work, would it be possible to resurrect it with Android STUDIO (I would have to install it)? Or would it be wasted time?

Leledumbo

  • Hero Member
  • *****
  • Posts: 8774
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: WRITE_EXTERNEL_STORAGE Failed
« Reply #4 on: April 11, 2024, 01:43:35 pm »
You can not achieve what you want anymore, not with recent Android version. The restriction comes from Android itself, only apps like a file manager and antivirus can have such a permission, the rest can only have user granted directory selection, it can not be dialogless. Not sure about the possibility to circumvent it for sideloaded apps, but here's a reading.

Guser979

  • Jr. Member
  • **
  • Posts: 64
Re: WRITE_EXTERNEL_STORAGE Failed
« Reply #5 on: April 12, 2024, 09:55:17 pm »
I got a temporary solution to export all data.

In the following example I compress all the photos taken.
Then use RequestCreateFile from LAWM.

In "ActivityResult" I finish saving the zip file in Downloads using "SaveBytesToUri"

Problem: I found it slow to finish writing. caused by Loop  FOR....  to pass the data from Tfilestream to the array.

But for now it's better than not being able to export the data.


Code: Pascal  [Select][+][-]
  1.  //////  call zip ( from Button , Menu , etc.)
  2.  
  3.  
  4.   procedure TAndroidModule3.zip;
  5.    var
  6.   zip: TZipper;
  7.   L: TStrings;
  8.   i: Integer;
  9.   relativefn: String;
  10.    begin
  11. zip := TZipper.Create;
  12.   try
  13.     zip.Filename := 'exportado.zip';
  14.     L := TStringList.Create;
  15.     try
  16.       FindAllFiles(L,GetEnvironmentDirectoryPath(dirDCIM), '*.jpg', true);
  17.    
  18.       WriteLn(L.Count);
  19.       for i:=0 to L.Count-1 do begin
  20.         relativefn := CreateRelativePath(L[i],GetEnvironmentDirectoryPath(dirDownloads));
  21.         zip.Entries.AddFileEntry(SysToUTF8(L[i]), relativefn);
  22.       end;
  23.     finally
  24.       L.Free;
  25.     end;
  26.    
  27.     zip.SaveToFile(GetEnvironmentDirectoryPath(dirDownloads)+'/exportado.zip');
  28.    Self.RequestCreateFile(Self.GetEnvironmentDirectoryPath(dirDownloads),'application/zip','exportado.zip', 111);   //handled by "OnActivityResult"
  29.  
  30.  
  31.  
  32.   finally
  33.     zip.Free;
  34.   end;
  35.  end;
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42. procedure TAndroidModule3.AndroidModule3ActivityResult(Sender: TObject;
  43.   requestCode: integer; resultCode: TAndroidResult; intentData: jObject);
  44. var
  45.   treeUri,uri: jObject;
  46.   arrayData: TDynArrayOfString;
  47.   listData: TstringList;
  48.   cnt,count, i: integer;
  49.   contentText: string;
  50.   arrayb: Tdynarrayofjbyte;
  51.   b:byte;
  52.   FS: TFileStream;
  53.   outFileName, outUriValue: string;
  54.  
  55. begin
  56.    if resultCode = RESULT_OK then
  57.    begin
  58.  
  59.       if intentData = nil then
  60.       begin
  61.          ShowMessage('Sorry... data nil received...');
  62.          Exit;
  63.       end;
  64.  
  65.       treeUri:= IntentManager1.GetDataUri(intentData);
  66.        Uri:= IntentManager1.GetDataUri(intentData);
  67.      
  68.  
  69.       if treeUri = nil then
  70.       begin
  71.          ShowMessage('Sorry... Uri nil received...');
  72.          Exit;
  73.       end;
  74.  
  75.  if requestCode = 111 then  //create file
  76.          begin
  77.        
  78.       FS := TFileStream.Create(GetEnvironmentDirectoryPath(dirDownloads)+'/exportado.zip', fmOpenRead or fmShareDenyWrite);
  79.           SetLength( arrayb, fs.Size);   fs.Position:=0;
  80.        
  81.          
  82.   Fs.Read(arrayb[0], fs.Size);
  83.  
  84.  self.SaveBytesToUri(arrayb,treeUri);
  85.  
  86. // release the filestream
  87.  Fs.free;
  88.  
  89. end;                        
  90.  
  91.  



UPDATE : Slowness problem resolved. Just eliminate the FOR.... Unnecessary because Fs.Read(arrayb[0], fs.Size); do the reading.

UPDATE : In activityresult: release the filestream


The code has been edited.   
« Last Edit: July 16, 2024, 03:39:26 am by Guser979 »

magleft

  • Full Member
  • ***
  • Posts: 125
Re: [SOLVED] WRITE_EXTERNEL_STORAGE Failed in ANDROID 14
« Reply #6 on: May 27, 2024, 03:35:13 pm »
Hello All.
Guser979  I need your help. I am facing the same problem as you.
My app needs to copy the database it uses to a shared folder.
Using your example, I created the compressed file in the downloads folder, but the entire path to the file is saved. This is something I would not want to happen. I am attaching your code as I modified it:

Code: Pascal  [Select][+][-]
  1. procedure TFmaster.CreateZipFile;
  2. var
  3.    zip: TZipper;
  4.    i: Integer;
  5.    relativefn: String;
  6. begin
  7.      zip := TZipper.Create;
  8.      try
  9.         zip.Filename :=zipFile ;
  10.         try
  11.                  relativefn:=self.GetEnvironmentDirectoryPath(dirDatabase)+'/'+dbname  ;
  12.                zip.Entries.AddFileEntry(PChar(relativefn));
  13.         finally
  14.                L.Free;
  15.         end;
  16.         zip.SaveToFile(GetEnvironmentDirectoryPath(dirDownloads)+'/'+zipFile);
  17.         Self.RequestCreateFile(Self.GetEnvironmentDirectoryPath(dirDownloads),'application/zip',zipFile, 111);   //handled by "OnActivityResult"
  18.      finally
  19.         zip.Free;
  20.      end;
  21. end;
  22.  
  23.  

What should I fix?
Also, how could I decompress the file inside the "dirDatabase" folder of the application?

Thanks in advance for your time and help.
windows 10 64

Guser979

  • Jr. Member
  • **
  • Posts: 64
Re: [SOLVED] WRITE_EXTERNEL_STORAGE Failed in ANDROID 14
« Reply #7 on: June 13, 2024, 10:24:51 pm »
The error is probably here:
Your code:
Code: Pascal  [Select][+][-]
  1.    relativefn:=self.GetEnvironmentDirectoryPath(dirDatabase)+'/'+dbname ;
  2.      
Try readapting your code to relative path:
Code: Pascal  [Select][+][-]
  1.  relativefn := CreateRelativePath(L[i],GetEnvironmentDirectoryPath(dirDownloads));  


L is the file path



I haven't tested unzip but you can study the zipper unit and try. There are examples in the source folder


LAMW4Windows\fpc\3.2.0\source\fixes_3_2\packages\paszlib\examples\fpunzipper.lpi
« Last Edit: June 13, 2024, 11:04:31 pm by Guser979 »

magleft

  • Full Member
  • ***
  • Posts: 125
Re: [SOLVED] WRITE_EXTERNEL_STORAGE Failed in ANDROID 14
« Reply #8 on: June 15, 2024, 03:05:01 pm »
Thanks. I will try it.
windows 10 64

magleft

  • Full Member
  • ***
  • Posts: 125
Re: [SOLVED] WRITE_EXTERNEL_STORAGE Failed in ANDROID 14
« Reply #9 on: July 14, 2024, 06:14:40 pm »
Hi to all.
Following the example, it finally worked.
My problem now is that when creating the compressed file, if it exists, it creates the 'filename(1).zip' file.
Is there a way to make it save over the old file or delete the file if it exists?
windows 10 64

magleft

  • Full Member
  • ***
  • Posts: 125
Re: [SOLVED] WRITE_EXTERNEL_STORAGE Failed in ANDROID 14
« Reply #10 on: July 16, 2024, 08:20:02 pm »
Thanks.
As you very correctly wrote, only fileExists works.
I don't know if and how the file can be requested to be deleted through the activityresult event.
windows 10 64

Guser979

  • Jr. Member
  • **
  • Posts: 64
Re: [SOLVED] WRITE_EXTERNEL_STORAGE Failed in ANDROID 14
« Reply #11 on: July 24, 2024, 01:25:25 pm »


About my app, it is now practically functional again.
Just a few more tweaks.
Detail: In the last version I used jIntentManager to VIEW an image from the list of registered objects (jListView with bitmaps) . In this version (Android 14 ) only worked when I used
Code: Pascal  [Select][+][-]
  1. self.StartDefaultActivityForFile.      

- In the previous version I had a button to add photo from the gallery as an additional photo captured by the camera. In this version this only worked when I used this line in the Result of jIntentManager.SetAction('android.intent.action.PICK');
Code: Pascal  [Select][+][-]
  1. GetEnvironmentDirectoryPath(dirDCIM)+'/'+self.GetFileNameByUri(FjUri )
  2.  

I hope this can help anyone who is updating their own app and needs this type of action.




Update:

My app is completely finished.

Features used and functional:

Camera
Codebar Scan
Data and photo compression (zip)
Import and export data (sqlite) and photos.
Data sharing (email, whatsapp, etc.)

Deeply grateful to jmpessoa and all the LAMW developers.
https://github.com/jmpessoa/lazandroidmodulewizard
« Last Edit: July 28, 2024, 06:34:30 pm by Guser979 »

magleft

  • Full Member
  • ***
  • Posts: 125
Re: [SOLVED] WRITE_EXTERNEL_STORAGE Failed in ANDROID 14
« Reply #12 on: July 27, 2024, 09:40:07 pm »
Congratulations.

What did I do wrong and it didn't work for me?
I made the modification in forms.java.
In procedure TFmaster.FmasterActivityResult(Sender: TObject; requestCode: integer;
 resultCode: TAndroidResult; intentData: jObject);
I added the call as shown in the code below:
Code: Pascal  [Select][+][-]
  1. procedure TFmaster.FmasterActivityResult(Sender: TObject; requestCode: integer;
  2.   resultCode: TAndroidResult; intentData: jObject);
  3. var
  4.   treeUri,uri: jObject;
  5.   arrayData: TDynArrayOfString;
  6.   listData: TstringList;
  7.   cnt,count, i: integer;
  8.   contentText: string;
  9.   arrayb: Tdynarrayofjbyte;
  10.   b:byte;
  11.   FS: TFileStream;
  12.   outFileName, outUriValue: string;
  13.   dbFile:String;
  14.   szip:TUnZipper ;
  15. begin
  16.    IntentManager1.SetAction('android.settings.MANAGE_ALL_FILES_ACCESS_PERMISSION')   ;
  17.    if resultCode = RESULT_OK then
  18.    begin
  19.       if intentData = nil then
  20.       begin
  21.          ShowMessage('Sorry... data nil received...');
  22.          Exit;
  23.       end;
  24.       treeUri:= IntentManager1.GetDataUri(intentData);
  25.       Uri:= IntentManager1.GetDataUri(intentData);
  26.       if treeUri = nil then
  27.       begin
  28.          ShowMessage('Sorry... Uri nil received...');
  29.          Exit;
  30.       end;
  31.       if requestCode = 111 then  //create file
  32.       begin
  33.               DeleteFile(UriToString(treeUri))  ;
  34.               FS := TFileStream.Create(GetEnvironmentDirectoryPath(dirDownloads)+'/'+zipFileName , fmOpenRead or fmShareDenyWrite );
  35.               SetLength( arrayb, fs.Size);
  36.               fs.Position:=0;
  37.               Fs.Read(arrayb[0], fs.Size);
  38.               self.SaveBytesToUri(arrayb,treeUri);
  39.       end;
  40.        if requestCode = 333 then  //open file
  41.       begin
  42.          CopyFileFromUri(treeUri,Self.GetEnvironmentDirectoryPath(dirDownloads));
  43.         StartDecompressFile ;
  44.       end;
  45.     end;
  46. end;
  47.  
  48.  


windows 10 64

Guser979

  • Jr. Member
  • **
  • Posts: 64
Re: [SOLVED] WRITE_EXTERNEL_STORAGE Failed in ANDROID 14
« Reply #13 on: July 28, 2024, 03:31:12 am »
I haven't tested your code, but I've already discovered my mistake. When I tested the modification in jform.java , I simply deleted the file I had just created with the create intent.

This is actually useless. But chatgpt suggested an approach that I'm going to try to implement.

It seems pretty simple to me:

1. Create the file "filename.zip" for the first time and store the URI.

2. Use the stored URI for future write operations.

That is, when filename.zip is created, the URI will be stored.

When using the Create intent again , it will be possible to delete the stored URI so that filename.zip is created and not filename(1).zip.

Let's see? Sorry for the mistake.


Code: Java  [Select][+][-]
  1.  
  2. import android.content.SharedPreferences;
  3. import android.net.Uri;
  4.  
  5.  
  6.  // Store the URI in SharedPreferences
  7.  
  8. private void saveFileUri(Uri uri) {
  9.     SharedPreferences prefs = getSharedPreferences("my_prefs", MODE_PRIVATE);
  10.     SharedPreferences.Editor editor = prefs.edit();
  11.     editor.putString("file_uri", uri.toString());
  12.     editor.apply();
  13. }
  14.  
  15.  
  16.  
  17.  
  18. // Retrieve the URI from SharedPreferences
  19. private Uri getFileUri() {
  20.     SharedPreferences prefs = getSharedPreferences("my_prefs", MODE_PRIVATE);
  21.     String uriString = prefs.getString("file_uri", null);
  22.     if (uriString != null) {
  23.         return Uri.parse(uriString);
  24.     }
  25.     return null;
  26. }
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
« Last Edit: July 28, 2024, 03:39:48 am by Guser979 »

magleft

  • Full Member
  • ***
  • Posts: 125
Re: [SOLVED] WRITE_EXTERNEL_STORAGE Failed in ANDROID 14
« Reply #14 on: July 28, 2024, 11:19:52 am »
Could you please help me by modifying my application? I can't understand where the java code should be added. I tried adding it to the jform.java file but it deletes it in the compile.
Thanks in advance for your time
windows 10 64

 

TinyPortal © 2005-2018