0

I am trying to install programmatically from my downloads folder updates of the application within an AsyncTask.

final String PACKAGE_INSTALLED_ACTION = "com.example.android.apis.content.SESSION_API_PACKAGE_INSTALLED";
        PackageInstaller.Session session = null;
        try {
            PackageInstaller packageInstaller = ContextHolder.getInstance().getContext().getPackageManager().getPackageInstaller();
            PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
                    PackageInstaller.SessionParams.MODE_FULL_INSTALL);
            int sessionId = packageInstaller.createSession(params);
            session = packageInstaller.openSession(sessionId);

            addApkToInstallSession(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/" + fileName,
                    session); // !!! Here it's crashing


            Context context = ContextHolder.getInstance().getContext();
            Intent intent = new Intent(context, Login.class);
            intent.setAction(PACKAGE_INSTALLED_ACTION);
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
            IntentSender statusReceiver = pendingIntent.getIntentSender();
            
            session.commit(statusReceiver);
            session.close();

Here's the addApkToInstallSession function:

private void addApkToInstallSession(String assetName, PackageInstaller.Session session)
        throws IOException {
    
    try (OutputStream packageInSession = session.openWrite("package", 0, -1);
         InputStream is = ContextHolder.getInstance().getContext().getAssets().open(assetName)) {
        byte[] buffer = new byte[16384];
        int n;
        while ((n = is.read(buffer)) >= 0) {
            packageInSession.write(buffer, 0, n);
        }
    }
}

I'm getting this error message even thiugh I checked and this file exists:

java.io.FileNotFoundException: /storage/emulated/0/Download/app-debug-2.apk

Edit 1: It's important to note that I'm currently working with SDK 30

Edit 2: I've noticed I was trying to accest something that didn't exist in the Assets folder, that's the reason it was crashing.

The code of the function addApkToInstallSession() looks now like this - without any errors:

private void addApkToInstallSession(String assetName, PackageInstaller.Session session)
        throws IOException {
    try (OutputStream outputStream = session.openWrite("package", 0, -1);
    InputStream is = new BufferedInputStream(new FileInputStream(assetName))) {
        byte[] buffer = new byte[65536];
        int n;
        while ((n = is.read(buffer)) >= 0) {
            outputStream.write(buffer, 0, n);
        }
    }
}

Now, however, it fails to do anything. It just runs, without crashing, but also without updtating the app...

Edit 3 Parts of the code were copied from: https://android.googlesource.com/platform/development/+/master/samples/ApiDemos/src/com/example/android/apis/content/InstallApkSessionApi.java P.S. I'm pretty new on StackOverflow so don't be too harsh on me ;)

BaconSky
  • 21
  • 5
  • This appears to be a duplicate of your prior question: [How can I install an update on Android without google play? (duplicate)](https://stackoverflow.com/q/67458108/295004) which was closed with a link to an existing answer. Read the linked question, please do some research/learning, if you still have doubts only then ask with specifics about what you do understand and what don't understand/generates an error. – Morrison Chang May 11 '21 at 08:52
  • Not really. That uses deprecated technology. After some research I noticed this is the new way of updating an app – BaconSky May 11 '21 at 09:00
  • Installer apps probably shouldn't be trusting/using the Downloads directory, download the APK to internal storage. [Is it possible to programmatically access Download folder on Android Q (SDK >= 29)?](https://stackoverflow.com/a/60416094/295004) and comments of [I write a file to Environment.DIRECTORY_DOWNLOADS, why can't I see it via the Downloads App?](https://stackoverflow.com/a/20472865/295004) – Morrison Chang May 11 '21 at 09:08
  • `.getContext().getAssets().open(assetName)) ` That makes no sense when assetName equals Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/" + fileName. Look how you call your function. Its no asset but a file. – blackapps May 11 '21 at 10:23
  • `OutputStream packageInSession = ` Whats in a name? Well this is unreadable. Make it `OutputStream outputStream =` or `OutputStream os = ` . – blackapps May 11 '21 at 10:25
  • @blackapps You're completely right. I modified it, but forgot to edit it on stackoverflow too. I'll repair it right away. I mean the `.getContext().getAssets().open(assetName))` part – BaconSky May 11 '21 at 10:25
  • `InputStream is = new FileInputStream(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/" + fileName)){`Dont define that file path again. You did it already calling your function. So `FileInputStream fis = new FileInputStream(assetName)){` ` ` – blackapps May 11 '21 at 10:29
  • `outputStream.close(); ` is missing. – blackapps May 11 '21 at 10:33
  • `InputStream is = new BufferedInputStream` ???? `BufferedInputStream bis = new BufferedInputStream` – blackapps May 11 '21 at 10:34
  • I have to get it somehow from the file, and `getAssets().open(assetName))` wouldn't work, since I am trying to get it from Downloads – BaconSky May 11 '21 at 10:40
  • @BaconSky If you click on log on the link for the `APIDemos/PackageInstaller` code you'll see that the code is 3.5 years old. `APIDemos` was the first "official" sample code provided when Android was released back in 2008/2009. While parts of the code still may be getting updates, I would be hesitant to believe everything there is maintained. For working code see open source store app F-Droid. – Morrison Chang May 11 '21 at 20:07

0 Answers0