I'm fairly new to Android and I'm trying to use the camera via an intent. I know my permissions for API23 or lower are working. My app successfully opens the camera, but when I hit OK, it doesn't go back to my MainActivity. I found online that the reason is because my code fails to create a file for the picture. So I was able to narrow it down to mkdirs(). This function always returns false. I have tried everything and still mkdirs always returns false. I have followed exactly the same code in the documentation :
https://developer.android.com/guide/topics/media/camera.html#saving-media
under Saving data.
Here's my code:
private static File getOutputMediaFile(int type){
----- .... I do some checks first to make sure the SD card is mounted ...------
.....
File photosDirectory;
photosDirectory = new File (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"myPhotos");
if(!photosDirectory.exists()) {
boolean file_creation = photosDirectory.mkdirs();
if(!photosDirectory.mkdirs()){
//return null; --->> HERE IS WHERE IT FAILS
}else{
Log.d("MyCameraApp", "FILE CREATION SUCCEEDED ");
}
}
----- I have some extra code here, not relevant to the question -----
}
Things I have tried:
1- Permissions. I have already included:
2- I have also tried:
try{
if(!photosDirectory.exists()) {
boolean file_creation = photosDirectory.mkdirs();
if(!photosDirectory.mkdirs()){
//return null; --->> HERE IS WHERE IT FAILS
}else{
Log.d("MyCameraApp", "FILE CREATION SUCCEEDED ");
}
} catch(Exception e){ show message}
3- I have also gone into the application and make sure that the App has CAMERA and STORAGE permissions.
4- I have tried different ways of calling the same code, but still.
I'm desperate. This is driving me nuts. I have spent 4 days working on this without any luck. I would immensely appreciate any input. Thank you very much!
The issue doesn't have to do with mkdirs(), but with my permissions. For API >=23 instead of using:
<uses-feature android:name="android.hardware.CAMERA" />
I should have used should use:
<uses-feature android:name="android.hardware.camera2"/>
Related
I've been trying to get this to work for the last couple of hours and it's driving me nuts.
I have a method set up to save out data, which works flawlessly on PC, however, on Android it will not write the file. Here's my code:
public void Save()
{
string data = buildJson();
File.WriteAllText(Application.persistentDataPath + "/playerSave.json", data);
Debug.Log("File Saved: " + Application.persistentDataPath + "/playerSave.json");
}
Not sure why it's not working. From what I can tell reading other threads, using the Application.persistantDataPath is the correct thing to do.
Any help?
If WriteAllText failed, an exception would be thrown. Why not try catch the exception and check what the error is?
Solved.
My problem was that the method wasn't even being called correctly.
I had created a singleton gameobject which was holding the script with my save method in it, but I wasn't using a reference to save it, which meant it only worked when I was calling the save method in the same scene the gameobject was created. (Which was the case when I was skipping my menu scene in the Unity editor, but not when I was testing it for real in the app)
On android File.WriteAllText(Application.persistentDataPath + "/playerSave.json", data) will write data on your sd card you need to add permission android.permission.WRITE_EXTERNAL_STORAGE in your manifest file. The default manifest file created by unity do not add this permission.
I'm trying to delete a file in my Android app. The file was preciously created by the same Android app, and has MODE_WORLD_READABLE permissions.
I'm trying to delete it as follows:
File chosenFile = context.getFileStreamPath("myfile.txt");
boolean fileDeleted = chosenFile.delete();
if (fileDeleted)
Log.d(TAG, "myfile.txt was deleted");
else
Log.d(TAG, "myfile.txt was not deleted");
chosenFile.delete() keeps returning false. Is it because it's still being accessed? If so, is there any way I can force close it?
Thanks.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Did you give this permission.
for this line of code is myfile.txt exists, please check that first, file write permissions are not required for writing in private file system. Its required only when you try to write external storage.
context.getFileStreamPath("myfile.txt");
and to delete the file use
context.deleteFile("myfile.txt");
OK, so I figured out my mistake - the file doesn't exist in the first place. I thought I guarded against that by checking if (chosenFile == null), but I should've checked if (chosenFile.exist() == true) instead.
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.
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" />
This is a strange problem. My Application can access the sdcard successfully if I don't set android.uid.system to it. But after setting android.uid.system to it, my application can't access the sdcard. At this time, the exception take place:07-13 09:11:24.999: INFO/System.out(9986): create file happen exception--->java.io.IOException: Permission denied. I check I write the right permission in the right place:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />.
Because use forceStopPackage in my application, I need to add android.uid.system to the manifest. And I have written LOCAL_CERTIFICATE := platform in the make file. Who can explain this strange problem. After setting android.uid.system, my application is belong the system process which should have more power to access the sdcard. This is my idea. The following are my code:
public void setPackage(String dir){
System.out.println( "setPackage dir=="+dir );
File share=new File("/mnt/sdcard","test.txt");
if(!share.exists()){
try{
share.createNewFile();
}catch(Exception e){
System.out.println( "creat file happen exception--->" +e.toString() );
}
}
try{
if(share!=null){
System.out.println( "create file is not null" );
FileOutputStream fops=new FileOutputStream(share);
fops.write(dir.getBytes());
fops.flush();
fops.close();
}
}catch(Exception e){
System.out.println( "write Exception-->" +e.toString() );
}
}
And My application run at the emulator and his target version is 2.3. Thank you very much.
Please read this: link1
and this link2
Use Environment.getExternalStorageDirectory().getAbsolutePath() to get the path, NOT "/mnt/sdcard"
Use: File share = new File(Environment.getExternalStorageDirectory().getAbsolutePath(),"test.txt");
This won't work: File share = new File("/mnt/sdcard", "test.txt");
You can see in android source code: frameworks\base\core\java\android\os\Environment.java, it have a function:
private static void throwIfSystem() {
if (Process.myUid() == Process.SYSTEM_UID) {
Log.wtf(TAG, "Static storage paths aren't available from AID_SYSTEM", new Throwable());
}
}
This function would be called getExternalStorageDirectory(), hence app with system uid can't access sdcard if you don't hack aosp.
android.uid.system make your app bind system, but sdcard observered by system also, then if your app delete this, it can access the sdcard. it seems
delete this line in your xml file :android:sharedUserId="android.uid.system"ystem