I'm sorry for a rather green question, but I could not find solution yet.
I am trying to restore a database from a back up on SD Card. The following code (a slight modified version of one provided here in SO)
try {
File sd = Environment.getExternalStorageDirectory();
File data = Environment.getDataDirectory();
if (sd.canWrite()) {
String currentDBPath =
"\\data\\com.dg\\databases\\" + com.dg.Constants.db_Table;
String backupDBPath = "com.dg";
File currentDB = new File(data, currentDBPath);
File backupDB = new File(sd, backupDBPath);
if (currentDB.exists()) {
FileChannel dst = new FileInputStream(currentDB).getChannel();
FileChannel src = new FileOutputStream(backupDB).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
}
line4.setText("Successful Import");
}
} catch (Exception e) {
line4.setText(e.toString());
}
Throws NonWriteableChannelException even though the database file is not open.
Your data is GENERALLY in
/data/data/com.dg/databases
You need to get rid of the double \ in the path.
Also, you're using Environment.getDataDirectory() as the parent directory, then "\data\com.dg\databases\"(etc) as the file name. That's totally wrong.
The easy way to go might be 'getDatabasePath' in Context (or Activity). Give it the name of your DB and it should give you a File reference to it. However, I don't know what it would do if that File didn't exist yet.
http://developer.android.com/reference/android/content/Context.html#getDatabasePath(java.lang.String)
You may also try simple 'getDir("databases", MODE_PRIVATE)'. That would hopefully return the database dir.
Final try for the database dir, really dirty:
File dbDir = new File(getFilesDir().getParentFile(), "databases");
Does your user / app have permissions to //database? (If not, then THIS IS THE ANSWER.)
Perhaps this might tell you why permission is denied:
IOException: Permission Denied
Bill Mote (from the above link) also pointed out the following permission setting:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Related
I cannot create directory, I have all the permissions and this in my Manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
In MainActivity onCreate, checks permission, if it has it should create a directory but it always returns a false:
if (!checkPermission()) requestPermission();
else {
File folder = new File(Environment.getExternalStorageDirectory() +
File.separator + "receipts");
if (!folder.exists()) {
boolean bool = folder.mkdirs();
System.out.println(bool);
}
}
Any clue or hint to why? Thanks
Unfortunately, with the security updates brought by Android 11 and up, as #CommonsWare said, you simply can't write directories on external storage (sdcard).
Straight from the docs:
Access to directories
You can no longer use the ACTION_OPEN_DOCUMENT_TREE intent action to
request access to the following directories:
The root directory of the internal storage volume.
The root directory of each SD card volume that the device manufacturer considers to be reliable, regardless of whether the card
is emulated or removable. A reliable volume is one that an app can
successfully access most of the time.
The Download directory.
Additionally from the same place:
App-specific directory on external storage Starting in Android 11, apps
cannot create their own app-specific directory on external storage. To
access the directory that the system provides for your app, call
getExternalFilesDirs().
Your app has a system generated directory to store any information. This makes sense, of course, because at any given time the user could remove/format the sd card inside the device, and your app's data would be entirely lost.
From more docs:
You would use this to write:
//Write to a file
String filename = "myfile";
String fileContents = "Hello world!";
try (FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE)) {
fos.write(fileContents.toByteArray());
}
And to read a file:
//To read from the file
FileInputStream fis = context.openFileInput(filename
);
InputStreamReader inputStreamReader =
new InputStreamReader(fis, StandardCharsets.UTF_8);
StringBuilder stringBuilder = new StringBuilder();
try (BufferedReader reader = new BufferedReader(inputStreamReader)) {
String line = reader.readLine();
while (line != null) {
stringBuilder.append(line).append('\n');
line = reader.readLine();
}
} catch (IOException e) {
// Error occurred when opening raw file for reading.
} finally {
String contents = stringBuilder.toString();
}
These are both within your app's "sandbox" folder. Because of this, you do not need to declare permissions.
File folder = new File(Environment.getExternalStorageDirectory() +
File.separator + "receipts");
Change to:
File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), "receipts");
Couldn't find too much about how to read a file that isn't somewhere on the SD card or storage, but rather right there in the android project directory.
I keep getting a FileNotFoundException. This is how I declare the file,
File SPPolicy = new File("SHPR_policy");
I've gotten the same error when putting it in the src/ directory, the src/[[package]]/ directory and the main project directory, and I get this error:
java.io.FileNotFoundException: /SHPR_policy: open failed: ENOENT (No such file or directory)
Is there a certain place I have to put this file? Is it because my file doesn't have an extension (I noticed the "/" before SHPR_policy but I didn't think it would be a problem because Eclipse let me create a file without an extension)?
Save the file in raw folder and try the below code.
try
{
Resources res = getResources();
InputStream in_s = res.openRawResource(R.raw.test);
byte[] b = new byte[in_s.available()];
in_s.read(b);
txtHelp.setText(new String(b));
} catch (Exception e) {
// e.printStackTrace();
txtHelp.setText("errr.");
}
Use these piece of code to check if the file was already created:
File f;
f=new File("myfile");
if(!f.exists()){
f.createNewFile();
}
Also, if you want to allocate your file in the external directory you can use these code:
File newxmlfile = new File( Environment.getExternalStorageDirectory() + "/new.xml");
XmlSerializer serializer = Xml.newSerializer();
try {
newxmlfile.createNewFile();
} catch (Exception e) {
Log.e("IOException", "exception in createNewFile() method", e);
}
And, did you added the permission in the manifest to be able to manipulate files?
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
You should place the file in the assets folder and use this:
InputStream ims = getAssets().open("SHPR_policy");
I can't figure out what's going wrong here...I've tried writing this more succicinctly, that didn't work. I put in all the extra strings after reading other suggestions with this problem. Not helping. No clue what's happening. Could it be permissions-related? AFAIK I'm trying to write to internal memory and that doesn't need special permissions?
public void outputBitmap(){
String path = Environment.DIRECTORY_PICTURES.toString();
File folder = new File(path + "/Blabla");
String filename = new SimpleDateFormat("yyMMddHHmmss").format(Calendar.getInstance().getTime()) + ".png";
try {
if (!folder.exists()) {
folder.mkdirs();
System.out.println("Making dirs");
}
File myFile = new File(folder.getAbsolutePath(), filename);
myFile.createNewFile();
FileOutputStream out = new FileOutputStream(myFile);
myBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
It goes "Making dirs" every time, the directory is not staying made, or something. When it gets to myFile.createNewFile(); it gives the error message "open failed: ENOENT (No such file or directory)"
Not sure if it's related, but the information I am trying to output is from:
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
myBitmap = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.RGB_565);
Canvas pngCanvas = new Canvas(myBitmap);
...[some maths and stuff]
canvas.drawLine(...);
pngCanvas.drawLine(...);
}
I thought I should be able to use the same canvas for the bitmap, but that caused crashed, so I'm writing the same information to both canvases. So...I don't know if that's related to the issue or a totally different bad issue or what.
Been searching all kinds of questions that seemed similar, but couldn't find any solutions that worked for me. I've been trying to solve this for days now. Anyone know what's going wrong?
Thanks
You are not using Environment.DIRECTORY_PICTURES correctly. It is not a folder by itself, you need to use it as a parameter to getExternalStoragePublicDirectory() method.
Check here : http://developer.android.com/reference/android/os/Environment.html#getExternalStoragePublicDirectory(java.lang.String)
Possible Issue:
Make sure you have given following required permission in your manifest file.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
And for Marhsmallow devices, make sure Contacts Groups Permissions is granted too by device user.
Ref: http://developer.android.com/training/permissions/requesting.html
Just change the begining of your code from this:
public void outputBitmap(){
String path = Environment.DIRECTORY_PICTURES.toString();
File folder = new File(path + "/Blabla");
To this:
public void outputBitmap(){File folder = new File(getActivity().getExternalFilesDir(null) + IMAGE_DIRECTORY + "whatever you want for your directory name");
I am working on an android app and I want to rename a file. The problem is that it is not renaming:
File f = adapter.getItem(i);
File file = new File(f.getAbsolutePath(), "helloworld");
if (f.renameTo(file)) {
Toast.makeText(getActivity(), "done", Toast.LENGTH_LONG).show();
}
Solution BIg Thanks to #S.D.(see comments)
File f = adapter.getItem(i);
File file = new File(f.getParent(), "helloworld");
if (f.renameTo(file)) {
Toast.makeText(getActivity(), "done", Toast.LENGTH_LONG).show();
}
I think the issue is that:
File f = adapter.getItem(i);
Gives use some File f, say where f cooresponds to say: user2351234/Desktop. Then, you do:
File file = new File(f.getAbsolutePath(), "helloworld");
Which says to make a File file, where file cooresponds to: user2351234/Desktop/helloworld. Next, you call:
f.renameTo(file)
which attempts to rename f, user2351234/Desktop to user2351234/Desktop/helloworld, which doesn't make sense since in order for user2351234/Desktop/helloworld to exist, user2351234/Desktop would have to exist, but by virtue of the operation it would no longer exist.
My hypothesis may not be the reason why, but from Why doesn't File.renameTo(…) create sub-directories of destination?, apparently renameTo will return false if the sub-directory does not exist.
If you want to just change the name of the file, do this:
File f = adapter.getItem(i);
String file = f.getAbsolutePath() + "helloworld";
f = new File(file);
EDIT:
My proposed solution should work, but if my hypothesis about why your way does not work is incorrect, you may want to see this answer from Reliable File.renameTo() alternative on Windows?
Question 1: Do you see an exception or does it return false?
Question 2: Did you give permission for the app to write to the SD card? (I'm assuming that's where this file lies).
The permission to add is"
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
This posting: How to rename a file on sdcard with Android application? seems to answer a similar question.
use this code.
File sdcard = Environment.getExternalStorageDirectory()+ "/nameoffile.ext" ;
File from = new File(sdcard,"originalname.ext");
File to = new File(sdcard,"newname.ext");
from.renameTo(to);
File file1 = new File(file.getAbsoluteFile() + "/example/directory/example.png");
file1.mkdirs();
file1.setWritable(true);
file1.createNewFile();
try {
FileInputStream is = new FileInputStream(exampleInputDirectory);
FileOutputStream os = new FileOutputStream(file1);
FileChannel srcChannel = is.getChannel();
FileChannel dstChannel = os.getChannel();
dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
is.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
This is my setup for copying an image file to a new directory tree. However, when this code is executed I get the following:
java.io.FileNotFoundException: *points to output directory* (Access is denied)
Have I gone about creating file1 incorrectly?
The problem here is because of using
file1.mkdirs();
and
file1.createNewFile();
together.
Since the file1 object is already been given 'directory' attributes after creating it as directory by calling "file1.mkdirs()", but then you are again using the same object to create a 'file', that means changin attribute of file1 object from directory to a file, which is not allowed. that's why its giving you FileNotFound.
Your creation of file1 seems to be up to par, maybe your input dir is non existent? Make sure all caps and such are correct, and that there are no typos in your directory reference. Also be sure if the user has permissions to copy a file to the directory, if not you can run it as root in linux, and as administrative in windows.