androidcapkadbraylib

Can't install apk using adb


guys! I want to create a simple HelloWorld apk in C using raylib.

My project structure:

HelloWorld/
    ├── CMakeLists.txt
    ├── src/
    │   ├── main.c
    ├── android/
    │   └── AndroidManifest.xml
    └── build/

src/main.c:

#include <raylib.h>

int main(void) {
    InitWindow(800, 600, "My App");

    while (!WindowShouldClose()) {
        BeginDrawing();
        ClearBackground(RAYWHITE);
        DrawText("Hello, World!", 190, 200, 20, LIGHTGRAY);
        EndDrawing();
    }

    CloseWindow();
}

CMakeLists.txt:

# Minimun version of CMake required to build the project
cmake_minimum_required(VERSION 3.5)

# Define the project name
project(HelloWorld)

# Specify the path of raylib headers
include_directories($ENV{RAYLIB_ANDROID}/include)        

# Compile C code into a shared library
add_library(hello_world SHARED src/main.c)

# Import raylib
add_library(raylib STATIC IMPORTED)

# Specify the path of raylib
set_target_properties(raylib PROPERTIES IMPORTED_LOCATION $ENV{RAYLIB_ANDROID}/lib/arm64/libraylib.a)

# Link with necessary libraries
target_link_libraries(hello_world raylib android log EGL GLESv2)

android/AndroidManifest.txt:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.oussamateyib.helloworld"
    android:versionCode="1"
    android:versionName="1.0.0">

    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="35" />

    <application android:label="Hello World">
        <activity android:name="android.app.NativeActivity"
            android:label="Hello World"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:exported="true">

            <meta-data android:name="android.app.lib_name" android:value="hello_world" />

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

In build/: I run:

cmake -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK_HOME%\build\cmake\android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-35 ..
make

--> libhello_world.so is generated successfully and i copied it to subdirectory lib/arm64-v8a.

Then i run:

aapt package -f -m -F HelloWorld-temp.apk -M ../android/AndroidManifest.xml -I %ANDROID_HOME%/platforms/android-35/android.jar
aapt add HelloWorld-temp.apk lib/arm64-v8a/libhello_world.so

--> apk is packaged successfully

Then i run:

zipalign -v 4 HelloWorld-temp.apk 
HelloWorld.apk

--> apk is aligned successfully

Then i run:

apksigner sign --ks my-key.jks --ks-key-alias HelloWorld HelloWorld.apk

--> apk is signed successfully with my previously generated key.

Then i run (with my phone connected via usb):

adb install HelloWorld.apk

Output:

Performing Incremental Install
Serving...
All files should be loaded. Notifying the device.
Failure [INSTALL_FAILED_INVALID_APK: Scanning Failed.: Package /data/app/~~KjqkABJbYD3SKFrJm_qwcQ==/com.oussamateyib.helloworld-rmQUIQxHLXKSuzm4eo3fuw==/base.apk code is missing]

--> ???

Any idea? Note: my phone abi is indeed arm64-v8a.


Solution

  • Your AndroidManifest.xml is missing an important entry: android:hasCode. For APK files that do not contain DEX code (thus don't have a classes.dex file) you have to set android:hasCode="false" in the <application> tag in AndroidManifest.xml.

    Whether the application contains any DEX code—that is, code using the Kotlin or Java programming language. It's "true" if it does and "false" if not. When the value is "false", the system doesn't try to load any application code when launching components. The default value is "true". If the application includes native (C/C++) code, but no DEX code, this should be set to "false". If set to "true" when the APK contains no DEX code, the app may fail to load.

    https://developer.android.com/guide/topics/manifest/application-element#code