简体   繁体   中英

Can't install apk from uri on Android 10 in Eclipse projects

We are installing apk from file uri, its working upto Android Pie(9),in Android 10 mobile its showing "There was problem while Parsing" . we have stored file in the application storage only and the build version is 4.4

I have shared the code below.

String PATH = Objects.requireNonNull(this.myActivity.getExternalFilesDir(null)).getAbsolutePath();
                 File file = new File(PATH + "/"+Utils.apk_name);
                 intent = new Intent("android.intent.action.VIEW");
                 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                 Uri uri = FileProvider.getUriForFile(this.myActivity, this.myActivity.getApplicationContext().getPackageName() + ".provider", file);
                 //Intrinsics.checkExpressionValueIsNotNull(uri, "FileProvider.getUriForFi…eProvider.install\", file)");
                 intent.setDataAndType(uri, "application/vnd.android.package-archive");
startActivity(intent);

Provider in Manifest

<provider
        android:name="com.kirubha.helpers.ESEProvider"          
        android:authorities="com.kirubha.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 version="1.0" encoding="utf-8"?>
<paths>
<external-path
    name="external_storage_root"
    path="."/>
</paths>

I have found most of my file provider worries disapear when I add

StrictMode.VmPolicy.Builder buildervm = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(buildervm.build());

to my main activities.

The above was found in this answer which might be useful to you.

android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()

In Android 10, ACTION_VIEW is deprecated, need to use PackageInstaller instead.

Follow the below code to implement PackageInstaller in Java.

private static int REQUEST_OEN_DOCUMENT = 1337;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                            Intent intent1 = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                            intent1.setType("application/vnd.android.package-archive");
                            intent1.addCategory(Intent.CATEGORY_OPENABLE);
                            startActivityForResult(intent1, REQUEST_OPEN_DOCUMENT);
                        }

This code will redirect to the files folder. Then need to select the.apk file.

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_OEN_DOCUMENT) {
            if (resultCode == Activity.RESULT_OK) {
                if (data != null) {
                    Uri uri = data.getData();

                   installAfterQ(uri);

                }
            }
        }

    }


public void installAfterQ(Uri uri) {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                InputStream inputStream = getApplication().getContentResolver().openInputStream(uri);

                long length = DocumentFile.fromSingleUri(getApplication(), uri).length();
                PackageInstaller installer = getApplication().getPackageManager().getPackageInstaller();
                PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
                int sessionId = installer.createSession(params);
                PackageInstaller.Session session = installer.openSession(sessionId);

                File file = new File(uri.getPath());
                OutputStream outputStream = session.openWrite(file.getName(), 0, length);

                byte[] buf = new byte[1024];
                int len;
                while ((len = inputStream.read(buf)) > 0) {
                    outputStream.write(buf, 0, (int) len);
                }


                session.fsync(outputStream);

                outputStream.close();
                inputStream.close();

                Intent intent = new Intent(getApplication(), UpdateReceiver.class);
                PendingIntent pi = PendingIntent.getBroadcast(getApplication(), 3439, intent, PendingIntent.FLAG_UPDATE_CURRENT);
                session.commit(pi.getIntentSender());
                session.close();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Update Receiver Class:

public class UpdateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -1);

if (status == PackageInstaller.STATUS_PENDING_USER_ACTION) {
Intent activityIntent =intent.getParcelableExtra(Intent.EXTRA_INTENT);
    context.startActivity(activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
} else if (status == PackageInstaller.STATUS_SUCCESS) {
    Toast.makeText(context, "Successfully Installed", Toast.LENGTH_SHORT).show();
} else {

     String msg =intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE);
    Toast.makeText(context, "Error while installing" + msg, Toast.LENGTH_SHORT).show();

}


    }
}

Android Manifest.xml

Inside Application tag.

<receiver android:name=".UpdateReceiver"/>

        <meta-data
            android:name="com.android.packageinstaller.notification.smallIcon"
            android:resource="@drawable/ic_install_notification" />

Permission:

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

Try this code. Hope this code is helpful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM