Launch APK Installer Oreo

Viewed 2751

I have had this code working for some time now but with Android Orea it doesn't work.

        Context context = mContextRef.get();

        if (context == null) {
            return;
        }

        // Get the update
        String filepath = getDownloadLocation();
        File apkFile = new File(filepath);

        Uri fileLoc;
        Intent intent;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
            fileLoc = android.support.v4.content.FileProvider.getUriForFile(context, mFileProviderAuthority, apkFile);
        } else {
            intent = new Intent(Intent.ACTION_VIEW);
            fileLoc = Uri.fromFile(apkFile);
        }

        intent.setDataAndType(fileLoc, "application/vnd.android.package-archive");
        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);

        context.startActivity(intent);

This code works with all version of android except 8.0 and above.

Edit

Sorry for not explaining more. IT doesn't work meaning, it flashes a window for a fraction of a second and disappears (some times imperceptibly) and continues on in the old app. The file is successfully downloaded (I can navigate to it and install) but when I try to start the activity to install it programmatically it fails with no errors or logs at all.

2 Answers

Apparently if your app targets later versions of android the android.permission.REQUEST_INSTALL_PACKAGES permission is required in the manifest otherwise nothing happens except a single line error in the LogCat.

So include the following in manifest.xml file:

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

Manifest API for REQUEST_INSTALL_PACKAGES

Please add the <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/> permission in Manifest.xml first.

We should check the result of getPackageManager().canRequestPackageInstalls() if the SDK version is equal or large than 26.

The code is below:

private void checkIsAndroidO() {  
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {  
    boolean result = getPackageManager().canRequestPackageInstalls();  
    if (result) {  
      installApk();
    } else {  
      // request the permission 
      ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.REQUEST_INSTALL_PACKAGES}, INSTALL_PACKAGES_REQUESTCODE);  
    }  
  } else {
    installApk();  
  }  
}

@Override  
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {  
  super.onRequestPermissionsResult(requestCode, permissions, grantResults);

  switch (requestCode) {  
    case INSTALL_PACKAGES_REQUESTCODE:  
      if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {  
        installApk();  
      } else {  
        Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);  
        startActivityForResult(intent, GET_UNKNOWN_APP_SOURCES);  
      }  
    break;  
  }  
}

@Override  
protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
  super.onActivityResult(requestCode, resultCode, data); 

  switch (requestCode) {  
    case GET_UNKNOWN_APP_SOURCES:  
      checkIsAndroidO();  
      break;  

    default:  
      break;  
  }  
}

I hope it will help you.

Related