Search code examples
androidgradleapkadb

"App not installed" error when trying to install signed APK on Android device


How can I troubleshoot the "App not installed" error when trying to install a generated signed APK on my mobile device?

I have already attempted the following solutions but no luck:

  • added android:testOnly="false" to the manifest file

  • added android.injected.testOnly=false to gradle.properties

  • make sure the main activity has the value android:exported="true"

  • changed to the release build variant and generated the APK

  • used "Build Bundle(s) / APK(s) > Build APK(s)" to generate the APK

  • set isMinifyEnabled = false and isShrinkResources = false

  • cleaned and rebuilt the project

  • enabled multiDexEnabled

  • used jarsigner to sign the APK

  • used a new signature to sign the APK

  • uninstalled the current app

  • cleared data of the package installer

  • disabled Play Protect

  • removed the proguardFiles path in build.gradle

  • used adb install apk, but received the error message

adb: failed to install C:\...\app-release.apk: Failure [INSTALL_FAILED_TEST_ONLY: installPackageLI]


This is my current app build.gradle

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.util.*

plugins {
    id("com.android.application")
    kotlin("android")
    id("kotlin-parcelize")
    kotlin("kapt")
    id("dagger.hilt.android.plugin")
    id("com.google.gms.google-services")
    id("com.google.firebase.crashlytics")
    id("com.google.firebase.firebase-perf")
}

android {
    compileSdk = 33
    compileSdkPreview = "UpsideDownCake"

    packagingOptions {
        resources.excludes.add("META-INF/versions/9/previous-compilation-data.bin")
    }

    defaultConfig {
        multiDexEnabled = true
        applicationId = ...
        minSdk = 21
        targetSdk = 33
        versionCode = 200000
        versionName = 2.0.0
        testInstrumentationRunner =
            "androidx.test.runner.AndroidJUnitRunner"
        javaCompileOptions.annotationProcessorOptions.arguments += mapOf(
            "room.schemaLocation" to "$projectDir/schemas"
        )
    }
    sourceSets {
        map { it.java.srcDir("src/${it.name}/kotlin") }
    }
    signingConfigs {
        create("release") {
            val keystorePropertiesFile = rootProject.file("keystore.properties")
            val keystoreProperties = Properties().apply {
                load(keystorePropertiesFile.reader())
            }
            val storeFilePath = keystoreProperties["storeFile"] as String
            val storePassword = keystoreProperties["storePassword"] as String
            val keyAlias = keystoreProperties["keyAlias"] as String
            val keyPassword = keystoreProperties["keyPassword"] as String
            this.storeFile = file(storeFilePath)
            this.storePassword = storePassword
            this.keyAlias = keyAlias
            this.keyPassword = keyPassword
        }
    }
    buildTypes {
        getByName("debug") {
            isMinifyEnabled = false
            isShrinkResources = false
            isDebuggable = true
            applicationIdSuffix = ".debug"
            versionNameSuffix = "-DEBUG"
            signingConfig = signingConfigs.getByName("debug")
        }
        getByName("release") {
            isMinifyEnabled = false
            isShrinkResources = false
            signingConfig = signingConfigs.getByName("release")
        }
    }

    compileOptions {
        targetCompatibility = JavaVersion.VERSION_11
        sourceCompatibility = JavaVersion.VERSION_11
    }
    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_11.toString()
    }
    packagingOptions {
        resources {
            excludes += setOf(
                "DebugProbesKt.bin",
                "META-INF/rxjava.properties",
                "META-INF/proguard/androidx-annotations.pro"
            )
        }
    }
    //testOptions.unitTests.returnDefaultValues = true
    lint {
        abortOnError = false
    }
    namespace = ...
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_11.toString()
        freeCompilerArgs = freeCompilerArgs + listOf("-XXLanguage:+InlineClasses")
    }
}

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.10")
    implementation("androidx.core:core-ktx:1.12.0-alpha01")
    implementation("androidx.multidex:multidex:2.0.1")
    implementation("androidx.fragment:fragment-ktx:1.5.6")
    implementation("androidx.paging:paging-runtime-ktx:3.2.0-alpha04")
    implementation("androidx.paging:paging-rxjava3:3.2.0-alpha04")
    implementation("androidx.datastore:datastore-preferences:1.1.0-alpha01")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.0-Beta")
    //dependency injection
    implementation("com.google.dagger:hilt-android:2.45")
    kapt("com.google.dagger:hilt-android-compiler:2.45")
    kapt("androidx.hilt:hilt-compiler:1.0.0")
    implementation("javax.inject:javax.inject:1")
    //network
    implementation("com.squareup.retrofit2:retrofit:2.9.0")
    implementation("com.squareup.retrofit2:adapter-rxjava3:2.9.0")
    implementation("com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.11")
    //other
    implementation("com.jakewharton.timber:timber:5.0.1")
    implementation("com.google.android.material:material:1.9.0-beta01")
    debugImplementation("com.squareup.leakcanary:leakcanary-android:2.10")
    debugImplementation("com.github.chuckerteam.chucker:library:3.5.2")
    releaseImplementation("com.github.chuckerteam.chucker:library-no-op:3.5.2")
    //test
    testImplementation("junit:junit:4.13.2")
    androidTestImplementation("androidx.test:runner:1.5.2")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
    //firebase bom
    implementation(platform("com.google.firebase:firebase-bom:31.2.3"))
    //crashlytics
    implementation("com.google.firebase:firebase-crashlytics-ktx")
    implementation("com.google.firebase:firebase-analytics-ktx")
    //performance
    implementation("com.google.firebase:firebase-perf-ktx")

    implementation(project(":presentation"))
    implementation(project(":data"))
    implementation(project(":domain"))
}

Manifest file:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

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

    <application
        android:name="...MainApplication"
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        android:testOnly="false"
        tools:targetApi="n">

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

        <activity
            android:name="...main.MainActivity"
            android:exported="true"
            android:screenOrientation="nosensor">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>


    </application>

</manifest>

Solution

  • I was able to resolve the issue by removing the line

    compileSdkPreview = "UpsideDownCake"

    from my build.gradle file. It seems that this line sets android:testOnly to true whenever the project is built, which was causing the problem.