im getting the following error in my logcat.
: android.os.FileUriExposedException: file:///storage/emulated/0/download/AllCast.apk exposed beyond app through Intent.getData()
it only happening on some devices ie marsh mellow and nougat.
this is where error occurs
intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" + newnamestring)), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
ive tried adding this line of code
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
also tried this in my app class
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
builder.detectFileUriExposure();
can anybody tell me what im doing wrong. thanks
EDIT****
Ok guys im trying to get #CommonsWare answer to work i can get the file to download fin to the provider folder. but then my app crashes when it trys to handle the intent. here is my new log cat
05-07 16:25:35.784 8715-8715/com.example.harrops.h20droidapp2 E/AndroidRuntime: FATAL EXCEPTION: main
Process: mypackagename, PID: 8715
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.io.File.getName()' on a null object reference
at my package name.Casting_Apps$DownloadFileFromURL.onPostExecute(Casting_Apps.java:273)
which leads me to section of code
File newFile = null;
MimeTypeMap mime = MimeTypeMap.getSingleton();
String ext = newFile.getName().substring(newFile.getName().lastIndexOf(".") + 1);
String type = mime.getMimeTypeFromExtension(ext);
try {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri contentUri = FileProvider.getUriForFile(getBaseContext(), "my package name", newFile);
intent.setDataAndType(contentUri, type);
} else {
intent.setDataAndType(Uri.fromFile(newFile), type);
}
startActivityForResult(intent, ACTIVITY_VIEW_ATTACHMENT);
} catch (ActivityNotFoundException anfe) {
Toast.makeText(getBaseContext(), "No activity found to open this attachment.", Toast.LENGTH_LONG).show();
}
This is the answer i went for.. thanks #CommonsWare for the help
File toInstall = new File(appDirectory, appName + ".apk");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri apkUri = FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".provider", toInstall);
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setData(apkUri);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
activity.startActivity(intent)
} else {
Uri apkUri = Uri.fromFile(toInstall);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(intent);
}
Related
I have a launcher type application from which user can install different apps. It is working completely fine but the apk's from different apps just keep stacking up and taking too much space.
Is there a way that I can detect that application installation has completed when using new Intent(Intent.ACTION_INSTALL_PACKAGE) and then I could delete the previously downloaded apk... after the installation has completed.
Here is some code:
Intent openDownloadIntent = getOpenDownloadedApkIntent(context, file);
try {
context.startActivity(openDownloadIntent);
} catch (ActivityNotFoundException e) {
// TODO
}
private static Intent getOpenDownloadedApkIntent(Context context, File file) {
// The type of intent to use to open the downloaded apk changed in Android N (7.0)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri path = FileProvider.getUriForFile(context,
context.getApplicationContext().getPackageName() + ".utils.DownloadedFileProvider",
file);
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setData(path);
return intent;
} else {
Uri uri = Uri.fromFile(file);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "application/vnd.android.package-archive");
return intent;
}
}
Bundle intent = getIntent().getExtras();`
cardView=(CardView)findViewById(R.id.card);
final String query = intent.getString("Query1");
db = new DataBaseHelper(Image.this);
Cursor c = db.getData(query);
if (c.getCount() != 0) {
c.moveToFirst();
do {
image = c.getString(5);
title=c.getString(3);
} while (c.moveToNext());
}
txt.setText(title);
img.setImageDrawable(getResources().getDrawable(getResources().getIdentifier(image, "drawable", getPackageName())));
To create an Share Intent for image, you can use following code.
uriToImage is Uri of your image file.
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
shareIntent.setType("image/jpeg");
startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.send_to)));
EDIT - To get URI of drawable image
Uri uri = Uri.parse("android.resource://your.package.here/drawable/image_name");
Use Content Provider(FileProvider) To Share Data as it is Good Practice.
Intent intent = new Intent(Intent.ACTION_SEND);
final String path = "Your File Path";
Uri uri = FileProvider.getUriForFile(YourActivity.this, "com.abc.xy.appname.fileprovider", new File(path));
intent.setDataAndType(uri, "image/*");
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
intent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(intent);
For Multiple File Sharing
ArrayList<Uri> files = new ArrayList<Uri>();
for (int i = 0; i < mfileList.size(); i++) {
File file = new File(mfileList.get(i).get_path());
Uri uri = FileProvider.getUriForFile(YourActivity.this, "com.abc.xy.appname.fileprovider", file);
files.add(uri);
}
Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
intent.setType("image/jpeg");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_STREAM, files);
startActivity(intent);
To Share an Image Stored in Your Drawable.Put this Uri in your Share Intent Extras.
Uri uri = Uri.parse("android.resource://your.package/drawable/image_name");
Check this Link out For Content Provider Setup.
[https://developer.android.com/reference/android/support/v4/content/FileProvider][1]
I have a webview app and wanted to updated app from inside when a certain text is present in the url.
I am calling these in shouldOverrideUrlLoading function of webview:
Intent intent = new Intent(getApplicationContext(), Update.class);
startActivity(intent);
return true;
And here is the Update.class
public class Update extends MainActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
String destination = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
String fileName = "app-file.apk";
destination += fileName;
final Uri uri = Uri.parse("file://" + destination);
File file = new File(destination);
if (file.exists())
file.delete();
DownloadManager.Request request = new DownloadManager.Request(
Uri.parse(getIntent().getStringExtra("http://example.com/app-file.apk")));
request.setDestinationUri(uri);
dm.enqueue(request);
final String finalDestination = destination;
final BroadcastReceiver onComplete = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri contentUri = FileProvider.getUriForFile(ctxt, BuildConfig.APPLICATION_ID + ".provider", new File(finalDestination));
Intent openFileIntent = new Intent(Intent.ACTION_VIEW);
openFileIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
openFileIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
openFileIntent.setData(contentUri);
startActivity(openFileIntent);
unregisterReceiver(this);
finish();
} else {
Intent install = new Intent(Intent.ACTION_VIEW);
install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
install.setDataAndType(uri, "application/vnd.android.package-archive");
startActivity(install);
unregisterReceiver(this);
finish();
}
}
};
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
}
When I go to the certain url to start the activity, the app crashes. I would love to see any solution. Thanks!!
I SOLVED IT, it was permission error.
I would suggest you to look into ADB Logcat, which will help you to fix the issue.
Otherwise, check into crash log or make sure that you have declared your Update Activity in manifest.xml
Make sure you declare the new activity in your Android Manifest.xml
try changing this
Intent intent = new Intent(getApplicationContext(), Update.class);
startActivity(intent);
return true;
to this
Intent intent = new Intent(getApplicationContext(), Update.class);
startActivity(intent);
finish();
return true;
Let me know how that went.
My goal is to upload a specific videofile to youtube from my app.
Here some code from my Method:
File videoToPlayFile = new File(mSharedPreferences.getString("output_file", ""));
Intent intent = new Intent();
intent.setDataAndType(Uri.fromFile(videoToPlayFile), "video/*");
Intent intent2 = YouTubeIntents.createUploadIntent(this,intent.getData());
startActivity(intent2);
I get the error that the Uri path from intent.getData needs to begin with content://media, but when I take Logs it allways showas a path like file://mnt/sdcard/blablabla.mp4
It is necessary to start intent with an image resource.
Uri path = Uri.parse("android.resource://" + getPackageName() + "/" + R.drawable.ic_launcher);
Intent intent = new Intent(Intent.ACTION_VIEW, null);
intent.setData(path);
intent.setType("image/png");
startActivity(intent);
There is an error: "the gallery is closed"
Where is my problem?