Cannot write to SD Card on Android phone - android

EDIT2: For people stumbling across this question from Google. The canWrite() function is kinda buggy and doesn't seem to work properly. I would recommend not using it. Just catch and exceptions instead. Also make sure your phone is not in USB Storage mode so that you can write to the SD card. Lastly make sure the settings in Android device don't have write protection or anything of the sort on.
I seem to be having issues trying to write to my SD card on my Android phone. It doesn't matter if I am in debug mode with Eclipse, or running the phone on it's own. I cannot write to the SD Card. Yes the permissions are configured, as shown below. When using the code snippet provided on the Android site I am being given false for both of the booleans after it finishes the segment. I have absolutely no idea why the storage is not available or writable. I eject the SD card and the phone from my Mac to make sure they are not using it and that the phone can mount, but like I said I get the same issue when not using Eclipse at all.
EDIT: Using a real Android phone running 4.04 according to the about information.
boolean mExternalStorageAvailable = false;
boolean mExternalStorageWriteable = false;
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write the media
mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// We can only read the media
mExternalStorageAvailable = true;
mExternalStorageWriteable = false;
} else {
// Something else is wrong. It may be one of many other states, but all we need
// to know is we can neither read nor write
mExternalStorageAvailable = mExternalStorageWriteable = false;
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tinywebteam.gpstracker"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.tinywebteam.gpstracker.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
It fails when trying to execute mkdirs() below and throws the assigned exception:
try {
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdCard.getAbsolutePath() + "/GPStracker/data/");
if (!dir.exists()) {
if (!dir.mkdirs())
throw new FileNotFoundException("Couldn't make directory.");
}
File fileOut = new File(dir, "GPSTracker_" + ts + ".csv");
if (fileOut.canWrite()) {
FileOutputStream out = new FileOutputStream(fileOut);
out.write(fileStr.getBytes());
out.close();
System.out.println("File written successfully");
} else {
System.out.println("Could not write to file");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

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.

here is the deal, you are using
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdCard.getAbsolutePath() + "/GPStracker/data/");
instead use -
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdcard + "/GPStracker/data");
here we didn't use second '/' because mkdirs() misinterpret it as creating recursive directories.
you will not get this exception. And check if you pass your filename with a '/' appended before or it works this way as well.

