file = new File(getFilesDir(), "data.txt");
try {
FileOutputStream fos = openFileOutput(fileName, Context.MODE_APPEND);
fos.write(data.getBytes());
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
Is there a way to export this file so I can have access to it? I don't have a SD-card available btw.
File file = new File(Environment.getExternalStorageDirectory()+"/Download/", "yourFile.extension");
This is for downloads directory.
Then to open your file
Intent myIntent = new Intent(Intent.ACTION_VIEW);
myIntent.setData(Uri.fromFile(file));
Intent j = Intent.createChooser(myIntent, "Choose an application to open with:");
startActivity(j);
If you want to get your application path use getFilesDir() which will give you path /data/data/<your package>/files
So, you can find your file using android file manager in above mentioned directory.
From getFilesDir()
Related
I'm trying to implement the "share" button. It is necessary to send a picture.
That's what I'm doing:
Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
File outputDir = context.getCacheDir();
File outputFile = null;
try {
outputFile = File.createTempFile("temp_", ".jpg", outputDir);
} catch (IOException e) {
e.printStackTrace();
}
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(outputFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(outputFile));
shareIntent.setType("image/jpeg");
startActivity(Intent.createChooser(shareIntent,
getResources().getText(R.string.send_via)));
but I get a message saying that it's impossible to upload an image. What's the matter?
First, third-party apps have no rights to access files in your portion of internal storage.
Second, on Android 7.0+, you cannot use file Uri values, such as those returned by Uri.fromFile().
To solve both problems, use FileProvider to make the image available to other apps. Use FileProvider.getUriForFile() instead of Uri.fromFile(), and be sure to add FLAG_GRANT_READ_URI_PERMISSION to the Intent.
This sample app demonstrates using FileProvider with third-party apps (for ACTION_IMAGE_CAPTURE and ACTION_VIEW, but the same technique will work for ACTION_SEND).
I found lot of topics with the same problem, but they couldn't fix mine.
I initially write a file as follow:`
File root = new File(Environment.getExternalStorageDirectory(), "Notes");
if (!root.exists()) {
root.mkdirs();
}
File notefile = new File(root, sFileName);
FileWriter writer = null;
try {
writer = new FileWriter(notefile);
} catch (IOException e1) {
e1.printStackTrace();
}
try {
writer.append(sBody);
} catch (IOException e1) {
e1.printStackTrace();
}
try {
writer.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
try {
writer.close();
} catch (IOException e1) {
e1.printStackTrace();
}
Don't worry about the try and catch blocks, i will clear them later :D.
And this is the reader which should works in the same directory ("Notes" of the sdcard, if it doesn't exist, will be created), read the file, and put it on a Notify as you can see:`
File root = new File(Environment.getExternalStorageDirectory(), "Notes");
if (!root.exists()) {
root.mkdirs();
}
File file = new File(root, "Nota.txt");
//Read text from file
text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
}
br.close() ;
}catch (IOException e) {
e.printStackTrace();
}
I really don't understand why i get this problem, i even try with
getExternalStorageDirectory().getAbsolutePath()
but without success.
Can someone help me?
You've tried to check with a debugger if root exists when you do:
File root = new File(Environment.getExternalStorageDirectory(), "Notes");
if (!root.exists()) {
root.mkdirs();
}
I do not think it will create the folder when you write the file
To write a file in external storage,
you need to have WRITE_EXTERNAL_STORAGE permission enabled.
Why are you trying to write a file in external storage?
I mean if you want this file for your app only means, use context.getExternalDirs() to get your app's sandbox, it doesn't require write permission, above android 4.2(Jelly bean).
If you want to share the file to other apps, you're doing the right job.
And before writing the file, check whether external storage is mounted programmatically.
Problem Solved
I used SharedPreferences of Android.
I stored the data in MainActivity and take in in my Class as follow:
MainActivity
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("string_id", InputString); //InputString: from the EditText
editor.commit();
In my Class to get my data
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String data = prefs.getString("string_id", "no id"); //no id: default value
I am trying to use this code to send my application apk file to another device:
public static void sendAppItself(Activity paramActivity) throws IOException {
PackageManager pm = paramActivity.getPackageManager();
ApplicationInfo appInfo;
try {
appInfo = pm.getApplicationInfo(paramActivity.getPackageName(),
PackageManager.GET_META_DATA);
Intent sendBt = new Intent(Intent.ACTION_SEND);
sendBt.setType("*/*");
sendBt.putExtra(Intent.EXTRA_STREAM,
Uri.parse("file://" + appInfo.publicSourceDir));
paramActivity.startActivity(Intent.createChooser(sendBt,
"Share it using"));
} catch (PackageManager.NameNotFoundException e1) {
e1.printStackTrace();
}
}
This code works very well.
But the name of the apk file shared with this code is base.apk
How can I change it?
Copy the file from the source directory to a new directory.
Rename the file while copying and share the copied file.
Delete the temp file after share is complete.
private void shareApplication() {
ApplicationInfo app = getApplicationContext().getApplicationInfo();
String filePath = app.sourceDir;
Intent intent = new Intent(Intent.ACTION_SEND);
// MIME of .apk is "application/vnd.android.package-archive".
// but Bluetooth does not accept this. Let's use "*/*" instead.
intent.setType("*/*");
// Append file and send Intent
File originalApk = new File(filePath);
try {
//Make new directory in new location
File tempFile = new File(getExternalCacheDir() + "/ExtractedApk");
//If directory doesn't exists create new
if (!tempFile.isDirectory())
if (!tempFile.mkdirs())
return;
//Get application's name and convert to lowercase
tempFile = new File(tempFile.getPath() + "/" + getString(app.labelRes).replace(" ","").toLowerCase() + ".apk");
//If file doesn't exists create new
if (!tempFile.exists()) {
if (!tempFile.createNewFile()) {
return;
}
}
//Copy file to new location
InputStream in = new FileInputStream(originalApk);
OutputStream out = new FileOutputStream(tempFile);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
System.out.println("File copied.");
//Open share dialog
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(tempFile));
startActivity(Intent.createChooser(intent, "Share app via"));
} catch (IOException e) {
e.printStackTrace();
}
}
Update: this method does not work anymore and throws exception if you implement it. Since android N, we should use content providers if we want to have access to files in memory(like the apk file). For more information please visit this Guide. Although the whole idea of copying and renaming and sharing the copied version is still valid.
You can use this function, test on api 22 and 27
private void shareApplication() {
ApplicationInfo app = getApplicationContext().getApplicationInfo();
String filePath = app.sourceDir;
Intent intent = new Intent(Intent.ACTION_SEND);
// MIME of .apk is "application/vnd.android.package-archive".
// but Bluetooth does not accept this. Let's use "*/*" instead.
intent.setType("*/*");
// Append file and send Intent
File originalApk = new File(filePath);
try {
//Make new directory in new location=
File tempFile = new File(getExternalCacheDir() + "/ExtractedApk");
//If directory doesn't exists create new
if (!tempFile.isDirectory())
if (!tempFile.mkdirs())
return;
//Get application's name and convert to lowercase
tempFile = new File(tempFile.getPath() + "/" + getString(app.labelRes).replace(" ","").toLowerCase() + ".apk");
//If file doesn't exists create new
if (!tempFile.exists()) {
if (!tempFile.createNewFile()) {
return;
}
}
//Copy file to new location
InputStream in = new FileInputStream(originalApk);
OutputStream out = new FileOutputStream(tempFile);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
System.out.println("File copied.");
//Open share dialog
// intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(tempFile));
Uri photoURI = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", tempFile);
// intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(tempFile));
intent.putExtra(Intent.EXTRA_STREAM, photoURI);
startActivity(Intent.createChooser(intent, "Share app via"));
} catch (IOException e) {
e.printStackTrace();
}
}
This only happens because it is saved by base.apk name.
To share it as per your need you have to just copy this file into another directory path and rename it over there. Then use new file to share.
This file path[file:///data/app/com.yourapppackagename/base.apk] in data folder is having only read permissions so you can't rename .apk file over there.
2021 Kotlin way
First we need to set a file provider
In AndroidManifest.xml create a File provider
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true"
>
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths"
/>
</provider>
If you don't have file_path.xml the create one in res/xml (create xml folder if it doesn't exist)
and in file_path.xml add
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path
name="apk"
path="cache/ExtractedApk/" />
</paths>
Now add the code to share the apk
private fun shareAppAsAPK(context: Context) {
val app: ApplicationInfo = context.applicationInfo
val originalApk = app.publicSourceDir
try {
//Make new directory in new location
var tempFile: File = File(App.instance.getExternalCacheDir().toString() + "/ExtractedApk")
//If directory doesn't exists create new
if (!tempFile.isDirectory) if (!tempFile.mkdirs()) return
//rename apk file to app name
tempFile = File(tempFile.path + "/" + getString(app.labelRes).replace(" ", "") + ".apk")
//If file doesn't exists create new
if (!tempFile.exists()) {
if (!tempFile.createNewFile()) {
return
}
}
//Copy file to new location
val inp: InputStream = FileInputStream(originalApk)
val out: OutputStream = FileOutputStream(tempFile)
val buf = ByteArray(1024)
var len: Int
while (inp.read(buf).also { len = it } > 0) {
out.write(buf, 0, len)
}
inp.close()
out.close()
//Open share dialog
val intent = Intent(Intent.ACTION_SEND)
//MIME type for apk, might not work in bluetooth sahre as it doesn't support apk MIME type
intent.type = "application/vnd.android.package-archive"
intent.putExtra(
Intent.EXTRA_STREAM, FileProvider.getUriForFile(
context, BuildConfig.APPLICATION_ID + ".fileprovider", File(tempFile.path)
)
)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
startActivity(intent)
} catch (e: IOException) {
e.printStackTrace()
}
}
If someone trying to generate apk from fragment they may need to change few lines from #sajad's answer as below
Replace
File tempFile = new File(getExternalCacheDir() + "/ExtractedApk");
with
File tempFile = new File(getActivity().getExternalCacheDir() + "/ExtractedApk");
2.while importing BuildConfig for below line
import androidx.multidex.BuildConfig // DO NOT DO THIS!!! , use your app BuildConfig.
and if you're getting below EXCEPTION
Couldn't find meta-data for provider with authority
Look for provider info in manifest file
then look for "provider"s name and authority in your manifest file and if it's androidx.core.content.FileProvider then
Replace
Uri photoURI = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", tempFile);
With
Uri photoURI = FileProvider.getUriForFile(getActivity(), BuildConfig.APPLICATION_ID + ".fileprovider", tempFile);
I'm trying to save data from the app to internal storage and load it back, but I feel like I miss something and the file is not found in the load.
Save code:
private void saveScanData(List<MyStack> surf) throws IOException {
Log.i(TAG, "Saving");
String filename = String.format("Scan%05d.data", scanNumber);
scanNumber += 1;
ObjectOutput out;
File outFile = new File(Environment.getExternalStorageDirectory(), filename);
out = new ObjectOutputStream(new FileOutputStream(outFile));
out.writeObject(surf);
out.close();
}
Load code:
public void load(View view) {
ObjectInput in;
List<MyStack> surf= null;
try {
in = new ObjectInputStream(new FileInputStream("Scan%05d.data"));
surf= (List<MyStack>) in.readObject();
in.close();
} catch (Exception e) {e.printStackTrace();}
Model model= new Model(surf);
Intent intent = new Intent(this, EditorPresenter.class);
intent.putExtra("model", model);
startActivity(intent);
}
Thank you for any help.
You write into the file with the name
String.format("Scan%05d.data", scanNumber)
But you read the file with the name
"Scan%05d.data"
Either change your object input stream creation or use another approach to create the filename.
new ObjectInputStream(new FileInputStream(String.format("Scan%05d.data", scanNumber));
Use the open openFileOutput and openfileInput method instead of opening new Input and output stream.
http://developer.android.com/intl/es/guide/topics/data/data-storage.html#filesInternal
Moreover, you are trying to save the file in the ExternalStorage folder.
Environment.getExternalStorageDirectory(). Writting in that folder requires Android permissions on the AndroidManifest
You are writing to external storage:
new File(Environment.getExternalStorageDirectory(), filename);
You are reading from nowhere:
new ObjectInputStream(new FileInputStream("Scan%05d.data"));
If you want to use external storage, use external storage in both places, not just one.
I've been working with this PDF library, trying to get the path to where the PDF file resides, but I keep getting an error. What am I missing here?
Checking my Android Device Monitor, i can see my db in that database folder which also reside in the assets folder but i can't find all the pdf files? please where are they? check the image below
Thanks friends, it was my mistake, i just discovered that i need to read the file from assets into file directory before opening it. Is working right now using the code below
`
private void CopyReadAssets(String fileName)
{
AssetManager assetManager = this.getAssets();
InputStream in = null;
OutputStream out = null;
File file = new File(this.getFilesDir(), fileName);
try
{
in = assetManager.open(fileName);
out = this.openFileOutput(file.getName(), Context.MODE_WORLD_READABLE);
Utility.copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e)
{
Log.e("tag", e.getMessage());
}
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
File dir_file = new File(file.getAbsolutePath());
//<-- Get FileType
String mimeType = Utility.getFileMineType(dir_file);
intent.setDataAndType(Uri.fromFile(file), mimeType); //"file://" + getFilesDir() + "/abc.pdf"),"application/pdf"
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
if(mimeType.equals("application/pdf")){
Log.e(TAG, Uri.fromFile(file).toString()+" -- "+dir_file);
//mPDFView = new StudentPdfViewer();
// mPDFView.display("Symfony.pdf", false);
//handle it as activity
Intent intent1 = new Intent(this, PdfViewer.class);
intent1.putExtra(Config.COURSE_FILE, fileName);
//intent1.putExtra(SqliteDb.COURSE_NAME, listCategory.get(0).getCategory_name());
//intent1.putExtras(mBundle);
startActivity(intent1);
}else{
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(this, "Unable to load selected Course Material, Please check the Study Studio installation guide to install the required dependency softwares", Toast.LENGTH_LONG).show();
}
}
}
`
There is no "assets folder" on the device, and there is no "path to where the PDF file reside" on the device.
The contents of the assets/ folder(s) in your app's project are stored inside the APK. You can access assets via an AssetManager, and you get one of those by calling getAssets() on any handy Context, such as an Activity.