This forum uses cookies. Click X button to hide this message. What is stored? 
Total Commander Forum Index Total Commander
Forum - Public Discussion and Support
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

sdcard2 not writable on Tablet
Goto page Previous  1, 2
 
Post new topic   Reply to topic    Total Commander Forum Index -> Total Commander for Android Printable version
View previous topic :: View next topic  
Author Message
ghisler(Author)
Site Admin
Site Admin


Joined: 04 Feb 2003
Posts: 34649
Location: Switzerland

PostPosted: Mon Sep 10, 2012 7:42 am    Post subject: Reply with quote

Quote:
Copying a folder from internal flash (/mnt/sdcard) does not work.

Thanks for the hint, I will add that.

Quote:
Copying files from the lan (SMB) does not work.

Currently this isn't supported in plugins, but I will try to add it to the next version if possible.

For anyone who wants to do this too, here is a class which you can use to write to the SD-Card. Feel free to use it in your own programs.

Code:
package com.ghisler.android.TotalCommander;

import java.io.OutputStream;

import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;

public class MediaFileFunctions {
   @SuppressLint({ "NewApi", "NewApi" })
   private static Uri getFileUri(Context context,String fullname) {
      // Note: check outside this class whether the OS version is >= 11
      Uri uri=null;
      Cursor cursor=null;
      ContentResolver contentResolver=null;
      try{
         contentResolver=context.getContentResolver();
         if (contentResolver==null)
            return null;
         uri=MediaStore.Files.getContentUri("external");
         String[] projection=new String[2];
         projection[0]="_id";
         projection[1]="_data";
         String selection="_data = ? ";    // this avoids SQL injection
         String[] selectionParams=new String[1];
         selectionParams[0]=fullname;
         String sortOrder="_id";
         cursor=contentResolver.query(uri, projection, selection, selectionParams, sortOrder);
         if (cursor!=null) {
            try {
               if (cursor.getCount()>0) {  // file present!
                  cursor.moveToFirst();
                  int dataColumn=cursor.getColumnIndex("_data");
                  String s=cursor.getString(dataColumn);
                  if (!s.equals(fullname))
                     return null;
                  int idColumn=cursor.getColumnIndex("_id");
                  long id=cursor.getLong(idColumn);
                  uri=MediaStore.Files.getContentUri("external",id);
               } else {  // file isn't in the media database!
                  ContentValues contentValues=new ContentValues();
                  contentValues.put("_data",fullname);
                  uri=MediaStore.Files.getContentUri("external");
                  uri=contentResolver.insert(uri,contentValues);
               }
            } catch (Throwable e) {
               uri=null;
            }
            cursor.close();
         }
      } catch (Throwable e) {
         uri=null;
      }
      return uri;
   }
   
   public static OutputStream getOutputStreamViaContentProvider(Context context,String fullname) {
      Uri uri=getFileUri(context,fullname);
      if (uri==null)
         return null;
      try {
         ContentResolver resolver=context.getContentResolver();
         return resolver.openOutputStream(uri);
      } catch (Throwable e) {
         return null;
      }
   }
   
   public static boolean deleteViaContentProvider(Context context,String fullname) {
      Uri uri=getFileUri(context,fullname);
      if (uri==null)
         return false;
      try {
         ContentResolver resolver=context.getContentResolver();
         // change type to image, otherwise nothing will be deleted
         ContentValues contentValues=new ContentValues();
         int media_type=1;
         contentValues.put("media_type", media_type);
         resolver.update(uri,contentValues,null,null);
         return resolver.delete(uri,null,null)>0;
      } catch (Throwable e) {
         return false;
      }
   }

   public static boolean mkDirViaContentProvider(Context context,String fullname) {
      String fileName;
      Uri uri;
      ContentResolver resolver;
      try {
         resolver=context.getContentResolver();
         fileName = strcatslash(fullname)+"ghisler_temp.jpg";
         ContentValues contentValues=new ContentValues();
         contentValues.put("_data", fileName);
         uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues);
      } catch (Throwable e) {
         return false;
      }
      if (uri!=null) {
         try {
            resolver.delete(uri,null,null);
         } catch (Throwable e) {
         }
         return true;
      } else
         return false;
   }

   public static String strcatslash(String dir) {
   if (dir.length()>0 && !dir.endsWith("/"))
      return dir+"/";
   else
      return dir;
    }

}


