I want to download multiple images from my app drawable with one button click and save it in device internal/external storage of my Android app.
How do I achieve this?
UPDATE
I tried it, but I'm having one issue.
downloadTest.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick (View v){
//path here is for internal storage (Option 2), replace it with the other line above from Option 1 to save images to SD card
String path = new File(getFilesDir(), "/Space Wallpapers").getAbsolutePath();
//ids are drawables resource ids
int[] ids = new int[]{ R.drawable.abduction,
R.drawable.green_nightstreak,
R.drawable.hero,
R.drawable.ic_night,
R.drawable.light_streak,
R.drawable.moon_with_stars,
R.drawable.orange_nightstreak,};
int i = 1;
for (int res : ids) {
//Creates the bitmap object from the given resource
Bitmap b = BitmapFactory.decodeResource(getResources(), res);
File file = new File(path, "image" + i + ".PNG");
//This creates the file and it's parent if doesn't exist
file.getParentFile().mkdirs();
try {
FileOutputStream fileOut = new FileOutputStream(file);
b.compress(Bitmap.CompressFormat.PNG, 100, fileOut);
fileOut.close();
} catch (Exception e) {
e.printStackTrace();
}
i++;
}
};
});
The issue is that it's not the images are not downloading.
**This is what my "Run" log is showing **
D/ViewRootImpl#372fd66[TestActivity]: ViewPostImeInputStage processPointer 0
D/ViewRootImpl#372fd66[TestActivity]: ViewPostImeInputStage processPointer 1
W/System.err: java.io.FileNotFoundException: /data/user/0/com.khumomashapa.notes.debug/files/Space Wallpapers/image1.PNG (Is a directory)
at java.io.FileOutputStream.open(Native Method)
W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
at java.io.FileOutputStream.<init>(FileOutputStream.java:169)
at com.khumomashapa.notes.activities.TestActivity$1.onClick(TestActivity.java:54)
at android.view.View.performClick(View.java:6205)
at android.widget.TextView.performClick(TextView.java:11103)
W/System.err: at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1073)
at android.view.View$PerformClick.run(View.java:23653)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
W/System.err: java.io.FileNotFoundException: /data/user/0/com.khumomashapa.notes.debug/files/Space Wallpapers/image2.PNG (Is a directory)
at java.io.FileOutputStream.open(Native Method)
W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
at java.io.FileOutputStream.<init>(FileOutputStream.java:169)
at com.khumomashapa.notes.activities.TestActivity$1.onClick(TestActivity.java:54)
at android.view.View.performClick(View.java:6205)
at android.widget.TextView.performClick(TextView.java:11103)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1073)
W/System.err: at android.view.View$PerformClick.run(View.java:23653)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
W/System.err: java.io.FileNotFoundException: /data/user/0/com.khumomashapa.notes.debug/files/Space Wallpapers/image3.PNG (Is a directory)
W/System.err: at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
at java.io.FileOutputStream.<init>(FileOutputStream.java:169)
at com.khumomashapa.notes.activities.TestActivity$1.onClick(TestActivity.java:54)
at android.view.View.performClick(View.java:6205)
at android.widget.TextView.performClick(TextView.java:11103)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1073)
at android.view.View$PerformClick.run(View.java:23653)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
W/System.err: java.io.FileNotFoundException: /data/user/0/com.khumomashapa.notes.debug/files/Space Wallpapers/image4.PNG (Is a directory)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
at java.io.FileOutputStream.<init>(FileOutputStream.java:169)
at com.khumomashapa.notes.activities.TestActivity$1.onClick(TestActivity.java:54)
at android.view.View.performClick(View.java:6205)
at android.widget.TextView.performClick(TextView.java:11103)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1073)
at android.view.View$PerformClick.run(View.java:23653)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
W/System.err: java.io.FileNotFoundException: /data/user/0/com.khumomashapa.notes.debug/files/Space Wallpapers/image5.PNG (Is a directory)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:169)
at com.khumomashapa.notes.activities.TestActivity$1.onClick(TestActivity.java:54)
at android.view.View.performClick(View.java:6205)
at android.widget.TextView.performClick(TextView.java:11103)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1073)
at android.view.View$PerformClick.run(View.java:23653)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
W/System.err: java.io.FileNotFoundException: /data/user/0/com.khumomashapa.notes.debug/files/Space Wallpapers/image6.PNG (Is a directory)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
at java.io.FileOutputStream.<init>(FileOutputStream.java:169)
at com.khumomashapa.notes.activities.TestActivity$1.onClick(TestActivity.java:54)
at android.view.View.performClick(View.java:6205)
at android.widget.TextView.performClick(TextView.java:11103)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1073)
at android.view.View$PerformClick.run(View.java:23653)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
W/System.err: java.io.FileNotFoundException: /data/user/0/com.khumomashapa.notes.debug/files/Space Wallpapers/image7.PNG (Is a directory)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
at java.io.FileOutputStream.<init>(FileOutputStream.java:169)
W/System.err: at com.khumomashapa.notes.activities.TestActivity$1.onClick(TestActivity.java:54)
at android.view.View.performClick(View.java:6205)
at android.widget.TextView.performClick(TextView.java:11103)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1073)
at android.view.View$PerformClick.run(View.java:23653)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
W/System.err: at android.os.Looper.loop(Looper.java:154)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6682)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
I/Choreographer: Skipped 134 frames! The application may be doing too much work on its main thread.
I assume that by "download" you mean save/export. Then, this code should be working fine.
Option 1:
If you want to save images to external storage (SD card) add this line above the code:
String path = new File(Environment.getExternalStorageDirectory(), "Images").getAbsolutePath();
Add: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> to manifest
Option 2
If you want to save images to internal storage, just add:
String path = new File(getFilesDir(), "Images").getAbsolutePath() ;
Then:
yourButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick (View v){
//path here is for internal storage (Option 2), replace it with the other line above from Option 1 to save images to SD card
String path = new File(getFilesDir(), "Images").getAbsolutePath();
//ids are drawables resource ids
int[] ids = new int[]{R.drawable.imageId1, R.drawable.imageId2, R.drawable.imageId3};
int i = 1;
for (int res : ids) {
//Creates the bitmap object from the given resource
Bitmap b = BitmapFactory.decodeResource(getResources(), res);
File file = new File(path, "image" + i + ".PNG");
//This creates the file and it's parent if doesn't exist
file.getParentFile().mkdirs();
try {
FileOutputStream fileOut = new FileOutputStream(file);
b.compress(Bitmap.CompressFormat.PNG, 100, fileOut);
fileOut.close;
} catch (Exception e) {
e.printStackTrace();
}
i++;
}
});
Output:
R.drawable.imageId1 will be saved to path/image1.PNG
R.drawable.imageId2 will be saved to path/image2.PNG
R.drawable.imageId3 will be saved to path/image3.PNG
Related
I am trying to get few frames from a video file. And getting java.lang.IllegalArgumentException in the setDataSource line below.
String root = Environment.getExternalStorageDirectory().getAbsolutePath()+"/";
String path=root + "master" + File.separator +"master.mp4";
Uri videoFileUri=Uri.parse(path);
File myFile = new File(path);
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(myFile.getAbsolutePath()); //getting error here
ArrayList<Bitmap> rev=new ArrayList<Bitmap>();
//Create a new Media Player
MediaPlayer mp = MediaPlayer.create(getBaseContext(), videoFileUri);
int millis = mp.getDuration();
for(int i=0;i<millis;i+=100){
Bitmap bitmap=retriever.getFrameAtTime(i,OPTION_CLOSEST_SYNC);
rev.add(bitmap);}
Error Log
E/AndroidRuntime: FATAL EXCEPTION: main
Process: in.mm.video, PID: 11576
java.lang.RuntimeException: Unable to start activity ComponentInfo{in.mm.video/in.mm.video.RecognizeActivity}: java.lang.IllegalArgumentException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: java.lang.IllegalArgumentException
at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:71)
at in.mm.video.RecognizeActivity.onCreate(RecognizeActivity.java:178)
at android.app.Activity.performCreate(Activity.java:6662)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Application terminated.
I ask the user to sign in:
DeezerConnect deezerConnect = new DeezerConnect(this, APP_ID);
DialogListener listener = new DialogListener(){
#Override
void onComplete(Bundle values) {
SessionStore session = new SessionStore();
session.save(deezerConnect, MainActivity.this);
Toast.makeText(MainActivity.this, "Sign in successful", Toast.LENGTH_SHORT).show();
}
#Override
void onCancel() {
Toast.makeText(MainActivity.this, "Sign in required", Toast.LENGTH_SHORT).show();
}
#Override
void onException(Exception e) {
e.printStackTrace();
}
}
deezerConnect.authorize(this, PERMISSIONS, listener);
Normal and Facebook sign-in seem to be working fine, but when I tap the Sign in with Google button, the login dialog closes, and in Logcat I see the following lines:
09-30 18:09:19.460 22918-22918/ro.ande.deezwaker W/System.err: com.deezer.sdk.network.connect.event.DialogError: Unexpected URL
09-30 18:09:19.460 22918-22918/ro.ande.deezwaker W/System.err: at com.deezer.sdk.Country$Blues.shouldOverrideUrlLoading(Unknown Source)
09-30 18:09:19.460 22918-22918/ro.ande.deezwaker W/System.err: at com.android.webview.chromium.WebViewContentsClientAdapter.shouldOverrideUrlLoading(WebViewContentsClientAdapter.java:74)
09-30 18:09:19.460 22918-22918/ro.ande.deezwaker W/System.err: at org.chromium.android_webview.AwContentsClient.shouldIgnoreNavigation(AwContentsClient.java:15)
09-30 18:09:19.460 22918-22918/ro.ande.deezwaker W/System.err: at org.chromium.android_webview.AwContentsClientBridge.shouldOverrideUrlLoading(AwContentsClientBridge.java:157)
09-30 18:09:19.460 22918-22918/ro.ande.deezwaker W/System.err: at org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)
09-30 18:09:19.460 22918-22918/ro.ande.deezwaker W/System.err: at org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:7)
09-30 18:09:19.460 22918-22918/ro.ande.deezwaker W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102)
09-30 18:09:19.460 22918-22918/ro.ande.deezwaker W/System.err: at android.os.Looper.loop(Looper.java:148)
09-30 18:09:19.460 22918-22918/ro.ande.deezwaker W/System.err: at android.app.ActivityThread.main(ActivityThread.java:7331)
09-30 18:09:19.460 22918-22918/ro.ande.deezwaker W/System.err: at java.lang.reflect.Method.invoke(Native Method)
09-30 18:09:19.460 22918-22918/ro.ande.deezwaker W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
09-30 18:09:19.460 22918-22918/ro.ande.deezwaker W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
There's also this line:
09-30 18:09:19.540 22918-22918/ro.ande.deezwaker I/chromium: [INFO:CONSOLE(0)] "Refused to display '*some google url*' in a frame because it set 'X-Frame-Options' to 'sameorigin'.", source: *some deezer url* (0)
What does this mean and how do I solve it?
My application should save a piechart as a png on the external storage. However this error appears:
java.io.FileNotFoundException: /storage/emulated/0/SAVE IMAGE EXAMPLE/myimage.png (No such file or directory)
I followed the instructions to add this kind of functionality very closely (From this tutorial), but yet the error appears. The app has the permission to write to external storage, I added the permission in my android_manifest.xml.
Can you guys spot the error? Because i can not.
If you also can't find the error, can you recommend any other way to do this?
Im using MPAndroidChart, but i don't really think it has to do with this, because i could try to save any other object and the error remains.
The code is
final PieChart piechart = (PieChart) findViewById(R.id.piechart);
button2.setOnClickListener(new View.OnClickListener() {
public void onClick (View v) {
Toast.makeText(Main.this, "Chart Saved", Toast.LENGTH_SHORT).show();
piechart.setCenterText("Test");
Bitmap bitmap;
OutputStream output;
bitmap = BitmapFactory.decodeResource(getResources(),R.id.piechart);
File filepath = Environment.getExternalStorageDirectory();
File dir = new File(filepath.getAbsolutePath()+"/SAVE IMAGE EXAMPLE");
dir.mkdirs();
File file = new File(dir, "myimage.png");
try {
output = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, output);
output.flush();
output.close();
}catch(Exception e){
e.printStackTrace();
}
}
});
FULL ERROR
W/System.err: java.io.FileNotFoundException: /storage/emulated/0/SAVE IMAGE EXAMPLE/myimage.png (No such file or directory)
W/System.err: at java.io.FileOutputStream.open(Native Method)
W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:169)
W/System.err: at com.pies.quickpie.Main$1$3.onClick(Main.java:175)
W/System.err: at android.view.View.performClick(View.java:5637)
W/System.err: at android.view.View$PerformClick.run(View.java:22429)
W/System.err: at android.os.Handler.handleCallback(Handler.java:751)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
W/System.err: at android.os.Looper.loop(Looper.java:154)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6119)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
You need to implement Runtime Permission model to get Storage Permission from user from marshmallow and above.
See the example here for storage permission
In my activity when the user login
I check if the file with the user list exists , in case the method returns false , I create a new file where to save this list.
This is the method:
public boolean isLoginFilePresent() {
file = new File(loginData.getPath());//file name /sdcard/Hotel_Manager/HotelsMangerUser.dat;
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
present = file.exists();
return present;
}
But I get the following error ( this is the log ):
java.io.FileNotFoundException: /sdcard/Hotel_Manager/HotelsMangerUser.dat (No such file or directory)
08-13 11:15:36.174 12174-12174/app.com.hotelsmanager W/System.err: at java.io.FileOutputStream.open(Native Method)
08-13 11:15:36.175 12174-12174/app.com.hotelsmanager W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
08-13 11:15:36.175 12174-12174/app.com.hotelsmanager W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:169)
08-13 11:15:36.175 12174-12174/app.com.hotelsmanager W/System.err: at app.com.hotelsmanager.Controller.LoginDataSaver.saveLoginData(LoginDataSaver.java:108)
08-13 11:15:36.175 12174-12174/app.com.hotelsmanager W/System.err: at app.com.hotelsmanager.Controller.LoginController.addDemoLoginFile(LoginController.java:130)
08-13 11:15:36.175 12174-12174/app.com.hotelsmanager W/System.err: at app.com.hotelsmanager.View.Activities.LoginViewActivity.loginMe(LoginViewActivity.java:101)
08-13 11:15:36.175 12174-12174/app.com.hotelsmanager W/System.err: at app.com.hotelsmanager.View.Activities.LoginViewActivity.-wrap0(LoginViewActivity.java)
08-13 11:15:36.175 12174-12174/app.com.hotelsmanager W/System.err: at app.com.hotelsmanager.View.Activities.LoginViewActivity$1.onClick(LoginViewActivity.java:71)
08-13 11:15:36.175 12174-12174/app.com.hotelsmanager W/System.err: at android.view.View.performClick(View.java:5610)
08-13 11:15:36.175 12174-12174/app.com.hotelsmanager W/System.err: at android.view.View$PerformClick.run(View.java:22260)
08-13 11:15:36.175 12174-12174/app.com.hotelsmanager W/System.err: at android.os.Handler.handleCallback(Handler.java:751)
08-13 11:15:36.175 12174-12174/app.com.hotelsmanager W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
08-13 11:15:36.175 12174-12174/app.com.hotelsmanager W/System.err: at android.os.Looper.loop(Looper.java:154)
08-13 11:15:36.175 12174-12174/app.com.hotelsmanager W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6077)
08-13 11:15:36.175 12174-12174/app.com.hotelsmanager W/System.err: at java.lang.reflect.Method.invoke(Native Method)
08-13 11:15:36.175 12174-12174/app.com.hotelsmanager W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
08-13 11:15:36.175 12174-12174/app.com.hotelsmanager W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
What I wrong?
Thanks for helping me!!!!
This is the method for save user into file
public void saveLoginData(Set<User> accountSet, Context context) {
final List<String> loginFile = new ArrayList<>();
for (final User u : accountSet) {
loginFile.add(u.getName() + Constants.USERDATA_SEPARATOR + u.getPassword() +
Constants.USERDATA_SEPARATOR + u.getAccessLevel().toString());
}
try {
sdDir = new File(Constants.USER_DIR); //USER_DIR = "/sdcard/Hotel_Manger"
sdDir.mkdirs();
userOutput = new File(sdDir,Constants.USER_PATH);//USER_PATH = "HotelManagerUser.dat"
fos = new FileOutputStream(userOutput); //<------this return FileNotFoundException e
out = new ObjectOutputStream(fos);
out.writeObject(loginFile);
out.close();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
I have a problem to create file in Android M.
I use Nexus 9 with Android 6.0.1. Then I set in my project as below:
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
build.gradle
android {
defaultConfig {
targetSdkVersion 23
...
}
}
MainActivity.Java
public class MainActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String storagePath = Environment.getExternalStorageDirectory().getAbsolutePath();
String rootPath = storagePath + "/test";
String fileName = "/test.zip";
File root = new File(rootPath);
if(!root.mkdirs()) {
Log.i("Test", "This path is already exist: " + root.getAbsolutePath());
}
File file = new File(rootPath + fileName);
try {
if (!file.createNewFile()) {
Log.i("Test", "This file is already exist: " + file.getAbsolutePath());
}
} catch (Exception e) {
e.printStackTrace();
}
}
Build was success and application was launched, but I got exception message like this:
IOExceiption
01-07 18:13:40.669 18027-18027/com.sample.myapplication W/System.err: java.io.IOException: open failed: ENOENT (No such file or directory)
01-07 18:13:40.669 18027-18027/com.sample.myapplication W/System.err: at java.io.File.createNewFile(File.java:939)
01-07 18:13:40.669 18027-18027/com.sample.myapplication W/System.err: at com.sample.myapplication.MainActivity.onCreate(MainActivity.java:36)
01-07 18:13:40.670 18027-18027/com.sample.myapplication W/System.err: at android.app.Activity.performCreate(Activity.java:6251)
01-07 18:13:40.670 18027-18027/com.sample.myapplication W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
01-07 18:13:40.670 18027-18027/com.sample.myapplication W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
01-07 18:13:40.670 18027-18027/com.sample.myapplication W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
01-07 18:13:40.670 18027-18027/com.sample.myapplication W/System.err: at android.app.ActivityThread.-wrap11(ActivityThread.java)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at android.os.Looper.loop(Looper.java:148)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5417)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at java.lang.reflect.Method.invoke(Native Method)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at libcore.io.Posix.open(Native Method)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: at java.io.File.createNewFile(File.java:932)
01-07 18:13:40.671 18027-18027/com.sample.myapplication W/System.err: ... 13 more
How can I solve this problem? I don't catch what I miss....
Please help.
Updated
Replace storagePath to access scoped storage, for Android 10.
Refer this document for more detail.
Thanks, laalto.
I didn't know about runtime permission.
I solved exception like this:
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* Request user permissions in runtime */
ActivityCompat.requestPermissions(MainActivity.this,
new String[] {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
},
100);
/* Request user permissions in runtime */
createTestFile();
}
#TargetApi(23)
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 100:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {
// User checks permission.
} else {
Toast.makeText(MainActivity.this, "Permission is denied.", Toast.LENGTH_SHORT).show();
finish();
}
}
}
private void createTestFile() {
// String storagePath = Environment.getExternalStorageDirectory().getAbsolutePath();
// If Target API level is 29(Android 10),
// you should access local path in scoped storage mode.
File localStorage = getExternalFilesDir(null);
if (localStorage == null) { return; }
String storagePath = localStorage.getAbsolutePath();
String rootPath = storagePath + "/test";
String fileName = "/test.zip";
File root = new File(rootPath);
if(!root.mkdirs()) {
Log.i("Test", "This path is already exist: " + root.getAbsolutePath());
}
File file = new File(rootPath + fileName);
try {
int permissionCheck = ContextCompat.checkSelfPermission(
MainActivity.this,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
if (!file.createNewFile()) {
Log.i("Test", "This file is already exist: " + file.getAbsolutePath());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
It works!
I was having the same problem. I got an IOException on the file.createNewFile. A closer look at the exception reveals that it was due to "permissions denied". I was writing to my getFilesDir, so I shouldn't need an in the android manifest to accomplish this task. I of course added both READ and WRITE permissions for external storage, and of course, that didn't fix the problem.
I had been testing the code using a NEXUS 6 emulator with sdk 26. Without changing any code, I tried testing using a PIXEL C emulator with sdk 26 and the problem did not occur. So there seems to be some problem with my Nexus 6 emulator.
I suspect that this hasn't always been a problem and that this emulator instance got corrupted, but I haven't verified that. I did take the time to look at the linux file permission on the directories I was creating the file into an it reported "drwxrwxrwx", which is correct. I will add that I've implemented a FileProvider with paths to the directory I'm trying to create the new file at. The code I'm using pretty much looks like the code that Kae10 shows.
I traced the problem down to this code in UnixFileSystem:
public boolean createFileExclusively(String path) throws IOException {
BlockGuard.getThreadPolicy().onWriteToDisk();
return createFileExclusively0(path);
}
the exception is thrown from createFileExlussively0, which I not able to debug into. I haven't investigated this issue any further (i.e. 1.) would deleting the avd instance and recreating it help, my guess is that might, 2.) is there a later system image I should be using?)