I have a samsung galaxy s3 (running android 4.1.2) and my internal memory is named sdCard0 and My external sd card named as extSdCard.
So Environment.getExternalStorageDirectory() returned the path of sdCard0 which my internal phone memory
In such cases you can use the following to get the actual path.
String externalpath = new String();
String internalpath = new String();
public void getExternalMounts() {
Runtime runtime = Runtime.getRuntime();
try
{
Process proc = runtime.exec("mount");
InputStream is = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
String line;
BufferedReader br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
if (line.contains("secure")) continue;
if (line.contains("asec")) continue;
if (line.contains("fat")) {//external card
String columns[] = line.split(" ");
if (columns != null && columns.length > 1) {
externalpath = externalpath.concat("*" + columns[1] + "\n");
}
}
else if (line.contains("fuse")) {//internal storage
String columns[] = line.split(" ");
if (columns != null && columns.length > 1) {
internalpath = internalpath.concat(columns[1] + "\n");
}
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println("Path of sd card external............"+externalpath);
System.out.println("Path of internal memory............"+internalpath);
}
Once you get the actual path you can write files to sdcard.

Related

Write a file in the SD card of an Android 7 device

I have to develop a little function that, besides other things, writes a file in the SD card. I have to use it for two specific Android tablets provided by a supplier. One tablet uses Android 5 and the other uses Android 7. The application that I am modifying is a system app and it doesn't have UI. I'm calling the code from a Service, and I want to call it from a FirebaseMessagingService. I have problems to write a file only in Android 7 tablet.
I have no problems with the Android 5 tablet, I identified the external storage folder and I can create files in it. But I do have problems in Android 7, I identified the external storage folder and I have a problem: Permission denied.
I have this permissions in the manifest:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
This is the piece of code that is giving me problems:
public void myFunction()
{
String sdPath;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP)
sdPath = "/storage/extsd";
else
sdPath = "/storage/0665-3426";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (my_context.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
Log.d(TAG, "Permission is granted");
else
Log.d(TAG, "Permission is denied");
}
File folder = new File(sdPath);
if (folder.exists()) {
Log.d(TAG, sdPath + " exists, can write: " + folder.canWrite());
File file = new File(sdPath + "/new_file");
boolean fileExists = file.exists();
Log.d(TAG, file.getAbsolutePath() + " file exists: " + fileExists + ", can write: " + file.canWrite());
if (!fileExists) {
try {
file.createNewFile();
Log.d(TAG, "Can write in " + sdPath);
}
catch (Exception exception) {
Log.e(TAG, "Cannot write in " + sdPath + ": " + exception.getMessage());
}
}
}
else
Log.e(TAG, sdPath + " does not exist.");
...
}
Here the logs in Android 5 tablet:
10-22 14:44:51.271 10450-10450/com.my.app D/MY_TAG: /storage/extsd exists, can write: true
10-22 14:44:51.368 10450-10450/com.my.app D/MY_TAG: /storage/extsd/new_file file exists: false, can write: false
10-22 14:44:51.479 10450-10450/com.my.app D/MY_TAG: Can write in /storage/extsd
And here the logs in Android 7 tablet:
2020-10-22 15:11:56.383 19689-19689/com.my.app D/MY_TAG: Permission is granted
2020-10-22 15:11:59.037 19689-19689/com.my.app D/MY_TAG: /storage/0665-3426 exists, can write: false
2020-10-22 15:12:07.956 19689-19689/com.my.app D/MY_TAG: /storage/0665-3426/new_file file exists: false, can write: false
2020-10-22 15:12:07.957 19689-19689/com.my.app E/MY_TAG: Cannot write in /storage/0665-3426: Permission denied
As you can see, even if permission is granted, canWrite() method returns false in Android 7. Do you know the reason? How can I solve this problem?
I have read some other questions from stack overflow but I didn't find the solution.
I'm referring to one of the answers in this Stack Overflow thread.
I am not aware of the target SDK version in your case, but if you're building for version 29, try adding this to your AndroidManifest.xml file:
<manifest>
<application
<!-- other stuff -->
android:requestLegacyExternalStorage="true">
<!-- other stuff -->
</application>
</manifest>
Also, are you requesting permissions at runtime correctly?
Removable micro sd cards are read only since Android Kitkat/Lollipop.
Hence you cannot write to paths like "/storage/0665-3426".
Only one app specific directory is writable on a removable micro sd card.
To determine the path of that folder have a look at the second item returned by
getExternalFilesDirs()
I have decided not to use the Android API. Since the application has elevated privileges, I have created the file by executing a shell command. This is the code to create a file (works with removable SD card folder):
public static String createFile(String filePath)
{
String returnValue = "";
try
{
Runtime runtime = Runtime.getRuntime();
String[] command = new String[]{ "su", "0", "touch", filePath};
Process p = runtime.exec(command);
p.waitFor();
java.io.BufferedReader errorIn = new java.io.BufferedReader(
new java.io.InputStreamReader(p.getErrorStream()));
String line = "";
while ((line = errorIn.readLine()) != null)
returnValue += line + "\n";
}
catch (IOException | InterruptedException e)
{
e.printStackTrace();
}
return returnValue;
}

Reading files from SD card issue: no file is visible

I have a problem with my app. I'm trying to read files from my SD card, but I cannot find any file. Files are added to main folder in my sdcard. I tried also create a new folder and read files from folder, but I have the same problem. Other files from SD card (not added by me for app purposes) are also not visible. I'm testing my app on real device Samsung Galaxy A3. Do you have any idea, where is a problem, or what I do wrong? Below is my code:
Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".RecipeActivity"></activity>
</application>
Activity class:
File dir = Environment.getExternalStorageDirectory();
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "receip.txt");
if(file.exists()) // check if file exist
{
//Read text from file
StringBuilder text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append("\n");
}
}
catch (IOException e) {
//You'll need to add proper error handling here
}
//Set the text
Log.d("File text:", text.toString() );
Toast.makeText(getApplicationContext(),"File Found", Toast.LENGTH_SHORT);
}
else
{
Log.d("Romek file:", "File not found" );
Toast.makeText(getApplicationContext(),"File not Found", Toast.LENGTH_SHORT);
}
I added also below methods to checked whether my SD card is writable and readable. All methods return true.
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
Log.d("Romek", "External Storage is writable");
return true;
}
Log.d("Romek", "External Storage is not writable");
return false;
}
/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
Log.d("Romek", "External Storage is readable");
return true;
}
Log.d("Romek", "External Storage is not readable");
return false;
}
I used runtime permission and I can read files, but I have another problem. How can I get a correct path to my files in external SDCARD. When I using a Environment.getExternalStorageDirectory().getAbsolutePath(), then I recived a path to external card in my phone, not SDCARD.
If your phone has android 6.0 or newer version, you have to ask run time permissions. More info you can get from https://developer.android.com/training/permissions/requesting.html

