What i am trying is to share a file over bluetooth. I have tried below two methods to pass the file name to the ACTION_SEND intend. share activity is pop'ing up and when i touch the connected bluetooth device, i get a toast saying Bluetooth share: File Unknown file not sent. Both the method fails.
public void pushFileOverOpp(String filename) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setPackage("com.android.bluetooth");
intent.setType("audio/mp3");
File f = new File(Environment.getExternalStorageDirectory(), "images");
File sample = new File(f, "sample.mp3");
Uri u = Uri.parse(sample.toString());
intent.putExtra(Intent.EXTRA_STREAM, u);
mContext.startActivity(intent);
}
Error , Log-
OppService: URI : /storage/emulated/0/images/sample.mp3
OppService: HINT : null
OppService: FILENAME: null
OppService: MIMETYPE: audio/mp3
File f = new File(mContext.getFilesDir(), "images");
File sample = new File(f, "sample.mp3");
Uri u = FileProvider.getUriForFile(mContext,
BuildConfig.APPLICATION_ID + ".provider", sample);
intent.putExtra(Intent.EXTRA_STREAM, u);
Error, Log-
OppService: URI : content://com.example.com.test.provider/tester/images/sample.mp3
OppService: HINT : null
OppService: FILENAME: null
I have checked the android source code, This error comes when filename is null. Log also says filename is null. But i could not figure out the exact reason. Could someone Please help me out here, what is wrong with my code.
After some study i understood the problem. There were two issues-
xml tag for external storage(/sdcard/) directory was wrong in xml file.
I changed as below.
<root-path
name="root"
path="/" />
URI permission was not granted
mContext.grantUriPermission("com.android.bluetooth", u,
Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
After modifying with above lines of code, File share is working !
full working code-
public boolean pushFileOverOpp(String filename) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("*/*"); // supports all mime types
intent.setPackage("com.android.bluetooth"); //bluetooth package name, default opp
File folder = new File(Environment.getExternalStorageDirectory(), "images");
File file = new File(folder, filename);
if (!file.exists()) {
Logger.e("No such file " + filename + " exists!");
return false;
}
Uri u = FileProvider.getUriForFile(mContext, mContext.getPackageName() + ".provider", file);
intent.putExtra(Intent.EXTRA_STREAM, u);
mContext.grantUriPermission("com.android.bluetooth", u,
Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
Logger.d("Sharing file over bluetooth " + folder.toString());
mContext.startActivity(intent);
return true;
}
Thanks.
Please refer this code , it works and share the files using createChooser method.
ArrayList<Uri> arrayList2 = new ArrayList<>();
String MEDIA_PATH = new String(Environment.getExternalStorageDirectory() +
"/NewCallLogs/audio.mp3");
File files = new File(MEDIA_PATH);
Uri u = Uri.fromFile(files);
arrayList2.add(u);
Intent share = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE);
share.setData(Uri.parse("mailto:"));
share.setType("audio/mpeg");
share.putExtra(android.content.Intent.EXTRA_STREAM, arrayList2);
try {
startActivity(Intent.createChooser(share, "Share..."));
// getActivity().finish();
Log.i("Finished sharing.", "");
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(getActivity(), "nothing shared.", Toast.LENGTH_SHORT).show();
}
For sharing the file only in bluetooth
ArrayList<Uri> arrayList2 = new ArrayList<>();
String MEDIA_PATH = new String(Environment.getExternalStorageDirectory() +
"/NewCallLogs/audio.mp3" );
File files = new File(MEDIA_PATH);
Uri u = Uri.fromFile(files);
arrayList2.add(u);
Intent share = new Intent(android.content.Intent.ACTION_SEND);
share.setData(Uri.parse("mailto:"));
share.setType("audio/mpeg");
share.setPackage("com.android.bluetooth");
share.putExtra(android.content.Intent.EXTRA_STREAM, arrayList2);
startActivity(share);
Related
I need to share 2 csv files I created in my app.
I was able to share one of them with the below code, but how to I pass 2 files to share?
for (File file : fileList) {
if (!file.exists()) {
Toast.makeText(ExcelExportActivity.this, "File doesn't exists", Toast.LENGTH_LONG).show();
return;
}
Uri uri = FileProvider.getUriForFile(ExcelExportActivity.this, "com.example.farmers.provider", file);
grantUriPermission(ExcelExportActivity.this.getPackageName(), uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
sharingIntent.setType("text/csv");
sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);
}
sharingIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
sharingIntent.putExtra(Intent.EXTRA_SUBJECT, "my subject");
startActivity(Intent.createChooser(sharingIntent, "sharing with..."));
You will need to use Intent.ACTION_SEND_MULTIPLE instead of Intent.ACTION_SEND.
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND_MULTIPLE);
intent.putExtra(Intent.EXTRA_SUBJECT, "Here are some files.");
intent.setType("text/csv");
ArrayList<Uri> files = new ArrayList<Uri>();
for(String path : filesToSend /* List of the files you want to send */) {
File file = new File(path);
Uri uri = Uri.fromFile(file);
files.add(uri);
}
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, files);
startActivity(intent);
i'm trying to send (install) my mcpack file using this code but is is not working, minecraft support this type of extenstion to install mods (.mcpack, .mcaddon, .mcworld, .mctemplate, .modpkg how we can define mimetypes for these extensions)
please go through this image i need exactly like this https://imgur.com/14rIBvN
try {
//File path = new File(getFilesDir(), "dl");
File file = new File(path);
PackageManager manager = this.getPackageManager();
// Get URI and MIME type of file
Intent share = new Intent(Intent.ACTION_SEND);
//share.setType("image/jpeg");
share.putExtra(Intent.EXTRA_STREAM, Uri.parse(path));
share.setPackage("com.mojang.minecraftpe");//package name of the app
startActivity(Intent.createChooser(share, "Select Minecraft to install"));
} catch (Exception e) {
Log.i(TAG, "App not found.. "+e.getMessage());
}
i did it!)
File file = new File(this.getExternalFilesDir(null), "1.mcpack");
Uri photoURI = FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".provider", file);
Intent intent = new Intent(Intent.ACTION_VIEW);
// set the content type and data of the intent
intent.setDataAndType(photoURI, "application/octet-stream");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// start the intent as a new activity
startActivity(intent);
Open with minecraft and it will open and it will day download started and if it works it will say, If it does not work it will say, Minecraft onlu supports .mcpack, .mcworld, .mctemplate on pocket edition
I'm creating an app, and in this app have a button to open an PDF with a calendar with activities of user...
The PDF is in assets folder.
And the actualy code is:
private void abrirCalendario() {
AssetManager assetManager = getAssets();
File fileDir = new File(Environment.getExternalStorageDirectory().getPath() + "/");
fileDir.mkdirs();
File file = new File(fileDir, "Calendario DAERG.pdf");
String path = Environment.getExternalStorageDirectory().getPath() + "/Calendario DAERG.pdf";
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(this, getPackageName() + ".provider", new File(path));
List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = "tk.davidev.android.ews";
grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
}else {
uri = Uri.fromFile(new File(path));
}
if(!file.exists()) {
try {
InputStream in = assetManager.open("calendario_2017.pdf");
OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
copyFile(in, out);
in.close();
out.flush();
out.close();
} catch (Exception e) {
}
}
intent.setDataAndType(uri, "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
And the error i'm getting is:
file:///storage/emulated/0/Calendario DAERG.pdf exposed beyond app through Intent.getData()
Hi because Android from Mashmellow , I think, changes its segurity behavior such as request for permission on runtime or using FileProvider to manage URI. Now me have to give permission in some code in order to work.
Here's an example of open Intent with ACTION_VIEW in Nougat
File archivo= new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES),"excerpt_DEC.pdf");
Uri uri = FileProvider.getUriForFile(this,
"com.example.android.fileprovider",
archivo);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri,"application/pdf");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivity(intent);
My example is the same as yours. I read a file from assets then, I find that file created and save it in archivo object. Later on, get an uri with FileProvider method and finally, I give permissions to intent with this line
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
I leave you this link for background knowledge about this new implementation.
https://developer.android.com/reference/android/support/v4/content/FileProvider.html
Also, I followed this anwser to read my file.pdf from asset
https://stackoverflow.com/a/7495078/8650422
Hope to help, greetings !
I am trying to attach a pdf file in gmail app. I have read this and this (applied solution) I am trying as;
public static void attachFile(Context ctx) {
String TAG = "Attach";
File documentsPath = new File(ctx.getFilesDir(), "documents");
Log.i(TAG,"documentsAbsolutePath Output");
Log.i(TAG, documentsPath.getAbsolutePath().toString());
File file = new File(documentsPath, "sample.pdf");
if ( file.exists() ) {
Toast.makeText(ctx, "Exits", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(ctx, "Not Exist", Toast.LENGTH_LONG).show();
}
Log.i(TAG,"file Output");
Log.i(TAG, file.toString());
Log.i(TAG, String.valueOf(file.length()));
Uri uri = FileProvider.getUriForFile(ctx, "com.example.fyp_awais.attachfiletest2.fileprovider", file);
Log.i(TAG,"URI Output");
Log.i(TAG,uri.toString());
Intent intent = ShareCompat.IntentBuilder.from((Activity) ctx)
.setType("application/pdf")
.setStream(uri)
.setChooserTitle("Choose bar")
.createChooserIntent()
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
ctx.startActivity(intent);
}
Outputs
documentsAbsolutePath Output
/data/data/com.example.fyp_awais.attachfiletest2/files/documents
file Output
/data/data/com.example.fyp_awais.attachfiletest2/files/documents/sample.pdf
0
URI Output
content://com.example.fyp_awais.attachfiletest2.fileprovider/pdf_folder/sample.pdf
Menifest
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.fyp_awais.attachfiletest2.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/filepath" />
</provider>
FilePath.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="pdf_folder" path="documents/"/>
</paths>
</PreferenceScreen
A pdf file is saved in Galaxy Core Prime\Phone\documents. (file size: 53.7KB)
But it gives
Cannot attach empty file.
I am confused with folder-name in this line <files-path name="pdf_folder" path="documents/"/>. The file is in the \Phone\documents. Then why folder name?
Edit 1
Tried to replace setType(application/pdf) with setType("message/rfc822") But did not work. Any help?
Send the file in URI format like this:
Intent emailIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
emailIntent.setData(Uri.parse("mailto:"));
emailIntent.setType("application/image");
emailIntent.putExtra(Intent.EXTRA_EMAIL, TO);
emailIntent.putExtra(Intent.EXTRA_CC, CC);
ArrayList<Uri> uris = new ArrayList<>();
//convert from paths to Android friendly Parcelable Uri's
uris.add(frontImageUri);
uris.add(backImageUri);
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
startActivity(Intent.createChooser(emailIntent, "Send mail..."));
if it's ok To send Zip then try this way
String fileNameStor_zip = Environment.getExternalStorageDirectory() + "/" + fileName + ".zip";
String[] path = { your 1st pdf File Path, your 2nd pdf File Path};
Compress compress = new Compress(path, fileNameStor_zip);
compress.zip();
URI = Uri.parse("file://" + fileNameStor_zip);
Provide your Gmail Intent
intent.putExtra(Intent.EXTRA_STREAM, URI);
Uri contentUri = FileProvider.getUriForFile(this, "com.mydomain.fileprovider", newFile);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
i.setData(contentUri);
String filename="my_file.vcf";
File filelocation = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), filename);
Uri path = Uri.fromFile(filelocation);
Intent emailIntent = new Intent(Intent.ACTION_SEND);
// set the type to 'email'
emailIntent .setType("vnd.android.cursor.dir/email");
String to[] = {"asd#gmail.com"};
emailIntent .putExtra(Intent.EXTRA_EMAIL, to);
// the attachment
emailIntent .putExtra(Intent.EXTRA_STREAM, path);
// the mail subject
emailIntent .putExtra(Intent.EXTRA_SUBJECT, "Subject");
startActivity(Intent.createChooser(emailIntent , "Send email..."));
You have to grant the permission to access storage for gmail.
In case it helps- here's what I do in an app debug function with a few files, it shouldn't really be any different.
I do copy/export them into a user-public folder first before attaching them, and make them world readable.
if (verifyStoragePermissions(c)) {
final Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"recipient#email.address"});
intent.putExtra(Intent.EXTRA_SUBJECT, "Email Subject");
//build up message
ArrayList<Uri> uris = new ArrayList<>();
StringBuilder content = new StringBuilder();
content.append(
String.format(
c.getString(R.string.message_log_upload_email_body) +
"\n\nmodelDesc:%s \n\nmanuf:%s \n\naId: %s,\n\nhIid: %s,\n\nfbId: %s.",
Build.MODEL, Build.MANUFACTURER, getSomeVar1(), getSomeVar2(), getSomeVar3())
);
content.append("\n\nMy logged in account id is: ").append(getAccountId(c)).append(".");
content.append("\n\nHere's an overview of my attachments:\n");
for (String s : addresses) {
File f = new File(s);
//noinspection ResultOfMethodCallIgnored
f.setReadable(true, false);
Uri add = Uri.fromFile(f);
//add attachment manifest
content.append(String.format(Locale.UK, "|-> %s (%.3f kb)\n", f.getName(), (float) f.length() / 1024));
uris.add(add);
}
//attach the things
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
//set content/message
intent.putExtra(Intent.EXTRA_TEXT, content.toString());
c.startActivity(intent);
}
}
addresses is a String[] param to that function. I build it up by making the functions I use to export the files return arrays of strings of the addresses of the files they've exported - as I initially store the files in my app's private storage
I'm trying to open a file using another app, i.e. opening a .jpg with Gallery, .pdf with Acrobat, etc.
The problem I'm having with this is when I try to open the file in the app, it only opens the chosen app instead of opening the file within the app. I tried following Android open pdf file via Intent but I must be missing something.
public String get_mime_type(String url) {
String ext = MimeTypeMap.getFileExtensionFromUrl(url);
String mime = null;
if (ext != null) {
mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext);
}
return mime;
}
public void open_file(String filename) {
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), filename);
// Get URI and MIME type of file
Uri uri = Uri.fromFile(file).normalizeScheme();
String mime = get_mime_type(uri.toString());
// Open file with user selected app
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(uri);
intent.setType(mime);
context.startActivity(Intent.createChooser(intent, "Open file with"));
}
As far as I can tell, it returns the right URI and MIME type:
URI: file:///storage/emulated/0/Download/Katamari-ringtone-985279.mp3
MIME: audio/mpeg
Posting my changes here in case it can help someone else. I ended up changing the download location to an internal folder and adding a content provider.
public void open_file(String filename) {
File path = new File(getFilesDir(), "dl");
File file = new File(path, filename);
// Get URI and MIME type of file
Uri uri = FileProvider.getUriForFile(this, App.PACKAGE_NAME + ".fileprovider", file);
String mime = getContentResolver().getType(uri);
// Open file with user selected app
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(uri, mime);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
}
I used this piece of code and it worked perfectly fine on android 6 and below not tested on the higher version
public void openFile(final String fileName){
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(new File(android.os.Environment.getExternalStorageDirectory()
.getAbsolutePath()+ File.separator+"/Folder/"+fileName));
intent.setDataAndType(uri, "audio/mpeg");
startActivity(intent);
}