Nach vielen Versuchen konnte ich dieses Problem lösen, indem ich verschiedene Absichten für etwas niedrigeres als Nougat erstellte, indem ich mit dem FileProvider eine Installationsabsicht mit Android-Versionen erstellte, bevor Nougat den Fehler verursacht:
ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.INSTALL_PACKAGE dat=content://XXX.apk flg=0x1 }
Bei Verwendung eines normalen Uri unter Android erzeugt Nougat den folgenden Fehler:
FileUriExposedException: file:
Meine Lösung, die für mich mit Android N auf dem Emulator und einem Telefon mit Android M funktioniert.
File toInstall = new File(appDirectory, appName + ".apk");
Intent intent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri apkUri = FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".fileprovider", toInstall);
intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setData(apkUri);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
Uri apkUri = Uri.fromFile(toInstall);
intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
activity.startActivity(intent);
UPDATE FÜR Android Nougat 7.1:
Sie müssen auch die Berechtigung REQUEST_INSTALL_PACKAGES in Ihrem Manifest hinzufügen. Es ist ab Api Level 23 (Android 6.0 Marshmallow) verfügbar und ab Level 25 (Android 7.1 Nougat) erforderlich.
AKTUALISIEREN:
Denken Sie daran, die Berechtigungen zum Lesen und Schreiben in den externen Speicher anzufordern, wenn sich die zu installierende Datei im externen Speicher befindet. Und auch, um einen korrekten FileProvider für Android Nougat und höher einzurichten.
Überprüfen Sie zunächst, ob Sie über eine Schreibberechtigung verfügen, indem Sie canReadWriteExternal()
unten anrufen . Wenn nicht, rufen Sie requestPermission()
vorher an:
private static final int REQUEST_WRITE_PERMISSION = 786;
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == REQUEST_WRITE_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED)
Toast.makeText(this, "Permission granted", Toast.LENGTH_LONG).show();
}
private void requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
requestPermissions(new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_PERMISSION);
}
private boolean canReadWriteExternal() {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M ||
ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED;
}
Hier ist ein Beispiel eines Dateianbieters für den Download-Ordner im externen Speicher. AndroidManifest.xml :
<application ... >
...
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
</application>
resources / xml / filepaths.xml :
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_download" path="Download"/>
</paths>
Wenn beim Installieren der .apk-Datei eine Fehlermeldung angezeigt wird, die besagt, dass beim Parsen des Pakets ein Problem vorliegt. Möglicherweise haben Sie nicht nach der Lese- / Schreibberechtigung gefragt, oder die Datei, die Sie installieren möchten, ist nicht vorhanden oder beschädigt.
ACTION_INSTALL_PACKAGE
. Das hat bei mir ab der Juni-Ausgabe der N Developer Preview funktioniert .