Search code examples
androidfileandroid-intentandroid-contentproviderandroid-install-apk

how can open an apk file in a target SDK higher than 24?


I have an application for download apk files. in my application I download an apk file and want to install this apk file after download finished.I test it on my phone with api 19 and it works. but it does not work on nougat version.how can change this code to work truly on nougat and higher version.

its my code for api lower than 24 to install apk:

Intent intent = new Intent(Intent.ACTION_VIEW);
                            intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/icm/" + fileName)), "application/vnd.android.package-archive");
                            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            getActivity().startActivity(intent);

the code that does not work on nougat version and higher:

Intent intent = new Intent(Intent.ACTION_VIEW);
                                intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                                Uri uri = FileProvider.getUriForFile(getContext(), getContext().getApplicationContext().getPackageName() + "clicksite.org.cafebazar.fileprovider", new File(Environment.getExternalStorageDirectory() + "/icm/" + fileName));
                                intent.setDataAndType(uri, "application/pdf");
                                getActivity().startActivity(intent);

android manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="clicksite.org.cafebazar">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <category android:name="android.intent.category.LAUNCHER"/>
            <action android:name="android.intent.action.MAIN"/>
        </intent-filter>
    </activity>
    <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>
</application>

and provider_path.xml that is in xml directory in res folder:

<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>

help me how can change this code to work for nougat version and higher


Solution

  • Problem #1: Wrong Authority

    Uri uri = FileProvider.getUriForFile(getContext(), getContext().getApplicationContext().getPackageName() + "clicksite.org.cafebazar.fileprovider", new File(Environment.getExternalStorageDirectory() + "/icm/" + fileName));
    

    This does not match:

    android:authorities="${applicationId}.provider"
    

    Change the earlier line to:

    Uri uri = FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID + ".provider", new File(Environment.getExternalStorageDirectory(), "icm/" + fileName));
    

    Problem #2: Wrong MIME Type

    intent.setDataAndType(uri, "application/pdf");
    

    APK files are not PDF files. Change this to:

    intent.setDataAndType(uri, "application/vnd.android.package-archive");
    

    There may be more problems than those two, as you did not explain what your symptoms are. However, those definitely need to be fixed. I would also recommend using ACTION_INSTALL_PACKAGE on API Level 14 and higher, rather than ACTION_VIEW.