solrudev / Ackpine

Android package installer library
https://solrudev.github.io/Ackpine/
Apache License 2.0
51 stars 7 forks source link

Can't make it to work #66

Open rynkowsg opened 2 weeks ago

rynkowsg commented 2 weeks ago

I tried to use Ackpine but I can't make it to work. This is pretty much what I try to run:

    val pm = ru.solrudev.ackpine.installer.PackageInstaller.getInstance(ctx)
    val session = pm.createSession(apkFileUri) {
        installerType = InstallerType.SESSION_BASED
        confirmation = Confirmation.DEFERRED
    }
    @Suppress("OPT_IN_USAGE")
    session.progress
        .onEach { progress -> println("Got session's progress: $progress") }
        .launchIn(GlobalScope)

    try {
        when (val result = session.await()) {
            is SessionResult.Success -> Timber.d("Success")
            is SessionResult.Error -> Timber.e(result.cause.message)
        }
    } catch (e: CancellationException) {
        Timber.e(e, "Cancelled")
    } catch (exception: Exception) {
        Timber.e(exception)
    }

I get in logs:

                         I  Got session's progress: Progress(progress=72, max=100)                                                                                                           
                         I  Got session's progress: Progress(progress=74, max=100)    
                         I  Got session's progress: Progress(progress=76, max=100)                                                                                                           
                         I  Got session's progress: Progress(progress=77, max=100)
                         I  Got session's progress: Progress(progress=79, max=100)                                                                                                           
       WM-WorkerWrapper  I  Work [ id=9f6f5e75-4213-4db7-b122-2c0259dc6719, tags={ green.chargedup.feature.node.work.AllInWorker } ] was cancelled                                           
                         I  java.util.concurrent.CancellationException: Task was cancelled.                                                                                                  
                         I      at androidx.work.impl.utils.futures.AbstractFuture.cancellationExceptionWithCause(AbstractFuture.java:1183)                                                  
                         I      at androidx.work.impl.utils.futures.AbstractFuture.getDoneValue(AbstractFuture.java:513)                                                                     
                         I      at androidx.work.impl.utils.futures.AbstractFuture.get(AbstractFuture.java:474)                                                                              
                         I      at androidx.work.impl.WorkerWrapper$2.run(WorkerWrapper.java:316)                                                                                            
                         I      at androidx.work.impl.utils.SerialExecutorImpl$Task.run(SerialExecutorImpl.java:96)                                                                          
                         I      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)                                                                           
                         I      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)                                                                           
                         I      at java.lang.Thread.run(Thread.java:1012)                                                                                                                    
          AllInWorkerKt  E  Cancelled                                                                                                                                                        
                         E  kotlinx.coroutines.JobCancellationException: Job was cancelled; job=JobImpl{Cancelling}@5ba316a

Some other time just gets stuck on 79% and stay there.

If I use same apkFileUri and use Android PackageInstaller and I commit session directly works with no issue.

I tested both solutions, with Ackpine and without on Android 13 as a normal app, and on Android 7 as a system app. In both cases, Ackpine got stuck and simple session based solution works.

I'm using v0.6.1.

Any advice?

solrudev commented 2 weeks ago

@rynkowsg Where do you call session.await()? It will cancel the session when the coroutine scope it was launched in is cancelled. It may be that you're calling await() in a coroutine scope with short lifecycle.

eriknyk commented 1 week ago

it doesn't work for me neither.

I have a function like follows:

private fun installAPK(apkFile: File) = lifecycleScope.launch(Dispatchers.IO) {
        val packageInstaller = PackageInstaller.getInstance(this@AppReleaseActivity)
        val packageUninstaller = PackageUninstaller.getInstance(this@AppReleaseActivity)
        val apkUri = uriFromFile(applicationContext, apkFile)

        try {
            val session = packageInstaller.createSession(InstallParameters
                .Builder(apkUri)
                .setName("release-app.apk")
                .setRequireUserAction(true)
                .build()
            )

            session.progress
                .onEach { progress -> {
                    Timber.d("PROG" + session.id +" - "+ progress)
                }}
                .launchIn(this)

            when (session.await()) {
                is SessionResult.Success -> {
                    println("Success")
                }
                is SessionResult.Error -> {
                    println(result.cause.message)
                }
            }
        } catch (_: CancellationException) {
            println("Cancelled")
        } catch (exception: Exception) {
            println(exception)
        }
}

But it does nothing, any log in logcat, and any action even if I set .setRequireUserAction(true), debugging the app, it never enters into when() { ... sentence, and not throwing eny exception type also :(

Any help will be appreciate it.

solrudev commented 6 days ago

@eriknyk Are you sure that your lifecycleScope isn't cancelled in the meantime?

eriknyk commented 6 days ago

@solrudev it is tied to the currect activity lifecycleScope, and the activity is active & visible, so the scope wan't cancelled. any thoughts?

solrudev commented 6 days ago

@eriknyk Please, provide a minimal reproducible example. It's important to see a broader picture of how the library is used, because there's no problem in your code snippet.

eriknyk commented 4 days ago

@solrudev here you go -> https://github.com/eriknyk/demoinstallapk if you uncomment line :74 (https://github.com/eriknyk/demoinstallapk/blob/main/app/src/main/java/com/github/eriknyk/demoinstallapk/MainActivity.kt#L74) and comment line :73, you will se that installAPK_Other() forks fine and install the apk as expected, and the installAPK() doesn't work using Ackpine

Regards.

solrudev commented 3 days ago

@eriknyk The problem in your sample is that you're using DEFERRED session confirmation and don't allow notifications to be posted.

In your AndroidManifest.xml you've disabled AckpineInitializer which creates a notification channel for (un)install confirmation notifications. Also you didn't request POST_NOTIFICATIONS permission. If you change confirmation to IMMEDIATE while creating the session, or if you fix the things mentioned, Ackpine will work.

eriknyk commented 3 days ago

it worked with the changes thank you! (136aca9) I just have a last questions, not sure what is supposed .setRequireUserAction(true/false) should to do? I've tried setting it true and false on both cases the confirm dialog to install the app is displayed.

solrudev commented 3 days ago

@eriknyk

what is supposed .setRequireUserAction(true/false) should to do?

It configures the PackageInstaller.SessionParams#setRequireUserAction() parameter. Also it's mentioned in library's docs.

solrudev commented 20 hours ago

@rynkowsg Have you solved the issue with stuck sessions? Maybe some comments in this thread were helpful?