To create a file on the card, just call:
Code:
boolean ok=true;
OutputStream g = null;
try {
   g = new FileOutputStream(fulltrg);
} catch (Exception e1) {
   ok = false;
}
if (!ok && getOsVersion()>=11 && fulltrg.startsWith("/mnt")) {
g=MediaFileFunctions.getOutputStreamViaContentProvider(this,fulltrg);


It's very important to check the OS version first, otherwise the class will crash your app on the first call! getOsVersion is defined like this:

Code:
   public static int getOsVersion() {
      try {
         java.lang.reflect.Field osField = android.os.Build.VERSION.class.getDeclaredField("SDK_INT");
         osField.setAccessible(true);
         int myBuild = osField.getInt(android.os.Build.VERSION.class);
         return myBuild;
      } catch (Exception e) {
         return 3;
      }
   }


The reason why this works, and the normal File() object doesn't, is the following: We call to the multimedia database for images, music etc. This is part of a different process, which is part of the operating system. Since only operating system processes are allowed to write to the card, this method works. The File() object is part of our own program, therefore it's not allowed to write.
_________________
Author of Total Commander
http://www.ghisler.com
Back to top
View user's profile Send private message Send e-mail Visit poster's website
t_arn
Junior Member
Junior Member


Joined: 28 Dec 2006
Posts: 38

PostPosted: Tue Aug 26, 2014 12:45 am    Post subject: Reply with quote

Hello Christian

Will the MediaFileFunctions class also let me write to my external sdcard on KitKat again? The upgrade of my Samsung S4 to KitKat crippled my external sdcard to a mere media storage while I used it to store all my data before - this *really* made me angry!

Is MediaFileFunctions built into TC 2.04 ?
If yes, then it does not work on my device Sad

I have also tested 2.05b3
There, I can write to /storage/extSdCard/Android/data/com.ghisler.android.TotalCommander/files, but not anywhere else on /storage/extSdCard/

Tom
Back to top
View user's profile Send private message
ghisler(Author)
Site Admin
Site Admin


Joined: 04 Feb 2003
Posts: 34649
Location: Switzerland

PostPosted: Tue Aug 26, 2014 9:02 am    Post subject: Reply with quote

Unfortunately it does not work any more on newer versions of Kitkat, it has all been locked down.
_________________
Author of Total Commander
http://www.ghisler.com
Back to top
View user's profile Send private message Send e-mail Visit poster's website
DrShark
Power Member
Power Member


Joined: 03 Nov 2006
Posts: 920
Location: Kyiv, 68/262

PostPosted: Thu Jul 27, 2017 3:17 am    Post subject: Reply with quote

When I had the Android 4.0.4 on the device, AFAIR (unfortunately I didn't save a screenshot) TC detected 3 media storages: Internal Storage, SDCard (it is internal fake sd), and SDcard2 (extsd one).
After I updated the Android 4.3.1 TC detects "Internal Storage" which is indeed a mentioned above internal fake SD, and TC shows SD card logo for it. Also it detects the SDCard which currently points to extsd.
TC can currently with Android 4.3.1 and could on Android 4.0.4 before to move files/folders on/to/from extsd, but the function to create New text file or New text file (UTF-8) don't work on extsd (and didn't work on Android 4.0.4).
However, once made a new folder with the empty file ghisler_temp.jpg inside (maybe it was while on Android 4.0.4, currently on 4.3.1 I can't reproduce it: TC creates empty folders on extsd), which could mean that actually TC can make a new file on extSD. If true, would be nice to see New text file creation feature to work on extsd too.
_________________
Android 4.3.1 no root, kernel 08.09.2016; Vista Home Premium SP2 rus 32 bit
TC #149847 Personal licence

Cuz we're all in this together, We're here to make it right
Back to top
View user's profile Send private message
DrShark
Power Member
Power Member


Joined: 03 Nov 2006
Posts: 920
Location: Kyiv, 68/262

PostPosted: Fri Jul 28, 2017 2:48 am    Post subject: Reply with quote

2ghisler(Author)
A also have to add that sometimes TC4A shows error calling su when trying to create a new text file, even though my device is not rooted, but usually it's just an writing file error. TC4A can show diffrerntg kind of error even for one new filename on one location on extsd, so I don't know what exactly causes this.

Since in this post you mentioned that writing to text file on extsd may fail on a rooted device, it may be the case that TC doesn't detect the root status on my device correctly.
_________________
Android 4.3.1 no root, kernel 08.09.2016; Vista Home Premium SP2 rus 32 bit
TC #149847 Personal licence

Cuz we're all in this together, We're here to make it right
Back to top
View user's profile Send private message
DrShark
Power Member
Power Member


Joined: 03 Nov 2006
Posts: 920
Location: Kyiv, 68/262

PostPosted: Mon Aug 07, 2017 2:01 pm    Post subject: Reply with quote

DrShark wrote:
New text file or New text file (UTF-8) don't work on extsd
No changes in TC4A 2.81 beta 7. I got the following error when trying to create New text file:
Code:
----
Write error
----
Error writing to target file!
/storage/extsd/testfile.txt

su error:
su call failed!
----
OK
----

It appeared after I tried to create a first text file since the updated TC 2.81 beta 7 launched.
After trying to create this file again (after clicking OK in above error window and selecting New text file from context menu of .. item in /storage/extsd), next error appeared:
Code:
----
Write error
----
Error writing to target file!
/storage/extsd/testfile.txt
----
OK
----

_________________
Android 4.3.1 no root, kernel 08.09.2016; Vista Home Premium SP2 rus 32 bit
TC #149847 Personal licence

Cuz we're all in this together, We're here to make it right
Back to top
View user's profile Send private message
ghisler(Author)
Site Admin
Site Admin


Joined: 04 Feb 2003
Posts: 34649
Location: Switzerland

PostPosted: Thu Aug 10, 2017 6:40 am    Post subject: Reply with quote

Sorry, this is currently not possible.
_________________
Author of Total Commander
http://www.ghisler.com
Back to top
View user's profile Send private message Send e-mail Visit poster's website
DrShark
Power Member
Power Member


Joined: 03 Nov 2006
Posts: 920
Location: Kyiv, 68/262

PostPosted: Tue Aug 29, 2017 2:04 pm    Post subject: Reply with quote

history2.txt wrote:
2017-08-11 Fixed: Could not create new text file (via long tap on "..") on secondary storage (e.g. SD card) when device was rooted
Maybe this fixed something on rooted devices, but my Android 4.3.1 device is not rooted, and I still get error messages mentioned in this post. Also Write error/su error appears if I change the path in file copy dialog manually (changing the target path to /original target path on extsd/new dir name/name.ext or /new target path on extsd/name.ext or just newname.ext).

What's important is if Write error/su error will appear after each of several continuous tries of creating a new file, something like a memory leak happens: interfaces of apps and reaction to keypresses on Android Navigation keys are slower, Android starts to close apps and notifications (like TC Media Player). In TC4A panels associated icons of files may change to default/general file icons (they may re-appear again after a refresh or re-enter to the folder.) Restart of TC4A doesn't help. After such a thing happened I had to reboot a device.
_________________
Android 4.3.1 no root, kernel 08.09.2016; Vista Home Premium SP2 rus 32 bit
TC #149847 Personal licence

Cuz we're all in this together, We're here to make it right
Back to top
View user's profile Send private message
ghisler(Author)
Site Admin
Site Admin


Joined: 04 Feb 2003
Posts: 34649
Location: Switzerland

PostPosted: Thu Aug 31, 2017 2:39 am    Post subject: Reply with quote

Sorry, this function is currently only supported on Android 5 and newer.
_________________
Author of Total Commander
http://www.ghisler.com
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Total Commander Forum Index -> Total Commander for Android All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Impressum: This site is maintained by Ghisler Software GmbH

Using phpBB © 2001-2005 phpBB Group