Android: external storage permission issue: - android

I really need someone here to guide me about some issues with the external storage OR sd-card. I won't go into complexities. I have a folder with the name of MyVideos. It is located in the sd-card folder of Motrola Xoom; the path is "/mnt/sdcard-ext/MyVideos. The folder is already there. However, there are some strange errors I am having.. For example, if I check if the folder exists or not using the following code:
File myDirectory = new File(defaultStorage, "/MyVideos/");
if (myDirectory.exists())
{
my code: lets say true
}
else
{
my code: false
}
where defaultStorage is = "/mnt/sdcard-ext". It always return false. It should return true since the folder surely exists there. And assuming that the folder exists there, I perform other operations like
for (File f : myDirectory.listFiles())
{
if (f.isFile())
{
filenames.add(f.getName()); //add to array
}//if closes
}//for closes
I get FATAL exception at the following line
for (File f : myDirectory.listFiles())
The error stack is below:
E/AndroidRuntime(22644): FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity
E/AndroidRuntime(22644): Caused by: java.lang.NullPointerException
I have just mentioned the things that are important from the stack. It is a NullPointerException to be precise. Although I am using
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
in my manifest file. Even then it doesn't work. The most surprising element is that it is running fine here; but there is a client in USA, it is crashing on all his devices.. Is there any difference in the permission settings of devices in UK or in USA.. I shall be thankful to you if you help me here.. It is a big problem for me.
Thanks

According to the documentation, the state you're describing means that the external media storage isn't accessible to you:
public static final String MEDIA_SHARED
Added in API level 1 getExternalStorageState() returns MEDIA_SHARED if the media is present not mounted, and shared via USB mass storage.
Constant Value: "shared"
You need to go to your USB Mass Storage options and turn off USB storage.
PS : Thanks to DigCamara I copied from this SO answer.
Thanks

Related

How can I make my Android app read and write a .txt file?

I'm using Xamarin, C# and Monogame and I'm taking a fully-working Desktop game and porting it over to Android.
My problem is that I have this "Content folder" that you would always use in the Desktop version of the app. But I cannot access it or any other folder through the code directly using Android.
basicShader = new Effect(game1.GraphicsDevice,System.IO.File.ReadAllBytes("Content/TextureShader.mgfxo"));
This works just fine in the Desktop app but throws System.IO.DirectoryNotFoundException:'Could not find a part of the path "/Content/TextureShader.mgfxo".' on Android.
I'd like to mention that I already had the code and the project working perfectly when it was a desktop program. I also have a private class-level variable string[] list_of_files and in the constructor, I had the line list_of_files = Directory.GetFiles("./Content","*.txt");
This is for saving and loading player data. It may have been rudimentary but I had a fully functioning program that saved and loaded data on my computer. I am transitioning this program to be an Android app and this is the only part of the project that isn't working. When I run the code as it was originally written, I get "System.IO.DirectoryNotFoundException: 'Could not find a part of the path '/Content'.' ".
I've tried playing around with trying to read the contents of different folders.
I've messed around with different paths, including the Resources folder instead.
I added <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> to my manifest.
I know that I'm trying to access internal storage, not external, so I also tried <uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" /> just to see if that might work.
Nothing works.
In another stack overflow post, a guy commented:
For the people who are facing NullPointerException - you are trying to access the files in the app's internal storage which are private sorry you can't do that. –
coderpc
Jun 23, 2017 at 16:00
I cannot imagine why this would be true. Why would a programmer not be able to write a program that can access it's own internal storage? That makes no sense to me. Obviously my app needs to be able to read and write it's own internal storage! And if this is true, then how else can I save persistent data on my phone? I don't want a database or a shared thingamabobber that uses key-value pairs, I have a self-made system that works as a text file and I want to continue to use it. I refuse to believe that an Android app can't keep track of a simple .txt file in one of it's own folders, that's just too hard for me to imagine. It can't be true.
I wanted to ask the commenter about his comment but Stack Overflow wouldn't let me because I don't have over 50xp.
Just like CommonsWare sayed, you can use the Intent.ActionOpenDocument to get the uri of the file. Such as
static readonly int READ_REQUEST_CODE = 1337;
Intent intent = new Intent(Intent.ActionOpenDocument);
intent.AddCategory(Intent.CategoryOpenable);
intent.SetType("*/*");
StartActivityForResult(intent, READ_REQUEST_CODE);
And override the OnActivityResult method:
if (requestCode == READ_REQUEST_CODE && resultCode == Result.Ok)
{
// The document selected by the user won't be returned in the intent.
// Instead, a URI to that document will be contained in the return intent
// provided to this method as a parameter. Pull that uri using "resultData.getData()"
if (data != null)
{
Android.Net.Uri uri = data.Data;
DocumentFile documentFile = DocumentFile.FromSingleUri(this.ApplicationContext,uri);
// Then you can operate the file with input and output stream
}
}
More information please check the simple on the github:
https://github.com/xamarin/monodroid-samples/blob/main/StorageClient/StorageClientFragment.cs
In addition, if you can ensure the file's path. You can use the StreamWriter and the StreamReader to write and read the file. Such as:
using (StreamWriter sw = new StreamWriter(path))
{
sw.WriteLine(content);
}
Furthermore, you can try to create the content folder and the txt file in the Android with the following code.
var filename1 = Android.App.Application.Context.GetExternalFilesDir(System.DateTime.Now.ToString("Content")).AbsolutePath;
var filename = System.IO.Path.Combine(filename1, "xxx.txt");
using (System.IO.FileStream os = new System.IO.FileStream(filename, System.IO.FileMode.Create))
{
}
The folder and the files created by this way belongs to the app and you can access it easily.
You can read the official document about the storage in the Android.
Link : https://developer.android.com/training/data-storage/shared/documents-files

