0

I wonder if you can help, I'm trying to download an apk file as an update after version check. it's downloading the apk but it will not open the apk file its printing an error when trying to open the apk

error :

E/UpdateAPP: Update error! file:///storage/emulated/0/download/update.apk exposed beyond app through Intent.getData()

code :

public class UpdateApp extends AsyncTask<String,Void,Void> {
    private Context context;
    public void setContext(Context contextf){
        context = contextf;
    }

    @Override
    protected Void doInBackground(String... arg0) {
        try {
            URL url = new URL(arg0[0]);
            HttpURLConnection c = (HttpURLConnection) url.openConnection();
            c.setRequestMethod("GET");
            c.setDoOutput(true);
            c.connect();

            String PATH = Environment.getExternalStorageDirectory() + "/download/";
            File file = new File(PATH);
            file.mkdirs();
            File outputFile = new File(file, "update.apk");
            if(outputFile.exists()){
                outputFile.delete();
            }
            FileOutputStream fos = new FileOutputStream(outputFile);

            InputStream is = c.getInputStream();

            byte[] buffer = new byte[1024];
            int len1 = 0;
            while ((len1 = is.read(buffer)) != -1) {
                fos.write(buffer, 0, len1);
            }
            fos.close();
            is.close();

            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" + "/update.apk")), "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // without this flag android returned a intent error!
            context.startActivity(intent);


        } catch (Exception e) {
            Log.e("UpdateAPP", "Update error! " + e.getMessage());
        }
        return null;
    }}

my targetSdkVersion :

targetSdkVersion 27

thanks for the help

Bossa
  • 159
  • 1
  • 1
  • 9
  • Possible duplicate of [android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()](https://stackoverflow.com/questions/38200282/android-os-fileuriexposedexception-file-storage-emulated-0-test-txt-exposed) – EJK Feb 21 '19 at 02:00
  • have you solved this problem? – c-an Jan 15 '20 at 08:01

1 Answers1

3

Since API 26, 'REQUEST_INSTALL_PACKAGES' permission is necessary permission to achieve install apk file.

  1. Make 'file_paths.xml' in res/xml folder to use FileProvider api
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="" path="/" />
</paths>
  1. Declare FileProvider and permission in AndroidManifest.xml

Note. I used Androidx version of FileProvider, if you don't use androidx, make sure android.support.v4.content.FileProvider

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

 <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="{PACKAGE_NAME}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />

</provider>
  1. Get 'Uri' by FileProvider api and request install permission
private fun openFile(file: File) {
        val uri = if (Build.VERSION.SDK_INT >= 24) {
            val authority = packageName + ".fileprovider"
            FileProvider.getUriForFile(this, authority, file)
        } else {
            Uri.fromFile(file)
        }

        val myMime = MimeTypeMap.getSingleton()
        val mimeType = myMime.getMimeTypeFromExtension(file.extension)

        val intent = Intent(Intent.ACTION_VIEW).apply {
            setDataAndType(uri, mimeType)
            flags = Intent.FLAG_ACTIVITY_NEW_TASK
            addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        }

        if (Build.VERSION.SDK_INT >= 26 && !packageManager.canRequestPackageInstalls()) {
            startActivity(
                Intent(
                    Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,
                    Uri.parse("package:$packageName")
                )
            )
        } else {
            intent.action = Intent.ACTION_VIEW
            startActivity(intent)
        }
    }

Edit -> remove specific methods using in my project.

WindSekirun
  • 1,038
  • 11
  • 22