Why this code is my white line drawing problem What is the problem
Is there a way to replace it?
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
Exactly this line of code is drawn by the white line method
getExternalStoragePublicDirectory
getExternalStoragePublicDirectory() --> Deprecated in API level 29
To improve user privacy, direct access to shared/external storage
devices is deprecated. When an app targets Build.VERSION_CODES.Q, the
path returned from this method is no longer directly accessible to
apps. Apps can continue to access content stored on shared/external
storage by migrating to alternatives such as
Context#getExternalFilesDir(String), MediaStore, or
Intent#ACTION_OPEN_DOCUMENT.
void createExternalStoragePrivateFile() {
// Create a path where we will place our private file on external
// storage.
File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
try {
// Very simple code to copy a picture from the application's
// resource into the external file. Note that this code does
// no error checking, and assumes the picture is small (does not
// try to copy it in chunks). Note that if external storage is
// not currently mounted this will silently fail.
InputStream is = getResources().openRawResource(R.drawable.balloons);
OutputStream os = new FileOutputStream(file);
byte[] data = new byte[is.available()];
is.read(data);
os.write(data);
is.close();
os.close();
} catch (IOException e) {
// Unable to create file, likely because external storage is
// not currently mounted.
Log.w("ExternalStorage", "Error writing " + file, e);
}
}
Related
Currently, we have an app that we are targeting Android 10 and right now are using the legacy storage API. Our app communicates via Bluetooth sensors and reads and writes raw data in CSV files in a subfolder in the main directory, with that subfolder having subfolders for each user.
I know Android 11 will enforce Scoped Storage. I would like to know, is our use case outside of the Scoped Storage requirement? It appears our use case isn't supported by MediaStore. If not, how would we go about this?
MediaStore APIs are just for media files - images, videos, and audio.
You can store all files in the app's private folder and add an export option to your app (maybe compress the whole structure to an archive). So a user will be able to store or send it wherever they want.
In this case, you need to use FileProvider to expose the file from the private directory.
reads and writes raw data in CSV files in a subfolder in the main directory,
For an Android 11 device you can create your own folders an subfolders in the Documents directory of what you call the 'main folder'.
And for using the MediaStore: you can also write any file to that Documents directory. Well in a subfolder if not directly.
I'm in a similar boat. This may help you get started.
public class FirstFragment extends Fragment {
...
public void fauxMakeCsvSurveyFile() {
File appDir = new File(getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "Field_data");
appDir.mkdirs();
try {
String storageState = Environment.getExternalStorageState();
if (storageState.equals(Environment.MEDIA_MOUNTED)) {
File file = new File(getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + "/Field_data/" + "OutputFile.csv");
FileOutputStream fos = new FileOutputStream(file);
String text = "Hello, world!";
fos.write(text.getBytes());
fos.close();
}
} catch (IOException e) {
Log.e("IOException", "exception in createNewFile() method");
}
}
...
}
I am working on a big project with a reasonably big code base. What I want to ask you is hints on how to reliably check where I have to provide a solution to adapt for android 6.0 . What i have used is Analyze > Inspect Code , it does a static analysis of the code and than shows missing checks in the section :
Android > Constant and Resource Type Mismatches. It looks somewhat not the right place to find those problems and that is why I am asking to make sure I am using the right thing and am looking at the right thing, plus I am a bit confused because I have parts of code which write files and i am not getting notified about permissions checks there(is it a normal behaviour?!)
public static boolean write(String folderName, String filename, Object objToWrite) {
// serialize cardModel
FileOutputStream file = null;
ObjectOutputStream o = null;
File dirFile = AppController.getInstance().getApplicationContext().getDir(folderName, Context.MODE_PRIVATE);
try {
// Create archiveDir
File mypath = new File(dirFile, filename);
file = new FileOutputStream(mypath, false);
o = new ObjectOutputStream(file);
o.writeObject(objToWrite);
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
try {
o.close();
file.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
return true;
}
Should I get a warning for Write permission here ?
Another thing that makes me ask is this issue that i have posted on google regarding an Android Studio bug:
Android Studio Bug
Not every write to a file needs a permission - only the one to external storage - this function might also write to the app file space - this needs no permission. Depends on the parameters
Interestingly enough, the definition of what "external storage" vs "internal storage" has changed quite a bit since Android Lollipop. What does this mean?
This call will require you to have storage permissions in the external public directory:
public File getAlbumStorageDir(String albumName) {
// Get the directory for the user's public pictures directory.
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), albumName);
if (!file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created");
}
return file;
}
However, if you do the following, you won't need STORAGE Permissions.
public File getAlbumStorageDir(Context context, String albumName) {
// Get the directory for the app's private pictures directory.
File file = new File(context.getExternalFilesDir(
Environment.DIRECTORY_PICTURES), albumName);
if (!file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created");
}
return file;
}
According to Google:
`If none of the pre-defined sub-directory names suit your files, you can instead call getExternalFilesDir() and pass null. This returns the root directory for your app's private directory on the external storage.
Remember that getExternalFilesDir() creates a directory inside a directory that is deleted when the user uninstalls your app. If the files you're saving should remain available after the user uninstalls your app—such as when your app is a camera and the user will want to keep the photos—you should instead use getExternalStoragePublicDirectory().
Regardless of whether you use getExternalStoragePublicDirectory() for files that are shared or getExternalFilesDir() for files that are private to your app, it's important that you use directory names provided by API constants like DIRECTORY_PICTURES. These directory names ensure that the files are treated properly by the system. For instance, files saved in DIRECTORY_RINGTONES are categorized by the system media scanner as ringtones instead of music.
`
I know there have been questions about this, but for some reason nothing seems to work for me.
I'm trying to get 2 text files to save to the SD card from my app. It correctly creates the directory and the files, but always to the Internal Storage, never the External Storage. I do have the permissions in place as well in the Manifest.
try {
File sdCard = Environment.getExternalStorageDirectory();
File myFile = new File(sdCard.getAbsolutePath() + "/rlgl");
myFile.mkdir();
// myFile.createNewFile();
String newLine = System.getProperty("line.separator");
File file = new File(myFile, "rlgls.txt");
if(file.exists()) {
} else if (!file.exists()){
FileOutputStream fOut = new FileOutputStream(file);
OutputStreamWriter myOutWriter =
new OutputStreamWriter(fOut);
for (int i = 0; i < 30; i++) {
myOutWriter.append("0.0" + newLine);
}
myOutWriter.close();
fOut.close();
}
} catch (IOException e) {
e.printStackTrace();
}
This is the code that I am using. I've followed directions from other Stackoverflow responses but it never goes to the SD Card. Is there something I'm doing wrong? Also a follow up question is there a way for me to use the above code in order to make the files invisible to the user. They should have no reason to open them. Thanks in advance.
It correctly creates the directory and the files, but always to the Internal Storage, never the External Storage
No, it places them on external storage. What the user sees as internal storage is what the developer sees as external storage. Internal storage is accessed via methods like getFilesDir(). And none of those are removable storage, such as some form of SD card.
Also a follow up question is there a way for me to use the above code in order to make the files invisible to the user. They should have no reason to open them.
Then put them on internal storage.
my app can't read/write from/to the files when there is a "." in front of their names
I find that very difficult to believe. The . prefix makes them not show up by default in some file browsers, but that's it. Users can get to them (if they are on external storage), and apps can get to them (subject to the same rules as any other files, those without a leading .).
Okay, I seem to be having a small issue with R.drawable.balloons. I'm trying to use a template for building a private external storage file that I found on Android Developer, but balloons keeps giving an error (cannot be resolved or is not a field). I was wondering if I could get some help fixing it.
Here's the code section it sits in:
void createExternalStoragePrivateFile() {
// Create a path where we will place our private file on external
// storage.
File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
try {
/*
Very simple code to copy a picture from the application's
resource into the external file. Note that this code does
no error checking, and assumes the picture is small (does not
try to copy it in chunks). Note that if external storage is
not currently mounted this will silently fail.
*/
// Creates file to stream picture
OutputStream os = new FileOutputStream(file);
// Allows app to accept the picture
InputStream is = getResources().openRawResource(R.drawable.balloons);
byte[] data = new byte[is.available()];
is.read(data);
os.write(data);
is.close();
os.close();
} catch (IOException e) {
// Unable to create file, likely because external storage is
// not currently mounted.
Log.w("ExternalStorage", "Error writing " + file, e);
}
}
A heads up, in case I get called out for being a copy/paster, this is only supposed to be a template, but I would like to test that it works before I make changes. Sorry.
You need an image named balloons in the res\drawable folder of your project (or any of its variants, such as drawable-hdpi, &c). The R class is autogenerated.
See How do I add R drawable android?
I'm very new to Android programming and I was wondering how can I make an app take a picture and save the image to the internal storage of a device, not to the SD card, because not everyone will have an SD card.
You can try saving it as an sqlite blob. This this thread for how to do the storage. Saying "not everyone will have external storage" is a bad excuse: you should handle both cases. If instead you want to implement it as a file (a perfectly good way to do it), you can look up an external storage directory using the Environment.getExternalStorageDir() call to determine a suitable directory in which to store your files. Read the API documentation here and heed the following note:
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.
Yes, you can try to save images in sqlite blob fields. It's just a java way: and let the whole world wait :)
It's a good practice to store all your files, cache etc into /Android/data/<package_name>/files/ directory on external storage. External storage is not the only SD cards and you can get external storage path and state by Environment.getExternalStorageDirectory() and Environment.getExternalStorageState() calls (reference). If you are using API 8 or greater, you can use Context.getExternalFilesDir().
If you would like to get user's hate-rays, you can try to store files and folders in the root of external storage.
Perhaps something like this
Bitmap largeBitmap ; // save your Bitmap from data[]
FileOutputStream fileOutputStream = null;
BufferedOutputStream bos = null;
int quality = 100;
String filePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + File.separator + "myImage.jpg"
File mediaFile = new File(filePath);
try {
fileOutputStream = new FileOutputStream(pictureFile);
bos = new BufferedOutputStream(fileOutputStream);
bitmap.compress(CompressFormat.JPEG, quality, bos);
return pictureFile;
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
// ignore close error
}
}