Currently, I need to update an installed application offline. To update the application, I have placed an apk file to the downloads folder of file manager and by pressing a button click event I want to update the apk but failed and facing an issue of "There was a problem while parsing the package error". I have rooted phone so is there any adb command or anything is available? I have also added exported="true" in manifest file and set allow to unknown permission for the app. Any help will be appreciable.
private void installApk() {
try {
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)+"/Demo.apk";
File file = new File(path);
Intent intent = new Intent(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= 24) {
Uri downloaded_apk = FileProvider.getUriForFile(MainActivity.this, getApplicationContext().getPackageName() + ".provider", file);
intent.setDataAndType(downloaded_apk, "application/vnd.android.package-archive");
List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
grantUriPermission(getApplicationContext().getPackageName() + ".provider", downloaded_apk, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
// startActivity(intent);
} else {
intent.setAction(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
minsdk is 19 and maxsdk is 33
Sending pdf files from my app to whatsapp was working until it was used on android 11 device
I have added this permission also and have asked for runtime permission
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R){
if (isPermissonGranted()){
Log.i("storageproblem","app runtime permission granted");
Uri fileuri = Uri.parse("file://" + file);
Intent share = new Intent(Intent.ACTION_SEND);
share.putExtra(Intent.EXTRA_STREAM, fileuri);
share.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
share.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
share.setPackage("com.whatsapp");
share.setType("*/*");
startActivity(share);
}else{
Log.i("storageproblem","app runtime permission not granted");
takePermisson();
}
}
instead of
Uri fileUri = Uri.parse("file://" + file);
use
Uri fileUri = FileProvider.getUriForFile(getApplicationContext(), "com.example.packagename.fileprovider", file);
Uri fileuri = Uri.parse("file://" + file);
Dont use a file uri but use a FileProvider to serve your file and can use a content scheme uri.
👍changing uri to file provider works
This question already has answers here:
Permission Denial with File Provider through intent
(4 answers)
Closed 11 months ago.
I am trying to share file with FileProvider. I checked that file is shared properly with apps like Gmail, Google Drive etc. Even though following exception is thrown:
2019-08-28 11:43:03.169 12573-12595/com.example.name E/DatabaseUtils: Writing exception to parcel
java.lang.SecurityException: Permission Denial: reading androidx.core.content.FileProvider uri content://com.example.name.provider/external_files/Android/data/com.example.name/files/allergy_report.pdf from pid=6005, uid=1000 requires the provider be exported, or grantUriPermission()
at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:729)
at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:602)
at android.content.ContentProvider$Transport.query(ContentProvider.java:231)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:104)
at android.os.Binder.execTransactInternal(Binder.java:1021)
at android.os.Binder.execTransact(Binder.java:994)
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_provider_paths" />
</provider>
file_provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="." />
</paths>
Sharing Intent
Intent intentShareFile = new Intent(Intent.ACTION_SEND);
File fileWithinMyDir = new File(targetPdf);
if (fileWithinMyDir.exists()) {
intentShareFile.setType("application/pdf");
Uri uri = FileProvider.getUriForFile(getActivity(), BuildConfig.APPLICATION_ID + ".provider", fileWithinMyDir);
intentShareFile.putExtra(Intent.EXTRA_STREAM, uri);
intentShareFile.putExtra(Intent.EXTRA_SUBJECT, "Sharing File...");
intentShareFile.putExtra(Intent.EXTRA_TEXT, "Sharing File...");
intentShareFile.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(intentShareFile, "Share File"));
}
Hopefully you can point out my mistake why this exceptions is thrown when it seems like apps are granted permission properly and sharing works as it should be.
EDIT:
I found that the problem lies in line:
startActivity(Intent.createChooser(intentShareFile, "Share File"));
When I changed it simply to
startActivity(intentShareFile);
However it displays a little bit different layout for picking application. But still I cannot figure out why original chooser is not working.
Sorry about the late response. I solved it like this:
Intent chooser = Intent.createChooser(intentShareFile, "Share File");
List<ResolveInfo> resInfoList = this.getPackageManager().queryIntentActivities(chooser, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
this.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
startActivity(chooser);
This helped me: Permission Denial with File Provider through intent
There is also a way to grant the URI permission through the Intent flag, without doing in manually with grantUriPermission() and by keeping the usage of Intent.createChooser().
The Intent.createChooser() documentation states:
If the target intent has specified FLAG_GRANT_READ_URI_PERMISSION or FLAG_GRANT_WRITE_URI_PERMISSION, then these flags will also be set in the returned chooser intent, with its ClipData set appropriately: either a direct reflection of getClipData() if that is non-null, or a new ClipData built from getData().
Therefore, if the original Intent has the Uri set in its ClipData or in setData(), it should work as wanted.
In your example, the ACTION_SEND Intent supports the Uri set through setClipData() as of Jelly Bean (Android 4.1).
Long story short, here is a working example of your code:
Intent intentShareFile = new Intent(Intent.ACTION_SEND);
File fileWithinMyDir = new File(targetPdf);
if(fileWithinMyDir.exists()) {
String mimeType = "application/pdf";
String[] mimeTypeArray = new String[] { mimeType };
intentShareFile.setType(mimeType);
Uri uri = FileProvider.getUriForFile(getActivity(), BuildConfig.APPLICATION_ID + ".provider", fileWithinMyDir);
// Add the uri as a ClipData
intentShareFile.setClipData(new ClipData(
"A label describing your file to the user",
mimeTypeArray,
new ClipData.Item(uri)
));
// EXTRA_STREAM is kept for compatibility with old applications
intentShareFile.putExtra(Intent.EXTRA_STREAM, uri);
intentShareFile.putExtra(Intent.EXTRA_SUBJECT,
"Sharing File...");
intentShareFile.putExtra(Intent.EXTRA_TEXT, "Sharing File...");
intentShareFile.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(intentShareFile, "Share File"));
}
In addition to the answer of Nit above, it is possible to set the ClipData directly with the to be shared uri as follows.
intent.setClipData(ClipData.newRawUri("", uri));
This prevents the security exception when presenting the intent chooser.
If you want to share multiple uris, you can set the clipdata with multiple uris to prevent the security exception. To summarize:
Intent intent = new Intent();
intent.setType(mimeType);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (uris.size() == 0) {
return;
}
else if (uris.size() == 1) {
Uri uri = uris.get(0);
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setClipData(ClipData.newRawUri("", uri));
}
else {
intent.setAction(Intent.ACTION_SEND_MULTIPLE);
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
ClipData clipData = ClipData.newRawUri("", uris.get(0));
for (int i = 1; i < uris.size(); i++) {
Uri uri = uris.get(i);
clipData.addItem(new ClipData.Item(uri));
}
intent.setClipData(clipData);
}
startActivity(Intent.createChooser(intent, title));
This worked for me.
Intent sharableIntent = new Intent();
sharableIntent.setAction(Intent.ACTION_SEND);
sharableIntent.setFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION );
Uri imageUri = Uri.parse(ImgLoc);
File imageFile = new File(String.valueOf(imageUri));
Uri UriImage = FileProvider.getUriForFile(context, Author, imageFile);
sharableIntent.setType("image/*");
sharableIntent.putExtra(Intent.EXTRA_STREAM, UriImage);
sharableIntent.putExtra(Intent.EXTRA_TITLE, title);
sharableIntent.putExtra(Intent.EXTRA_TEXT, body);
Intent chooser = Intent.createChooser(sharableIntent, "Chooser Title");
chooser.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
context.startActivity(chooser);
createChooser
Intent.createChooser():Builds a new ACTION_CHOOSER Intent that wraps the given target intent, also optionally supplying a title. If the target intent has specified FLAG_GRANT_READ_URI_PERMISSION or FLAG_GRANT_WRITE_URI_PERMISSION, then these flags will also be set in the returned chooser intent, with its ClipData set appropriately: either a direct reflection of getClipData() if that is non-null, or a new ClipData built from getData()
My app has Auto-Update feature. I install apk file using this code:
Uri uri;
Intent intent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file);
intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setData(uri);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
uri = Uri.fromFile(file);
intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(intent);
The problem is that in api 24 or higher Android package installer doesn't ask to click on "Done" or "Open" after updating completed and dialog will be closed without any questions or any messages.
I need package installer ask what to do like
.
[This question may be duplicate, but i din't find what i am looking for]
[Read]How can we open files like ppt, doc, pps, rtf, etc. in Android?
I am having PPT files. In my app, i have a list view which display the PPT file list available in my private app folder. In click of particular file, i want to open corresponding PPT file for reading in my App.
The App which i am creating is just like collection of PPTs and reading them one by one.
Please provide any API/Example/Links.
You need to use other application to open your ppt files , Make sure that file location you are providing is accessible to other application. Try with following :
final Uri uri = Uri.fromFile(file);
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "application/vnd.ms-powerpoint");
PackageManager pm = getPackageManager();
List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);
if(list.size() > 0)
startActivity(context, intent);
Available application will be shown to user and user can choose application which can open.
private void openPPT(final String path) {
File file = new File(path);
Uri uri ;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
uri = FileProvider.getUriForFile(context, context.getPackageName() + ".provider", file);
} else {
uri = Uri.fromFile(file);
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setDataAndType(path, "application/vnd.ms-powerpoint");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(this, "Application not found", Toast.LENGTH_SHORT).show();
}
}