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?
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");
}
}
...
}
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);
}
}
I want to generate a qr code image and add it programmatically to the assets drawable folder of the app.
In the mean time, you would add it mannually in eclipse or android studio. Just wonder is there any ways to do it programmatically as well.
Many thanks!
This is simply not possible, you cant't modify/add that folder once you have generated apk and installed app. What you can do is to generate a folder on internal or external storage and save your images there.
It is already disccussed here and here
Asset Folder is used to load our Data with application , it never be changed at run time , AssetManger has method to read Asset Data and there is no way to write within Asset programmatically at Run Time.
Rather if you want to store your data at run time , You may store in Internal Memory like below Code.
Drawable drawable = getResources().getDrawable(R.drawable.demo_img);
Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
bitmap.compress(Bitmap.CompressFormat.PNG, 60, bytearrayoutputstream);
file = new File( Environment.getExternalStorageDirectory() + "/SampleImage.png");
try
{
file.createNewFile();
fileoutputstream = new FileOutputStream(file);
fileoutputstream.write(bytearrayoutputstream.toByteArray());
fileoutputstream.close();
}
catch (Exception e)
{
e.printStackTrace();
}
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'm using the below code to transfer an image from one folder on external memory, to another..as specified by the user. The problem is, the photo gets copied to the destination folder fine..but I can't open or view it. I use a file manager named Astro to see if it was successfully moved, and it is..but I'm unable to open it both in Astro and in the resident Gallery app. I'm thinking something is wrong with my code and maybe I need read and/or decode to photo before I can move it, from what I understand about the File class it is just an abstraction. Any guidance on this would be greatly appreciated, here is the code I'm currently using.
File img = new File(imgViewPath);
File output = new
File(Environment.getExternalStorageDirectory().toString() + "/MyAppPics/" + moved,
img.getName());
OutputStream out = null;
try {
out = new BufferedOutputStream(new FileOutputStream(output));
}
finally {
if (out != null) {
out.close();
}
}
}catch(Exception e){
e.printStackTrace();
}
You are not writing anything to the output stream. Read the bytes from the input stream and write it to the output stream, only then the files will get copied.