Hi.
In order to integrate the project with native code, I made a few changes to the configuration files. Currently, the native code executes correctly but there were problems with displaying application elements such as text, background, etc.
The native code at application startup calls a "toast" with "Hello from JNI";
The expected look of the application:
Current:
In the Embedded Wizard project itself, I have the library declared inline:
I have created 2 files MainActivity.java and native-lib.c:
native-lib.c ( C:\Android\Application\Project\app\src\main\cpp\native-lib.c):
#include <jni.h>
#include <stdio.h>
#include <string.h>
JNIEXPORT jstring JNICALL
Java_com_example_myapplication_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
const char* hello = "Hello from JNI";
return (*env)->NewStringUTF(env, hello);
}
MainActivity.java (C:\Android\Application\Project\app\src\main\java\com\example\myapplication\MainActivity.java):
package com.example.myapplication;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends Activity {
// Load the native library
static {
System.loadLibrary("myapplication");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Call the native method to get the string from JNI
String messageFromJNI = stringFromJNI();
// Display the string as a Toast
Toast.makeText(this, messageFromJNI, Toast.LENGTH_SHORT).show();
// Finish the activity
}
// Declare the native method
public native String stringFromJNI();
}
And I have modified the following config file:
build.gradle (C:\Android\Application\Project\build.gradle):
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.0'
}
}
allprojects {
repositories {
jcenter()
google()
}
tasks.withType(JavaCompile) {
options.compilerArgs << '-Xlint:-options'
}
}
task appStart(type: Exec, dependsOn: ':app:installDebug') {
// windows
commandLine 'cmd', '/c', 'adb', 'uninstall', 'com.example.myapplication.'
commandLine 'cmd', '/c', 'adb', 'shell', 'am', 'start', '-n', 'com.example.myapplication.MainActivity'
}
task clean(type: Delete) {
delete rootProject.buildDir
delete "app/.externalNativeBuild"
}
build.gradle (C:\Android\Application\Project\app\build.gradle):
apply plugin: 'com.android.application'
android {
compileSdkVersion = 33
defaultConfig {
applicationId = 'com.example.myapplication'
minSdkVersion 33
targetSdkVersion 33
versionCode 1
versionName "1.0"
externalNativeBuild {
cmake {
arguments '-DANDROID_STL=c++_static'
}
}
sourceSets {
main {
java {
// srcDirs 'src/main/java/com/example/myapplication'
}
}
}
ndk {
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path '../../Source/CMakeLists.txt'
}
}
buildFeatures {
viewBinding true
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:25.4.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
}
CmakeList ( C:\Android\Application\Source):
# Copyright (C) The Android Open Source Project
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required(VERSION 3.4.1)
project("myapplication")
# Dodaj ścieżkę do plików źródłowych C++
set(SOURCE_FILES C:/Android/Application/Project/app/src/main/cpp/native-lib.c)
# Dodaj bibliotekę C++
add_library(myapplication SHARED ${SOURCE_FILES})
# Znajdź i dodaj bibliotekę log
find_library(log-lib log)
# Powiąż bibliotekę log z naszą biblioteką C++
target_link_libraries(myapplication ${log-lib})
get_filename_component(ABSOLUTE_PATH ../GeneratedCode/ewfiles.cmake ABSOLUTE)
if(NOT EXISTS ${ABSOLUTE_PATH})
message(FATAL_ERROR "\n\n>>> Please open Embedded Wizard project and generate code first <<<\n")
endif()
# defines
add_definitions(
-DEW_USE_OPERATING_SYSTEM=1
)
# OpenGL zooming
add_definitions(
-DEW_BORDER_AROUND_GLYPHS=1
)
# 64-bit
message( STATUS "Architecture: ${ANDROID_ABI}" )
if ("$ENV{EVALUATION}" STREQUAL "arm64-v8a")
add_definitions(-D__LP64__)
endif()
if ("$ENV{EVALUATION}" STREQUAL "x86_64")
add_definitions(-D__LP64__)
endif()
...
AndroidManifest (C:\Android\Application\Project\app\src\main):
<?xml version="1.0" encoding="utf-8"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication"
android:versionCode="1"
android:versionName="1.0">
<!-- Request legacy Bluetooth permissions on older devices. -->
<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<!-- Needed only if your app looks for Bluetooth devices.
If your app doesn't use Bluetooth scan results to derive physical
location information, you can strongly assert that your app
doesn't derive physical location. -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<!-- Needed only if your app makes the device discoverable to Bluetooth
devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<!-- Needed only if your app communicates with already-paired Bluetooth
devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- Needed only if your app uses Bluetooth scan results to derive physical location. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Wymagany vluetooth Classic-->
<uses-feature android:name="android.hardware.bluetooth" android:required="true"/>
<!-- Wymagany vluetooth LE-->
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
<!-- This .apk has no Java code itself, so set hasCode to false. -->
<application
android:allowBackup="false"
android:fullBackupContent="false"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:hasCode="true">
<!-- Our activity is the built-in NativeActivity framework class.
This will take care of integrating with our NDK code. -->
<!-- android:name="android.app.NativeActivity" -->
<activity android:name="com.example.myapplication.MainActivity"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:label="@string/app_name"
android:keepScreenOn="true"
android:launchMode="singleTask"
android:configChanges="keyboardHidden|orientation"
android:screenOrientation="landscape"
android:exported="true">
<!-- Tell NativeActivity the name of our .so -->
<meta-data android:name="android.app.lib_name"
android:value="embedded_wizard_activity" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-feature android:glEsVersion="0x00020000"/>
</manifest>
<!-- END_INCLUDE(manifest) -->
I noticed that the display error is caused by changing: package="de.embedded_wizard.embedded_wizard_activity" and android:name="android.app.NativeActivity" in the Manifest file.
If there was a possibility, I would ask for advice or help in solving the problem.
Android: https://we.tl/t-SEZaOYLbfQ
Project: https://we.tl/t-cXwR4LnH11
Best regards,
Kyo.