I am trying to install apk after it has been downloaded by the download manager. I am using a broadcast to get the message after download completes. This is my code below:-
FileProvider: Installing APK. There was an error parsing the package.
val file = File(getExternalFilesDir("Download"), "/playlist/update.apk")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val apkUri = FileProvider.getUriForFile(this#MainActivity, BuildConfig.APPLICATION_ID + ".provider", file)
val intent = Intent(Intent.ACTION_INSTALL_PACKAGE)
intent.data = apkUri
intent.flags= Intent.FLAG_GRANT_READ_URI_PERMISSION
this#MainActivity.startActivity(intent)
} else {
val apkUri = Uri.fromFile(file)
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
this#MainActivity.startActivity(intent)
}
Manifest:-
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/filepaths" />
</provider>
filespath.xml :-
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="Download" path="Download/" />
</paths>
I am downloading the apk in "Downloads/playlist/" dir. I saw this same problem - here. However I have can't seem to get it working from that solution. I also checked the apk by installing it myself and it gets installed without any errors. Please help.
Related
Hello i'm trying to install an apk programmatically.
AndroidManifest.xml:
<application android:label="ABM.Ablesegeraet.Android">
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths">
</meta-data>
</provider>
</application>
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>
other code:
var context = Android.App.Application.Context;
Java.IO.File file = new Java.IO.File(GetExternalFilesDir("").AbsolutePath + $"/com.companyname.abm.ablesegeraet.apk");
var downloadUri = Xamarin.Essentials.FileProvider.GetUriForFile(context, context.ApplicationContext.PackageName + ".fileprovider", file);
Intent install = new Intent(Intent.ActionView);
install.AddFlags(ActivityFlags.NewTask);
install.AddFlags(ActivityFlags.GrantReadUriPermission);
install.AddFlags(ActivityFlags.GrantWriteUriPermission);
install.AddFlags(ActivityFlags.GrantPersistableUriPermission);
install.SetDataAndType(downloadUri, "application/vnd.android.package-archive");
context.StartActivity(install);
I don't get any errors but when context.StartActivity(install) is executed nothing happens.
What's the problem here?
//edit: this does not work in debug... In Release the activity does start but for some reasen it fails during the installation... It just says "App has not been installed" But why?
//edit2: to solve the "App has not been installed" error I had to delete the app and install it with a APK and not from visual studio. Also the update apk needs to have a higher build version than the installed one.
I am using FileProvider to install apk from my app. Followed many stackoverflow questions but still facing this issue
java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.tssi.myapptour/files/download/myapp_newSigned.apk
My provider in manifest
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.tssi.myapptour.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
my file_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="download" path="download/" />
<!-- <external-path name="download" path="Android/data/com.tssi.myapptour/files/download/" />-->
</paths>
And my code for calling apk
String strApkToInstall = "myapp_newSigned.apk";
File fileApkToInstall = new File(getExternalFilesDir("download"), strApkToInstall);
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri fileUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider",
fileApkToInstall);
intent.setDataAndType(fileUri, "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
Your file is in getExternalFilesDir(). That does not match files-path in your FileProvider metadata. Either:
Switch to getFilesDir() (a much better solution from a security standpoint), or
Switch to external-files-path
See the FileProvider documentation for more about the mapping between filesystem locations and metadata entries.
I am using File provider for installing downloaded APK using Google Package installer in Android TV But always stuck on Package Parsing Error.
The same code base is working fine on android Mobile phone OS but not on Android TV. To note, Mine is a system application and have all the required permissions like REQUEST_INSTALL_PACKAGES, READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE but still no luck.
Can any folk please help me if this is a known bug on Android TV or there is something special need my attention.
Checklist:
1. Provider cross-checked with authority to grantURIPermissions
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
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="."/>
<files-path
name="data"
path="."/>
<cache-path
name="cache"
path="." />
<external-path name="external_download" path="Download"/>
<external-files-path name="Download" path="Download/" />
val uri = FileProvider.getUriForFile(this#MainActivity, BuildConfig.APPLICATION_ID+".provider", file)
val intent = Intent(Intent.ACTION_VIEW)
intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
intent.setDataAndType(uri, "application/vnd.android.package-archive")
val resInfoList = context?.packageManager?.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
resInfoList?.let {
for (res in resInfoList) {
val packageName = res.activityInfo.packageName
context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
}
}
startActivity(intent)
internal fun getDownloadFileLoc(context: Context): String {
val fileDir = "${Environment.getExternalStorageDirectory()}/download"
val fileName = context.getString(R.string.apk_name)
return "$fileDir/$fileName"
}
I get a warning that permission denial for provider. Please tell me if I have to provide some specific information.
I want to show a notification and when user clicked install an APK file.
I know how to use the fileProvider itself but I have problem with service context.
Here is my code
manifest:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.company.app"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/filepaths" />
</provider>
filePaths:
<paths>
<external-path
name="externalFiles"
path="." />
</paths>
service Code:
resultIntent = new Intent(Intent.ACTION_VIEW);
Uri uri;
File file = FileHelper.getApkFile(item.getLink());
if (Build.VERSION.SDK_INT >= 24) {
uri = FileProvider.getUriForFile(
NotificationService.this,
NotificationService.this.getApplicationContext().getPackageName(),
file);
NotificationService.this.setResult(Activity.RESULT_OK,
resultIntent);
} else {
uri = Uri.fromFile(file);
}
resultIntent.setDataAndType(uri, "application/vnd.android.package-archive");
resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
as you know setResult() is not available in service.
How can I grant permission from service context?
thank you every one.
I found the problem
I had to add this permission to my manifest to install apk file.
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
I am trying to install an .apk I have downloaded to the downloads folder in Android 7.
I have tried the way recommended in a number of StackOverflow posts and here https://inthecheesefactory.com/blog/how-to-share-access-to-file-with-fileprovider-on-android-nougat/en by using a FileProvider:
File file = new File(fileUri);
//using Android.Support.V4.Content;
var downloadUri = FileProvider.GetUriForFile(context,context.ApplicationContext.PackageName + ".com.package.name.provider", file);
Intent install = new Intent(Intent.ActionInstallPackage);
install.AddFlags(ActivityFlags.GrantReadUriPermission);
install.AddFlags(ActivityFlags.GrantWriteUriPermission);
install.AddFlags(ActivityFlags.GrantPersistableUriPermission);
install.SetDataAndType(downloadUri, "application/vnd.android.package-archive");
context.StartActivity(install);
AndroidManifest.xml
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<application android:label="Settings" android:icon="#drawable/Icon" android:theme="#style/myTheme">
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.com.package.name.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
</application>
provider_paths.xml
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="." />
</paths>
The "downloadUri" looks like: "content://com.package.name.com.package.name.provider/external_files/Download/Sensors%2520Multitool_1.3.0_apk-dl.com.apk"
The error when the installation window pops up is: "There was a problem parsing the package".
I have installed this package by clicking on it in the downloads folder and it installs fine, I have also tried other .apk's with the same issue.
File file = new File(fileUri);
if(Build.VERSION.SdkInt >= Build.VERSION_CODES.N) {
Uri apkUri = FileProvider.GetUriForFile(context, context.ApplicationContext.PackageName + ".provider", toInstall);
Intent intentS = new Intent(Intent.ActionInstallPackage);
intentS.SetData(apkUri);
intentS.SetFlags(ActivityFlags.GrantReadUriPermission);
context.StartActivity(intentS);
} else {
Uri apkUri = Uri.FromFile(toInstall);
Intent intentS = new Intent(Intent.ActionView);
intentS.SetDataAndType(apkUri, "application/vnd.android.package-archive");
intentS.SetFlags(ActivityFlags.NewTask);
context.StartActivity(intentS);
}
It appears that the issue in parsing the package was due to the space in the package name "Sensors%2520Multitool_1.3.0_apk-dl.com.apk".
As soon as the space was removed the package installed correctly.