Error implementing PackageInstallerActivity for some versions of Android 6.0

1

I have the following code that is executed when the user accepts the update of the application within it.

I already provide code for compatibility with versions 6.0 + and versions 6.0 -, the problem arises that some devices accept the code execution that I show below, and some others do not., usually the devices with versions 6.0 - do not cause problems execute correctly, the problem is in the versions 6.0 + that some executions and in some others do not.  -

File fileToUpdate = new File(getExternalFilesDir(null) + File.separator + "nameAppV" + (currentVersionCode + 1) + ".apk");
                    ComponentName comp;
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.setDataAndType(Uri.fromFile(fileToUpdate), "application/vnd.android.package-archive");
                    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                    if (android.os.Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1)
                    {
                        comp = new ComponentName("com.android.packageinstaller", "com.android.packageinstaller.PackageInstallerActivity");
                    }
                    else{
                        comp = new ComponentName("com.google.android.packageinstaller", "com.android.packageinstaller.PackageInstallerActivity");
                    }
                    intent.setComponent(comp);
                    startActivity(intent);

This is the error that throws me when trying the execution.

Summary:

1.- I have implemented the code to perform an installation of the application when there are new updates.

2.- Support for versions 6.0+ and earlier versions is provided.

3.- Previous versions (OS) runs smoothly.

4.- Versions 6.0 + runs in some correctly.

5.- In some versions of 6.0 + the code is not executed and it throws me the error.

SOLVED !!!

Apparently the some versions of android 6.0 still bring the package ( com.android.packageinstaller ) installed, that later send an update to solve this problem because others with the same phone, system, applications already have the updated package ( com.google.android.packageinstaller ) installed.

To check the package they have installed I had to buy a phone from those who were causing problems with code execution, run the following command in the console to verify the package.

Phone, system, applications, etc. Exactly the same, but different package.

INPUT -> adb -s ZY22342FG3 exec-out pm list packages -f install
package:/system/app/CertInstaller/CertInstaller.apk=com.android.certinstaller
package:/system/priv-app/GooglePackageInstaller/GooglePackageInstaller.apk=com.android.packageinstaller


INPUT -> adb -s ZY2233Z2S2 exec-out pm list packages -f install
package:/system/app/CertInstaller/CertInstaller.apk=com.android.certinstaller
package:/system/priv-app/GooglePackageInstaller/GooglePackageInstaller.apk=com.google.android.packageinstaller

Method to verify if the package exists on the mobile device

public boolean isPackageExisted(String targetPackage){
        List<ApplicationInfo> packages;
        PackageManager pm;

        pm = getPackageManager();
        packages = pm.getInstalledApplications(0);
        for (ApplicationInfo packageInfo : packages)
        {
            if(packageInfo.packageName.equals(targetPackage))
                return true;
        }
        return false;
    }

Final code:

            Intent intent = new Intent(Intent.ACTION_VIEW);

            File fileToUpdate = new File(getExternalFilesDir(null) + File.separator + "lecturasV" + (currentVersionCode + 1) + ".apk");
            ComponentName comp;
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            //Soporte para 5.1 -
            if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1 || isPackageExisted("com.android.packageinstaller"))
            {
                Log.e("VERSION: ", "OPT 1 "+ Build.VERSION.SDK_INT);
                intent.setDataAndType(Uri.fromFile(fileToUpdate), "application/vnd.android.package-archive");
                comp = new ComponentName("com.android.packageinstaller", "com.android.packageinstaller.PackageInstallerActivity");
            }
            //Soporte para 6.0+
            else
            {
                //Soporte para 7.0 +
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
                {
                    Uri uriToUpdate = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", fileToUpdate);
                    intent.setDataAndType(uriToUpdate, "application/vnd.android.package-archive");
                }else{
                //Soporte para 7.0 -
                    intent.setDataAndType(Uri.fromFile(fileToUpdate), "application/vnd.android.package-archive");
                }
                Log.e("VERSION: ", "OPT 2 "+ Build.VERSION.SDK_INT);
                comp = new ComponentName("com.google.android.packageinstaller", "com.android.packageinstaller.PackageInstallerActivity");
            }
            intent.setComponent(comp);
            startActivity(intent);
    
asked by Desarrollador Android Jr. 09.10.2017 в 19:39
source

1 answer

0

You do not need the Flags that you define to require permissions, if it is greater than or equal to 6.0 you must manually require them:

One of the permissions that are required for Android 6.0 is WRITE_EXTERNAL_STORAGE (which is also implicitly READ_EXTERNAL_STORAGE :

You can request permission before trying to read the external storage, call this method:

private void checkExternalStoragePermission() {
    int permissionCheck = ContextCompat.checkSelfPermission(
            this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
        Log.i("Mensaje", "No se tiene permiso para leer.");
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 225);
    } else {
        Log.i("Mensaje", "Se tiene permiso para leer!");
    }
}

You can validate calling the method only operating systems greater than or equal to Android 6.0:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
    //Verifica permisos para Android 6.0+
     checkExternalStoragePermission();
}

Android 6 the packageName change to com.android.packageinstaller , therefore it would be this way, when it is less than 23 (Android M) it uses the previous method:

File fileToUpdate = new File(getExternalFilesDir(null) + File.separator + "nameAppV" + (currentVersionCode + 1) + ".apk");

    ComponentName comp;
    Intent intent = new Intent(Intent.ACTION_VIEW); 
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
    intent.setDataAndType(Uri.fromFile(fileToUpdate), "application/vnd.android.package-archive");  

    if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1/*23*/){
     comp = new ComponentName("com.android.packageinstaller", "com.android.packageinstaller.PackageInstallerActivity");
    }else{
     comp = new ComponentName("com.google.android.packageinstaller", "com.android.packageinstaller.PackageInstallerActivity");
    }

    intent.setComponent(comp);
    startActivity(intent);
    
answered by 09.10.2017 в 20:13