Programmatically install an apk in Android 7 / api24

For Oreo, Add permission in AndroidManifast

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>

Here is the solution I have found

val newFile = File(dirPath, "$fileNameWithoutExtn.apk")
                        var fileUri = Uri.fromFile(newFile)
                        //use the fileProvider to get the downloaded from sdcard
                        if (Build.VERSION.SDK_INT >= 24) {
                            fileUri = FileProvider.getUriForFile(this@SettingAcitivity, applicationContext.packageName + ".provider", newFile)
                         val intent=Intent(Intent.ACTION_VIEW)
                            intent.setDataAndType(fileUri, "application/vnd.android.package-archive")
                            intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
                            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                            startActivity(intent)
                        }else{
                            newFile.setReadable(true, false)
                            val intent = Intent(Intent.ACTION_VIEW)
                            intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
                            intent.setDataAndType(fileUri, "application/vnd.android.package-archive")
                            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                            startActivity(intent)
                        }

and write in 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/paths"/>

and also set the permission

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

and in xml folder paths will be

<paths>
    <external-path
        name="external_files"
        path="." />
</paths>

For Oreo, Add permission in AndroidManifast (Otherwise it just silently fails)

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>

now add to you'r 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/provider_paths"/>
</provider>

in xml directory add...

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="." /></paths>

then use these codes where you want.

File directory = Environment.getExternalStoragePublicDirectory("myapp_folder"); 

 File file = new File(directory, "myapp.apk"); // assume refers to "sdcard/myapp_folder/myapp.apk"


    Uri fileUri = Uri.fromFile(file); //for Build.VERSION.SDK_INT <= 24

    if (Build.VERSION.SDK_INT >= 24) {

        fileUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file);
    }
    Intent intent = new Intent(Intent.ACTION_VIEW, fileUri);
    intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true);
    intent.setDataAndType(fileUri, "application/vnd.android.package-archive");
    intent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //dont forget add this line
    context.startActivity(intent);
}

Are there any ways to allow an app to progammatically install an apk with api24?

Add addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) to your promptInstall setup, to grant read access to the content.

I have export=true in my manifest.

Not on your FileProvider, as that would cause your app to crash.

The problem seems to be that packageinstaller cannot use a content:// uri.

No, the problem is that you did not grant permission to the package installer to read from that Uri. Had the package installer been unable to use a content scheme, you would have gotten an ActivityNotFoundException.

Note, though, that it is only with Android 7.0 that the package installer starts supporting content. Earlier versions of Android have to use file.