Unable to write image to Android SD Card (Permission Denied) [duplicate]

The following code which consists of downloading a file from a server and save it in the storage works fine when the device has an internal storage.
But when I tried it with a device with no internal storage, only with external storage I get the following exception.
java.io.filenotfoundexception open failed eacces (permission denied)
public void downloadFile(String dlUrl, String dlName) {
int count;
HttpURLConnection con = null;
InputStream is = null;
FileOutputStream fos = null;
try {
URL url = new URL( dlUrl );
con = (HttpURLConnection) url.openConnection();
con.setDoInput(true);
con.connect();
is = url.openStream();
String dir = Environment.getExternalStorageDirectory() + Util.DL_DIRECTORY;
File file = new File( dir );
if( !file.exists() ){
file.mkdir();
}
Util.LOG_W(TAG, "Downloading: " + dlName + " ...");
fos = new FileOutputStream(file + "/" + dlName);
byte data[] = new byte[1024];
while( (count = is.read(data)) != -1 ){
fos.write(data, 0, count);
}
Util.LOG_D(TAG, dlName + " Download Complete!");
} catch (Exception e) {
Util.LOG_E(TAG, "DOWNLOAD ERROR = " + e.toString() );
bServiceDownloading = false;
}
finally{
try {
if( is != null)
is.close();
if( fos != null)
fos.close();
if( con != null)
con.disconnect();
} catch (Exception e) {
Util.LOG_E(TAG, "CLOSE ERROR = " + e.toString() );
}
}
}
And in manifest file I has the following:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Any suggestions what maybe the cause?
By the way Environment.getExternalStorageDirectory() returns /mnt/sdcard/ and file.mkdir() return false.
This attribute is "false" by default on apps targeting
Android 10 or higher.
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
This problem seems to be caused by several factors.
Check#1
First add this permission in your manifest file and check if it is working:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application>
...
</application>
  .....
Check#2:
If you are running on an emulator, check the properties to see if it has an SD card.
Check#3:
Disable file transfer from device to computer. If Enabled, the app wont be able to access the SD card.
Check#4:
If still not working, try the following:
String dir = Environment.getExternalStorageDirectory().getAbsolutePath()
For me the following worked:
The problem is that getExternalStorageDirectory returns /mnt/sdcard whereas I need the actual path of external storage which is /mnt/sdcard-ext and there is no API in android that can get me the absolute path of removable sdcard.
My solution was to hard code the directory as follows:
String dir = "/mnt/sdcard-ext" ;
Since the application is intended to work only on one device, the above did the job.
If you encounter the same problem, use an file explorer application to find out the name of the external directory and hard code it.
Use READ_EXTERNAL_STORAGE permission to read data from the device.
Did you try it on emulator? Check the properties if it has an SD card. I had the same problem, and it was because the emulator did not have an SD card. Check if yours has or not.
I had the same problem, and i solved it by disabling file transfer from device to computer.
Because if u enable file transfer, sd card is not accessible to debugging application.
try
Environment.getExternalStorageDirectory().getAbsolutePath()
and don't forget to add
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Try using mkdirs instead of mkdir. If you are creating a directory path and parent doesn't exist then you should use mkdirs.
I suspect you are running Android 6.0 Marshmallow (API 23) or later. If this is the case, you must implement runtime permissions before you try to read/write external storage.
https://developer.android.com/training/permissions/requesting.html
i have done very silly mistake.
I have already put in AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
and also add permission in java file,as get permission pragmatically.
But there is mistake of Manifest.permission.READ_EXTERNAL_STORAGE.
Please use Manifest.permission.WRITE_EXTERNAL_STORAGE.
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode);
I had the same problem. I used the write and read permission in the manifest correctly , yet it didn't work! The solution was very silly: unplug your phone from the PC before running the application. It seems when your phone is connected as "Mass storage" to the PC, the application cannot access the external storage.
First in your manifest file declare permissions :
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
now in header of application tag of manifest file :
android:requestLegacyExternalStorage="true"
now defines provider for your app in between tag of manifest file. as :
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_path" />
</provider>
now create a folder xml in res folder like this :
now create a xml file provider_path.xml and copy below code in it :
<?xml version="1.0" encoding="utf-8"?>
<path>
<external-path
name="external_files"
path="." />
now in your activity :
String filename = null ;
URL url = null;
try {
url = new URL("http://websitename.com/sample.pdf");
filename = url.getPath();
filename = filename.substring(filename.lastIndexOf('/')+1);
} catch (MalformedURLException e) {
e.printStackTrace();
}
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)+"/"+filename);
if(file.exists()){
Uri uri = FileProvider.getUriForFile(context, "com.example.www"+".provider",file);
Intent i = new Intent(Intent.ACTION_VIEW);
i.setDataAndType(uri, "application/pdf");
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivity(i);
}
else {
//download file here
new AlertDialog.Builder(context)
.setTitle("Information")
.setMessage("Do you want to download this file ?")
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setPositiveButton("Continue", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url+""));
request.setTitle(filename);
request.setMimeType("application/pdf");
request.allowScanningByMediaScanner();
request.setAllowedOverMetered(true);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename);
DownloadManager downloadManager = (DownloadManager)context.getSystemService(DOWNLOAD_SERVICE);
downloadManager.enqueue(request);
}
}).show();
}

