In my app i've got some data which I'd like to display into an Excel sheet.
Some days ago I've already managed to build the file .xls.
I've also been able to sent it by email whith this code:
FileOutputStream fos = null;
try {
file = new File(getContext().getFilesDir(), (main.getNomeAzienda() + "" + getDate(System.currentTimeMillis(), "dd-MM-yyyy_HH-mm")) + ".xls");
fos = new FileOutputStream(file);
workbook.write(fos);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_EMAIL, new String[]{FirebaseAuth.getInstance().getCurrentUser().getEmail()});
i.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(getActivity(), "com.example.authority.fileprovider", file));
i.putExtra(Intent.EXTRA_SUBJECT, "Raccolto globale aSista");
i.putExtra(Intent.EXTRA_TEXT, "In allegato il File Excel con i dati filtrati.");
try {
startActivity(Intent.createChooser(i, "Seleziona il Client di posta che vuoi utilizzare..."));
} catch (android.content.ActivityNotFoundException ex) {
Snackbar.make(main.getFab(), "Non ci sono client di posta disponibili installati sul dispositivo.", Snackbar.LENGTH_SHORT).show();
}
}
Snackbar.make(main.getFab(), "Foglio Excel generato.", Snackbar.LENGTH_SHORT).show();
Sorry if some parts of the code are in italian.
Anyway, now I'd like to display the excel file directly on the phone.
I downloaded some apps which should be able to display .xls file. Like Excel, this one from google and polaris office.
With this code i call the intent which ask the user to choose one of those app and open the file:
Uri path = Uri.fromFile(finalFile);
Intent excelIntent = new Intent(Intent.ACTION_VIEW);
excelIntent.setDataAndType(path , "application/vnd.ms-excel");
excelIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
startActivity(excelIntent);
}
catch (ActivityNotFoundException e) {
Snackbar.make(main.getFab(),"Impossibile aprire il file su questo dispositivo",Snackbar.LENGTH_LONG).show();
}
I've faced some problems related to the name of the file, which should't include some special characters. Then i finally been able to start opening the file but now i've got a problem.
Excel tells me "is not possible to open the file, an error has occurred".
Google docs the same.
Polaris doesn't display errors but it show an empty file.
Your file is in getFilesDir(). That is part of internal storage, and third-party apps do not have access to your portion of internal storage.
Since you already have FileProvider set up, use the FileProvider Uri, and use Intent.FLAG_GRANT_READ_URI_PERMISSION to give temporary read access to the other app.
Related
I have a word document(.doc or .docx) in the server. I need to open in my android application by clicking one button .doc file have to open. How to do this? anyone, please help me.
I tried this code :
File file = new File(Environment.getExternalStorageDirectory(),
"Document.docx");
try {
if (file.exists()) {
Uri path = Uri.fromFile(file);
Intent objIntent = new Intent(Intent.ACTION_VIEW);
// replace "application/msword" with
// "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
// for docx files
// objIntent.setDataAndType(path,"application/msword");
objIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(objIntent);
} else {
Toast.makeText(PMComplitionProjectActivity.this, "File NotFound",
Toast.LENGTH_SHORT).show();
}
} catch (ActivityNotFoundException e) {
Toast.makeText(PMComplitionProjectActivity.this,
"No Viewer Application Found", Toast.LENGTH_SHORT)
.show();
} catch (Exception e) {
e.printStackTrace();
}
I have this link that shows how to open any file in Android : http://www.androidsnippets.com/open-any-type-of-file-with-default-intent.html
Also, there is a similar case, which is done by PDF file : Android : how to open pdf file from server in android
I hope these links will work for you.
Good Luck,
G.
I am having an issue, I have never had problem opening files via ACTION_VIEW the next way:
File file = new File(getActivity().getFilesDir(), TEMP_FILE_NAME);
String dataType = "image/*";
if (file.exists()) {
Intent fileIntent = new Intent(Intent.ACTION_VIEW);
fileIntent.setDataAndType(Uri.fromFile(file), dataType);
fileIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
Intent intent = Intent.createChooser(fileIntent, "Open file");
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
Log.e(TAG, "There is a problem when opening the file");
}
} else {
Toast.makeText(getContext(), "Invalido", Toast.LENGTH_LONG).show();
}
The problem I am having right now is that even though the file exists when I choose the app to open the file it immediately closes and tells me Not found. I have put the image I am loading in an image view and there is no problem, so the file is valid but for some reason it has conflicts when I am opening it via intent.
I am aware that it may have something to do with the way I am creating the file, I am retrieving it from Google drive so I am writing the file using the Apache Commons library the next way:
DriveContents contents = result.getDriveContents();
InputStream inputStream = contents.getInputStream();
File file = new File(getActivity().getFilesDir(), TEMP_FILE_NAME);
try {
OutputStream outputStream = new FileOutputStream(file);
IOUtils.copy(inputStream, outputStream);
IOUtils.closeQuietly(inputStream);
IOUtils.closeQuietly(outputStream);
} catch (IOException e) {
e.printStackTrace();
}
What is it I am doing wrong? I am not totally sure if the problem has to do with the copy method executing asynchronously or something like that.
Thanks in advance.
I have never had problem opening files via ACTION_VIEW the next way
That code will never work, as third-party apps have no rights to work with files on getFilesDir() of your app.
What is it I am doing wrong?
You are attempting to serve an inaccessible file to third-party programs. Use FileProvider to serve the file, using FileProvider.getUriForFile() to get the Uri to use in your ACTION_VIEW Intent.
This question has been posted before, but there was no clear or accepted answer and all of the solutions provided that were supposed to "work" didn't for me. See here: Gmail 5.0 app fails with "Permission denied for the attachment" when it receives ACTION_SEND intent
I have an app which builds up data in a text file and needs to send the text file along in an email, automatically attaching it. I have tried many ways to get this to attach, and it apparently works for Gmail 4.9 and below but 5.0 has some new permission features disabling it from doing what I wish.
Intent i = new Intent(Intent.ACTION_SEND);
String to = emailRecipient.getText().toString();
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_EMAIL, new String[] { to });
i.putExtra(Intent.EXTRA_SUBJECT, "Pebble Accelerometer Data");
i.putExtra(Intent.EXTRA_TEXT, "Attached are files containing accelerometer data captured by SmokeBeat Pebble app.");
String[] dataPieces = fileManager.getListOfData(getApplicationContext());
for(int i2 = 0; i2 < dataPieces.length; i2++){
i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(getApplicationContext().getFilesDir() + File.separator + dataPieces[i2])));
}
i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(getApplicationContext().getFilesDir() + File.separator + fileManager.getCurrentFileName(getApplicationContext()))));
Log.e("file loc", getApplicationContext().getFilesDir() + File.separator + fileManager.getCurrentFileName(getApplicationContext()));
try {
startActivity(Intent.createChooser(i, "Send Email"));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(Main.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
}
The datapieces might be empty yes but the current file line below the for loop is always reliable and always attaches something.
I have tried changing
Uri.fromFile()
to
Uri.parse()
When I do that, it attaches, but Gmail then crashes and when I check the logcat it's because of a null pointer. This is most likely because Gmail has no access to the file and therefore results as null.
I've also tried using
getCacheDir()
instead of
getFilesDir()
and it has the same outcome.
What am I doing wrong here, and how should I go about fixing it? Some example code would be really, really handy because I am new to Android development and explaining what I need to do without some sort of push off probably won't end up helping.
Thanks a lot.
Alright guys. Took a break and came back, figured it out.
Here's how it works, you need to have write/read permissions to external storage, so add these permissions to your manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Then, your file has to be copied from your app's internal storage directory into the app's external directory. I recommend you use internal storage, and that's what I'm doing here so you can figure out SD cards yourself.
Here is the block of code that does the magic. Logs are included but you can remove them by all means.
public void writeToExternal(Context context, String filename){
try {
File file = new File(context.getExternalFilesDir(null), filename); //Get file location from external source
InputStream is = new FileInputStream(context.getFilesDir() + File.separator + filename); //get file location from internal
OutputStream os = new FileOutputStream(file); //Open your OutputStream and pass in the file you want to write to
byte[] toWrite = new byte[is.available()]; //Init a byte array for handing data transfer
Log.i("Available ", is.available() + "");
int result = is.read(toWrite); //Read the data from the byte array
Log.i("Result", result + "");
os.write(toWrite); //Write it to the output stream
is.close(); //Close it
os.close(); //Close it
Log.i("Copying to", "" + context.getExternalFilesDir(null) + File.separator + filename);
Log.i("Copying from", context.getFilesDir() + File.separator + filename + "");
} catch (Exception e) {
Toast.makeText(context, "File write failed: " + e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); //if there's an error, make a piece of toast and serve it up
}
}
Encountered the same attachment denied. Permissions in manifest did not have any effect, rather do not have an effect any more since API 23. Finally solved it as follows.
1st need to check and grant permissions on run-time, I did it in my main activity:
public static final int MY_PERMISSIONS_REQUEST_READ_STORAGE=10001;
private void checkPermission(){
if (this.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (this.shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE)) {
// Show an explanation to the user asynchronously
} else {
// No explanation needed, we can request the permission.
this.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_READ_STORAGE);
}
}
}
Now when sending, create a file in PUBLIC directory (tried saving to my app folder - same denial problem)
public File createFile(){
String htmlStr="<!DOCTYPE html>\n<html>\n<body>\n<p>my html file</p></body></html>";
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "aimexplorersummary.html");
try {
FileWriter writer = new FileWriter(file ,false);
writer.write(htmlStr);
}
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
return file;
}
Now compose sending intent and putExtra with uri to your file which is in public storage that user must grant permissions to and that causes no problem now
public void send(){
Intent intentSend = new Intent(android.content.Intent.ACTION_SEND);
intentSend.setType("text/html");
File file = createFile();
if(file!=null){
intentSend.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
}
startActivity(Intent.createChooser(intentSend, "Send using:"));
}
Few devices in android unable to read .crt (Certificate File) whereas few can. How to deal with this device related issue ? Is there any other Intent to open file other than ACTION_VIEW which can be an alternative to open file.
File vpnCerti = new File("/sdcard/VPNCertificate/Install.crt");
Uri path = Uri.fromFile(vpnCerti); //Mime Type Info : http://webdesign.about.com/od/multimedia/a/mime-types-by-content-type.htm
MimeTypeMap type_map = MimeTypeMap.getSingleton();
//Get the extension from the path
String extension = MimeTypeMap.getFileExtensionFromUrl(path.toString());
extension = extension.toLowerCase();
if (extension.contains(".")) {
extension = extension.substring(extension.lastIndexOf("."));
}
String mime_type = type_map.getMimeTypeFromExtension(extension);
Log.d("DownloadManager", "MIME Type : " + mime_type);
Intent i = new Intent();
i.setAction(android.content.Intent.ACTION_VIEW);
i.setDataAndType(Uri.fromFile(vpnCerti), mime_type);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try
{
Log.d("DownloadManager", "Trying to open file");
startActivity(i);
Log.d("DownloadManager", "Opened file");
}
catch(ActivityNotFoundException e)
{
Log.d("DownloadManager", "Couldn't open file");
Toast.makeText(SettingsActivity.this, "Couldn't find specific activity to open it", Toast.LENGTH_LONG).show();
}
I am not sure about the exact problem you are encountering right now (without the stack trace it is very hard to tell), but it may be because some of your devices don't have a SD card installed. In fact, I have been researching for the best solution to load a certificate, and if you only have a few certificates to manage, putting them in /res/raw/ folder might be a better idea than storing them in sd card. Here is how to load one from /res/raw/:
InputStream is = context.getResources().openRawResource(R.raw.cert_id);
I am downloading a pdf file from dropbox, it is downloaded in my sdcard, how can i read it, i know many people have asked this question, but i have not found a good answer uptil now, any help or guidance would be appriciated
Try This:
Uri uri = Uri.fromFile(mActivity.getFileStreamPath(mFileName));
try
{
Intent intentUrl = new Intent(Intent.ACTION_VIEW);
intentUrl.setDataAndType(uri, "application/pdf");
intentUrl.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
mActivity.startActivity(intentUrl);
}
catch (ActivityNotFoundException e)
{
Toast.makeText(mActivity, "No PDF Viewer Installed", Toast.LENGTH_LONG).show();
}