I create a txt-File with FileWriter:
try
{
fw = new FileWriter( filePath );
fw.write("Name: " + title);
fw.write("Publisher: " + publisher + System.getProperty("line.separator"));
fw.write("Author: " + author + System.getProperty("line.separator"));
fw.write("Book Version: " + version + System.getProperty("line.separator"));
fw.write("URL: " + url + System.getProperty("line.separator"));
fw.write("ThumbMD5: " + thumbMD5 + System.getProperty("line.separator"));
fw.write("FileMD5: " + fileMD5 + System.getProperty("line.separator"));
fw.write("Book Area Code: " + areaCode + System.getProperty("line.separator"));
fw.write("Type: " + type + System.getProperty("line.separator"));
fw.flush();
fw.close();
}
catch ( IOException e ) {
Log.e(TAG, "saveTxt: Couldn't create File: " + e.getMessage() );
}
finally {
if ( fw != null )
try { fw.close(); } catch ( IOException e ) { e.printStackTrace(); }
}
That file gets created correctly, with correct content. I can open the file when I connect my Smartphone with a windows PC.
But when I try
File dirTxt = new File(Helper.getExternalStorageDirectory() + Helper.getFileCache());
File[] txts = dirTxt.listFiles();
for (File txt : txts) {
Log.e(TAG, txt.getName());
}
all files in that directory are found, but my new txt file.
What's up with that? All help is appreciated!
Workaround: instead of looking for the new File and coping it, I just used
File f = new File(pathToNewFile);
Then i copied f.
Related
Inside my software, a list of user information is generated offline as a PDF file. I tested this operation on Android 7 and 8 and everything was fine. But when I test on Android 11, the file is not generated. I was looking for a solution but I did not really find the complete source and training in this field.
I was able to create a PDF file via Intent, but inside another software, I saw that as soon as I clicked the save button, a folder with the program name was created in the Documents folder and the file was created inside.
This is the code I use to save the PDF file in the Download folder and it works for Android 7 and 8.
public void savePdfFileToStorage(String pdfTitleHeader, String currentTime, PdfDocument pdfDocument, Context context) {
String PdfDir=Environment.getExternalStorageDirectory() + "/Download/Apple";
File dir=new File(PdfDir);
if (!dir.exists())
dir.mkdir();
String fileName = pdfTitleHeader + "_" + todayDate() + "_" + convertToEnglishDigits(currentTime) + ".pdf";
File file = new File(PdfDir,fileName);
if (!file.exists()) {
try {
file.createNewFile();
Log.e(TAG, "savePdfFileToStorage: " + "file created" + file.getName() + "path: " + file.getPath());
} catch (IOException e) {
e.printStackTrace();
}
}
try {
pdfDocument.writeTo(new FileOutputStream(file));
Log.e(TAG, "savePdfFileToStorage: pdf Wrote in file");
Toast.makeText(context, "فایل PDF در پوشه Download/Apple حافظه داخلی ذخیره شد.", Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(context, "فایل PDF ساخته نشد.", Toast.LENGTH_LONG).show();
}
pdfDocument.close();
}
And I wrote these codes in the Manifest file.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application>
...
android:requestLegacyExternalStorage="true"
...
</application>
Please advise where I should add the code to solve the storage problem in Android 11.
This code generates a similar name: allTransaction 20220202 10:15:23 .pdf
The : is a forbidden character in file names and paths.
I used the following code and was finally able to save the file in the Documents folder.
public void savePdfFileToStorage(String pdfTitleHeader, String currentTime, PdfDocument pdfDocument, Context context) {
File dir;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) + "/Apple");
else dir = new File(Environment.getExternalStorageDirectory() + "/Apple");
if (!dir.exists())
if(!dir.mkdir())
return;
String fileName = pdfTitleHeader + "_" + todayDate() + "_" + convertToEnglishDigits(currentTime) + ".pdf";
File file = new File(dir, fileName);
if (!file.exists()) {
try {
file.createNewFile();
Log.e(TAG, "savePdfFileToStorage: " + "file created" + file.getName() + "path: " + file.getPath());
} catch (IOException e) {
e.printStackTrace();
}
}
try {
pdfDocument.writeTo(new FileOutputStream(file));
Log.e(TAG, "savePdfFileToStorage: pdf Wrote in file");
Toast.makeText(context, "فایل PDF در پوشه Download/Appleحافظه داخلی ذخیره شد.", Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(context, "فایل PDF ساخته نشد.", Toast.LENGTH_LONG).show();
}
pdfDocument.close();
}
I need to write some data into a text file to be read from standard text editor applications. In my app (running on Android 7.0) compiled with targetSdkVersion 27 I'm doing this trough this method, that works (or at least it seems to work since I got no exeptions):
private void storeLocation(Location location) {
try {
FileOutputStream outputStreamWriter;
outputStreamWriter = this.openFileOutput(logPath.getPath(), Context.MODE_APPEND);
outputStreamWriter.write(("LAT: " + location.getLatitude() + "\n").getBytes());
outputStreamWriter.write(("LON: " + location.getLongitude() + "\n").getBytes());
outputStreamWriter.close();
}
catch (Throwable e) {
Log.e("Exception", "File write failed: " + e.getMessage());
}
}
Variable logPath is defined in this way in application onCreate() event handler:
File logPath = new File("VIPER_" + getCurrentDateTime() + "_" + UUID.randomUUID().toString() + ".log");
I tought to find this file inside application private data folder but it's not here (maybe it's deleted after application closing?).
If I try to specify a different folder (like public downloads folder etc.) I got all sort of exceptions like file not found, read only filesystem, presence of / character in path etc.
There's a (simple) way to allow an application without having to deal with a FileProvider implementation?
The solution I found and that's working for some reason is the following:
logPath = new File( this.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "VIPER_" + getCurrentDateTime() + "_" + UUID.randomUUID().toString() + ".txt");
private void storeLocation(Location location) {
try {
final FileOutputStream outputStreamWriter = new FileOutputStream( logPath, true);
final SimpleDateFormat time_format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault());
final String line = time_format.format(
new Date()) + String.format(Locale.getDefault(),
" %f %f %f %f\n",
location.getLatitude(),
location.getLongitude(),
location.getAltitude(),
location.getBearing());
outputStreamWriter.write(line.getBytes());
outputStreamWriter.flush();
outputStreamWriter.close();
}
catch (Throwable e) {
Log.e("Exception", "File write failed: " + e.getMessage());
}
}
I really haven't got why this code works while the previous wasn't ... maybe one of the reason is openFileOutput() call I was using in the first sample or maybe is the Environment.DIRECTORY_DOCUMENTS I'm using now. What's certain that even if now the file is availabe its availability is not immediate but may require a variable timespan (from some seconds to some minutes).
May this code be of any help to someonelse.
I've wrote method below to copy my backup file to external storage
public Boolean Backup() {
try {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
File sd = Environment.getExternalStoragePublicDirectory("");
File data = Environment.getDataDirectory();
String dbPath = "//data//" + "com.example.sqlitetest"
+ "//databases//" + "TestDB";
// Backup file name
Calendar calendar = Calendar.getInstance();
String backupName = calendar.get(Calendar.YEAR) + "-"
+ (calendar.get(Calendar.MONTH) + 1) + "-"
+ calendar.get(Calendar.DAY_OF_MONTH) + "-"
+ calendar.get(Calendar.HOUR_OF_DAY) + ":"
+ calendar.get(Calendar.MINUTE) + ":"
+ calendar.get(Calendar.SECOND);
String backupPath = "//BackupFiles";
File db = new File(data, dbPath);
File backup = new File(sd + backupPath, backupName);
if (!backup.exists())
backup.mkdirs();
FileChannel src = new FileInputStream(db).getChannel();
FileChannel dest = new FileOutputStream(backup).getChannel();
dest.transferFrom(src, 0, src.size());
src.close();
dest.close();
return true;
} else
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
I've added permissions to write and read external storage. The destination folder is created (sd + backupPath) but files no and throws FileNotFoundException! How can I solve this problem?
Thanks in advance
Try:
String dbPath = context.getApplicationInfo().dataDir + File.separator
+ "databases" + File.separator + "TestDB";
And instead of using //, try File.separator.
Your dbPath variable is already a full absolute path name, so can't be used in combination with a File object referring to your data directory, but only on its own. And you got that full path name by making poor assumptions anyway.
What you should do is obtain a File representing the data directory as you are, and use it in combination with a String containing just a filename (within that) and not an absolute directory path.
If you do decide you want directories under your data directory, you can do that, but will have to make sure they exist or create them.
SOLVED:
ok so I am basically stupid. I couldn't open the file because I forgot to install winrar or 7zip since this pc is newly formatted... Everything works fine. Sorry to waste anyone's time.
In my app I programmatically generate a .zip file from photos and .csv files in a directory.
It creates the zip and then sends the email with the attachment without a hickup. The problem however is that on my pc I can't extract the .zip file because it says it's invalid, but on my device using "WinZip" I can check my .zip file and it has everything it is suppose to have. This is confusing me.
Here is my code:
Here I check for which checkboxes have been checked then do the zipping
for(int i = 0; i < cbStates.size(); ++i)
{
if(cbStates.get(i))
{
String zipFile = Environment.getExternalStorageDirectory() + "/ArcFlash/" + listItems.get(i) + ".zip";//ex: /storage/sdcard0/ArcFlash/study12.zip
String srcDir = Environment.getExternalStorageDirectory() + "/ArcFlash/" + listItems.get(i);
try
{
FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
File srcFile = new File(srcDir);
Log.i("customException", "going to compress");
addDirToArchive(zos, srcFile);
// close the ZipOutputStream
zos.close();
}
catch (IOException ioe)
{
System.out.println("Error creating zip file: " + ioe);
}
//Send the email
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("application/image");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"jbasson#powercoreeng.com"});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,"Test Subject");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "From My App");
String folderPath = Environment.getExternalStorageDirectory() + "/ArcFlash/" + listItems.get(i) + ".zip";
//Uri u = Uri.fromFile(folderPath);
//Log.i("customException", "uri path: " + u.getPath());
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + folderPath));
startActivity(Intent.createChooser(emailIntent, "Send mail..."));
Toast.makeText(context,"Case \"" + studyName + "\" has been sent", Toast.LENGTH_LONG).show();
//adapter.setElement(i, adapter.getStudy(i) + "(sent)");
}
}
and here is the zip function:
private static void addDirToArchive(ZipOutputStream zos, File srcFile)
{
File[] files = srcFile.listFiles();
Log.i("customException", "Adding directory: " + srcFile.getName());
for (int i = 0; i < files.length; i++)
{
// if the file is directory, use recursion
if (files[i].isDirectory())
{
addDirToArchive(zos, files[i]);
continue;
}
try
{
System.out.println("tAdding file: " + files[i].getName());
// create byte buffer
byte[] buffer = new byte[2048];//1024
FileInputStream fis = new FileInputStream(files[i]);
zos.putNextEntry(new ZipEntry(files[i].getAbsolutePath() + "/" + files[i].getName()));//files[i].getName()
int length;
while ((length = fis.read(buffer)) > 0)
{
zos.write(buffer, 0, length);
}
zos.closeEntry();
// close the InputStream
fis.close();
}
catch (Exception ex)
{
Log.i("customException", "error zipping: " + ex.getMessage());
}
}
}
ok so I am basically stupid. I couldn't open the file because I forgot to install winrar or 7zip since this pc is newly formatted...
I am using a ShareActionProvider to share a vcf file I created.
If I store the file in the external cache, I have absolutely no problems sharing the file, but if I store it in the internal cache, every app I try to share the vCard with says the file is corrupted or unsupported.
I read the file after creating it, and in both cases they are exactly the same.
This code works:
File dir = new File(getExternalCacheDir() + "/contact");
dir.mkdirs();
vcfFile = new File(dir, name.replace(' ', '+') + ".vcf");
However, if I use getCacheDir() instead, I get the problem.
Here's the code for creating the file:
FileWriter fw;
try {
fw = new FileWriter(vcfFile);
fw.write("BEGIN:VCARD\r\n");
fw.write("VERSION:2.1\r\n");
fw.write("N:" + codedName + "\r\n");
fw.write("FN:" + name + "\r\n");
fw.write("ORG:" + org + "\r\n");
fw.write("TITLE:" + position + "\r\n");
fw.write("TEL;PREF;WORK;VOICE;ENCODING=QUOTED-PRINTABLE:" + phone + "\r\n");
fw.write("TEL;PREF;WORK;FAX;ENCODING=QUOTED-PRINTABLE:" + fax + "\r\n");
fw.write("ADR;WORK;;ENCODING=QUOTED-PRINTABLE:" + codedAddr + "\r\n");
fw.write("EMAIL;INTERNET:" + email + "\r\n");
fw.write("URL;WORK:" + website + "\r\n");
fw.write("PHOTO;TYPE=JPEG;ENCODING=BASE64:" + codedImage + "\r\n");
fw.write("END:VCARD\r\n");
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
And here's the code for the ShareActionProvider:
provider = (ShareActionProvider) menu.findItem(R.id.share).getActionProvider();
if (provider != null) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("text/vcard");
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(vcfFile));
provider.setShareIntent(intent);
}
Any ideas of what I'm doing wrong?
Any ideas of what I'm doing wrong?
every app I try to share the vCard with says the file is corrupted or unsupported.
According with Using the Internal Storage
You can save files directly on the device's internal storage. By default, files saved to the internal storage are private to your application and other applications cannot access them (nor can the user)...
For this reason, it is advisable to use External Storage
Manifest
uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
Code
```
public void sharePublicContact(View view){
String name = "Mickey Mouse";
String org = "Disney Corp.";
String note = "";
File dir = new File(getExternalCacheDir() + "/contact");
dir.mkdirs();
File vcfFile = new File(dir, name.replace(' ', '+') + ".vcf");
FileWriter fw;
try {
fw = new FileWriter(vcfFile);
fw.write("BEGIN:VCARD\r\n");
fw.write("VERSION:3.0\r\n");
fw.write("FN:" + name + "\r\n");
fw.write("ORG:" + org + "\r\n");
fw.write("NOTE:" + note + "\r\n");
fw.write("END:VCARD\r\n");
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/vcard");
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(vcfFile));
startActivity(sendIntent);
}
```