C++ OpenCV imread not working in Android

I am trying to read an image in my C++ code
LOGD("Loading image '%s' ...\n", (*inFile).c_str());;
Mat img = imread(*inFile, CV_LOAD_IMAGE_GRAYSCALE);
CV_Assert(img.data != 0);
and get the following output:
09-25 17:08:24.798: D/IRISREC(12120): Loading image '/data/data/com.example.irisrec/files/input/osoba1.jpg' ...
09-25 17:08:24.798: E/cv::error()(12120): OpenCV Error: Assertion failed (img.data != 0) in int wahet_main(int, char**), file jni/wahet.cpp, line 4208
The file exists. But strange is, that if I try to preview the image using Root File Browser it is just black. I copied the files there manually.
EDIT:
The code works fine under Windows with .png and .jpg format. I am just trying to port an existing C++ project for Iris Recognition to Android.
imread() determines the type of file based on its content not by the file extension. If the header of the file is corrupted, it makes sense that the method fails.
Here are a few things you could try:
Copy those images back to the computer and see if they can be opened by other apps. There's a chance that they are corrupted in the device;
Make sure there is a file at that location and that your user has permission to read it;
Test with types of images (jpg, png, tiff, bmp, ...);
For testing purposes it's always better to be more direct. Get rid of inFile:
Example:
Mat img = imread("/data/data/com.example.irisrec/files/input/osoba1.jpg", CV_LOAD_IMAGE_GRAYSCALE);
if (!img.data) {
// Print error message and quit
}
When debugging, first try to get more data on the problem.
It's an unfortunate design that imread() doesn't provide any error info. The docs just say that it'll fail "because of missing file, improper permissions, unsupported or invalid format".
Use the debugger to step into the code if you can. Can you tell where it fails?
Search for known problems, stackoverflow.com/search?q=imread, e.g. imread not working in OpenCV.
Then generate as many hypotheses as you can. For each one, think of a way to test it. E.g.
The image file is malformed (as #karlphillip offered). -- See if other software can open the file.
The image file is not a supported format. -- Verify the file format on your desktop. Test that desktop OpenCV can read it. Check the docs to verify the image formats that AndroidCV can read.
The image file is not at the expected path. -- Write code to test if there's a file at that path, and verify its length.
The image file does not have read permission. -- Write code to open the file for reading.
A problem with the imread() arguments. -- Try defaulting the second argument.
I was able to solve this issue only by copying the image files in code.I stored them in my asset folder first and copied them to internal storage following this example.
If someone can explain this to me please do this.
It could be a permission issue.You would have to request the permission from Java code in your Activity class like this in Android 6.0 or above. Also make sure that in your AndroidManifest.xml, you have the the following line :
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
In your activity file add this:
if (PermissionUtils.requestPermission(
this,
HOME_SCREEN_ACTIVITY,
Manifest.permission.READ_EXTERNAL_STORAGE)) {
Mat image = Imgcodecs.imread(filePath,Imgcodecs.IMREAD_COLOR);
}
I struggled a long time to find this and I was getting Mat object null for all the time before.

getExternalFilesDir(null) returns null

Once again, I've come up against a question which has been asked and answered before but in my implementation it is still not working.
I'm calling getExternalFilesDir(null) right at the very start of my main activity's onCreate method. It returns null every time, whether I run it in an AVD or on my phone (Samsung Galaxy Plus).
Yes, I have the <uses-permission android:name="android.permissions.WRITE_EXTERNAL_STORAGE" /> line in my AndroidManifest.xml and yes, I am checking the external storage state before I make the call and it is mounted.
Here are the first three lines inside my onCreate() method. Actually, it's just after the super.onCreate() and setContentView() calls.
String state = Environment.getExternalStorageState();
File extFiles = getExternalFilesDir(null);
File locFiles = getFilesDir();
So, once these three lines have executed, these are the values for the variables:
state == "mounted"
extFiles == null
locFiles == "/data/data/com.mypackage.name/files"
Would anyone have any ideas as to why this might be?
-----EDIT-----
So I've tried another approach; Rather than using getExternalFilesDir(null), I tried using File basePath = new File(Environment.getExternalStorageDirectory(), "myAppName");
This is not ideal and I know that the Android documentation says, and I agree with it, that you should rather use getExternalFilesDir(). Seeing as that's not working for me though I had to try something else. This time the function does return a valid File object so, after the above line, the path of basePath is /mnt/sdcard/myAppName. So far, so good. When I check with DDMS I can see that /mnt/sdcard exists but not /mnt/sdcard/myAppName. This is to be expected. So I call boolean result = basePath.mkdirs();
But this returns false and when I check on the file system I can confirm that the myAppName subfolder has not been created. When I create the folder manually through DDMS and put files in it, I can read those files from my application but I can't write anything in that folder.
Please help! I'm at my wit's end.
If this wasn't a typo when you posted your question, you'll probably hate yourself for this:
<uses-permission android:name="android.permissions.WRITE_EXTERNAL_STORAGE" />
should be
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
This is from Android documentation:
Returns the path of the directory holding application files on external storage.
Returns null if external storage is not currently mounted so it could not ensure
the path exists; you will need to call this method again when it is available.
The other option is you can check if External storage is available:
String state = Environment.getExternalStorageState();
File filesDir;
// Make sure it's available
if (Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write the media
filesDir = getExternalFilesDir(null);
} else {
// Load another directory, probably local memory
filesDir = getFilesDir();
}
My issue was that I opened a FileOutputStream, then before I closed the FileOutputStream, I opened a FileInputStream to see what was already in the file.
I moved opening the FileInputStream to before the FileOutputStream is opened and that fixed my issue.
Delete a line
uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
in AndroidManifest.xml.
Switch a xml editor to "Android Manifest Permissions" with "Permission" tab in eclipse, and add a
uses-permission "android.permission.WRITE_EXTERNAL_STORAGE"
with some clicks.
Then try running your application.
It seems eclipse (may depends on a defference of version or state or settings) can ignore some words described by direct xml in AndroidManifest.xml.
Thanks for an advise. You are right, my answer looked like to agree in small talk.

Not a DRM File, opening notmally

I am looking for a solution regarding a repeating log print that is caused by calling
BitmapFactory.decodeFile.
In My app i have a ListView that is being redrawn by a timer every second.
The ListView has an ImageView that gets is image source from the local storage, (not from the network)
The image is stored in :
filePath = /data/data/com.xxx.testlib/files/b22a1a294fd6e5ad3ea3d25b63c4c735.jpg
I am using the following code to redraw the image and it is working fine. with out exception.
try
{
File filePath = context.getFileStreamPath(imageName);
if(filePath.exists()){
bMap = BitmapFactory.decodeFile(filePath.getPath());
}
}catch (Exception e)
{
e.printStackTrace();
}
But when preforming the following line :
bMap = BitmapFactory.decodeFile(filePath.getPath());
I get a print in the log as follow:
03-07 09:55:29.100: I/System.out(32663): Not a DRM File, opening notmally
03-07 09:55:29.105: I/System.out(32663): buffer returned
....
How can i get read from the printing to the log.
Thank you
lior
Edit
Also it lags the phone whenever this operation is performed. And this reduced performance is noticeable specially when the phone is Waked up and we return to activity with this code.
Its more than a year for OP and still no answer is found. If anyone has found solution then please post it.
Thank you.
DRM stands for Digital Rights Management. It's normally a special keys used by owners of content to make sure that your device is authorized to view/play the content. iTunes was notorious for this for ages.
All it's doing is letting you know that the material you are opening is not DRM protected, and therefore can be opened normally.
Hope, this might help you.
I also got the same exception when i tried to save the image captured by camera directly to : /data/data/com.xxx.testlib/images/b22a1a294fd6e5ad3ea3d25b63c4c735.jpg.
Then i first saved the image to default location used by camera and the copied it to : /data/data/com.xxx.testlib/images/b22a1a294fd6e5ad3ea3d25b63c4c735.jpg.
and now "Not a DRM File, opening notmally" is removed from the log and saved the image successfully.
Conclussion : folder :- "/data/data/com.xxx.testlib/" is private and can be accessible from inside the application only.
Maybe it's a permission error.
Do you have added the right permission in your Manifest ?
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Android Programming: Where To Start For Creating A Simple File Browser?

I would like to make a file browser that will do two things:
1) Allow the user to browse and select a directory
2) Allow the user to browse all files on their sdcard
I've looked for tutorials but can't seem to find any?
Can someone please help me by either explaining how what my code would need to do in order to have a simple file browser or providing me with a link to a tutorial/source code?
Please and thanks!
If you're actually more interested in learning to write your own, I'd suggest taking a good long read through the File class documentation. That's where you're going to be doing most of the work.
In the case of SD cards/other external storage for Android, you'll want to first check to ensure that the external storage is mounted and available before trying to read it, using the Environment class:
String extState = Environment.getExternalStorageState();
//you may also want to add (...|| Environment.MEDIA_MOUNTED_READ_ONLY)
//if you are only interested in reading the filesystem
if(!extState.equals(Environment.MEDIA_MOUNTED)) {
//handle error here
}
else {
//do your file work here
}
Once you've determined the proper state of the external storage, a simple way to start is to use File's listFiles() method, like so:
//there is also getRootDirectory(), getDataDirectory(), etc. in the docs
File sd = Environment.getExternalStorageDirectory();
//This will return an array with all the Files (directories and files)
//in the external storage folder
File[] sdDirList = sd.listFiles();
You can then start using FileFilters to narrow down your results:
FileFilter filterDirectoriesOnly = new FileFilter() {
public boolean accept(File file) {
return file.isDirectory();
}
};
File[] sdDirectories = sd.listFiles(filterDirectoriesOnly);
From there on, just read through the docs to find the type of thing you're looking to do with it, and then you can work on tying these into list adapters, etc.
Hope this helps!
This is a late answer but I worked on creating an android file explorer recently. https://github.com/mburman/Android-File-Explore
Its really straightforward. Essentially its just 1 file that you would need to integrate into your application.
Take a look at OI File Manager, which is an open-source Android file manager. You can get the source code here.

Categories

Resources