Can't check if file on sdcard exists

I'm trying to make a simple check if the file exist. I saw similar questions here, but they didn't help. When I run my application, the app crashes and I got message "Unfortunatelly, fileCheck1 has stopped". I got this error both on emulator and smartphone.
My code:
package com.example.fileCheck1;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.widget.TextView;
import java.io.File;
public class MyActivity extends Activity {
TextView msgText;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
msgText = (TextView) findViewById(R.id.textView);
String Path = Environment.getExternalStorageDirectory().getPath()+"/ping.xml";
File file = getBaseContext().getFileStreamPath(Path);
if(file.exists()){
msgText.setText("Found");
}
if(!file.exists()){
msgText.setText("Not Found");
}
}
}
In my Manifest such permissions:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
Thanks in advance.
I think that problem is here:
getBaseContext()
where it is assigned to NULL. You really don't need this line. You can simply achieve your goal with
String path = Environment.getExternalStorageDirectory().getPath() + "/ping.xml";
File f = new File(path);
if (f.exists()) {
// do your stuff
}
else {
// do your stuff
}
Update:
If you or someone else have Samsung Galaxy S3, please follow #Raghunandan's answer because in this case getExternalStorageDirectory() returns internal memory.
I have samsung galaxy s3 with android 4.1.2. My internal phone memory is named sdcard0 and my external card extSdCard.
Environment.getExternalStorageDirectory()
So the above returns the path of sdcard0 which is internal phone memory
So get the actual path you can use the below
String externalpath = new String();
String internalpath = new String();
public void getExternalMounts() {
Runtime runtime = Runtime.getRuntime();
try
{
Process proc = runtime.exec("mount");
InputStream is = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
String line;
BufferedReader br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
if (line.contains("secure")) continue;
if (line.contains("asec")) continue;
if (line.contains("fat")) {//external card
String columns[] = line.split(" ");
if (columns != null && columns.length > 1) {
externalpath = externalpath.concat("*" + columns[1] + "\n");
}
}
else if (line.contains("fuse")) {//internal storage
String columns[] = line.split(" ");
if (columns != null && columns.length > 1) {
internalpath = internalpath.concat(columns[1] + "\n");
}
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println("Path of sd card external............"+externalpath);
System.out.println("Path of internal memory............"+internalpath);
}
Once you get the path
File file = new File(internalpath+"/ping.xml");// internalpath or external path
if(file.exists()){
msgText.setText("Found");
}
else{
msgText.setText("Not Found");
}
UPDATE :
The above solution is not recommended. May not work well. Environment.getExternalStorageDirectory() will always return the path of External Storage. In most cases it is a Sdcard.
From the docs
public static File getExternalStorageDirectory ()
Added in API level 1 Return the primary external storage directory.
This directory may not currently be accessible if it has been mounted
by the user on their computer, has been removed from the device, or
some other problem has happened. You can determine its current state
with getExternalStorageState().
Note: don't be confused by the word "external" here. This directory
can better be thought as media/shared storage. It is a filesystem that
can hold a relatively large amount of data and that is shared across
all applications (does not enforce permissions). Traditionally this is
an SD card, but it may also be implemented as built-in storage in a
device that is distinct from the protected internal storage and can be
mounted as a filesystem on a computer.
check this:
File file = new File(Environment.getExternalStorageDirectory()+"/ping.xml");
if(file.exists()){
msgText.setText("Found");
}
else{
msgText.setText("Not Found");
}

java.io.FileNotFoundException (Permission denied) When trying to write to the Android sdcard

I am trying to select an image file from the photo gallery and write to the sdcard. Below is the code that results in an exception. It appears to throw this exception when trying to create the FileOutputStream. I have the following line added to the manifest file nested inside the application element. I can't find a solution to the problem:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
public boolean saveSelectedImage( Uri selectedImage, int imageGroup,
int imageNumber )
{
boolean exception = false;
InputStream input = null;
OutputStream output = null;
if( externalStorageIsWritable() )
{
try
{
ContentResolver content = ctx.getContentResolver();
input = content.openInputStream( selectedImage );
if(input != null) Log.v( CLASS_NAME, "Input Stream Opened successfully");
File outFile = null;
File root = Environment.getExternalStorageDirectory( );
if(root == null) Log.v(CLASS_NAME, "FAILED TO RETRIEVE DIRECTORY");
else Log.v(CLASS_NAME, "ROOT DIRECTORY is:"+root.toString());
output = new FileOutputStream( root+"/Image"+ imageGroup + "_" + imageNumber + ".png" );
if(output != null) Log.e( CLASS_NAME, "Output Stream Opened successfully");
// output = new FileOutputStream
// ("/sdcard/Image"+imageGroup+"_"+imageNumber+".png");
byte[] buffer = new byte[1000];
int bytesRead = 0;
while ( ( bytesRead = input.read( buffer, 0, buffer.length ) ) >= 0 )
{
output.write( buffer, 0, buffer.length );
}
} catch ( Exception e )
{
Log.e( CLASS_NAME, "Exception occurred while moving image: ");
e.printStackTrace();
exception = true;
} finally
{
// if(input != null)input.close();
// if(output != null)output.close();
// if (exception ) return false;
}
return true;
} else
return false;
}
This is how your manifest file should look like
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".WriteCBTextToFileActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I had this issue and the answers here didn't fix it, because I had made a pretty silly mistake.
Make sure you give your Android emulator an SD card...I had left the size of the SD card blank and so of course it couldn't find anything. On top of that, I was specifying a directory inside said SD card which had not yet been created so be sure to consider that case as well.
(You can change an AVD's SD card settings by going to the Android Virtual Device Manager, editing your emulator of choice, and entering some value for the SD card size)
You must also make sure that the External Storage subsystem is in the correct state; use Environment.getExternalStorageState() and look for Environment.MEDIA_MOUNTED that is the only safe state.
It's also a good idea to narrow exception handling to IOException around those sections, so you don't over-recover from IO-specific issues, e.g. media unmounted.
If you need events, there are broadcast intents (Intent.ACTION_MEDIA_xxx) with the same information you can register for with IntentListener.
Also note that external storage may be disabled when you are using USB for debugging!
There is also an extended period during device startup, where External Storage is not available. If you do stuff in services on startup, this is an issue.
In general, your application must be aware of the External Storage state when accessing it, and handle cases where it is unavailable, or becomes unavailable while accessing it.
If you have the correct permissions set in the manifest, make sure your device is not in "Disk Drive" mode when connect to a PC. Change it to "Charge only" mode and it should work.
Notice that in addition to Saurabh answer, since API 23 you need to request permissions at run-time.
See here:
https://developer.android.com/training/permissions/requesting.html
And Justin Fiedler's answer here: https://stackoverflow.com/a/33288986/328059
Also, I've had several cases when after changing permission and re-running the app using Instant Run the permissions were not updated. So, as a best practice, after changing the manifest I uninstall the app from the target device, and rebuild.
You can try with:
String myPath=Environment.getExternalStorageDirectory()+"/Image"+ imageGroup + "_" + imageNumber + ".png";
File myFile = new File();
input = new FileInputStream(myFile);
Try to use openFileOutput("filename") to return a FileOutputStream instead of specifying the location by yourself.
Check the doc
here

Categories

Resources