diff --git a/.gitignore b/.gitignore index 0d8de4c..759b7ca 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,8 @@ /Dockerfile +/app/result +/app/result/* +/app/obj +/app/obj/* +/app/bin +/app/bin/* +/app/app.apk diff --git a/app/.Makefile.scripts/make--AppActivity.java.sh b/app/.Makefile.scripts/make--AppActivity.java.sh new file mode 100755 index 0000000..db9663f --- /dev/null +++ b/app/.Makefile.scripts/make--AppActivity.java.sh @@ -0,0 +1,88 @@ +#!/bin/bash + + +test -f app-config.sh && { + source app-config.sh +} + +echo "package $APP_PACKAGE;" + +cat << 'APPACTIVITYJAVA' + +import android.provider.Settings ; +import android.content.Intent; +import android.util.Log; +import android.util.Base64; +import java.util.Objects; +import android.app.Activity; +import android.os.Bundle; +import android.os.CountDownTimer; +import android.os.Environment; +import android.text.method.ScrollingMovementMethod; +import android.view.*; +//import android.view.MenuItem; +import android.view.ViewGroup.*; +import android.widget.*; +//import android.widget.Toast; +//import android.widget.TextView; +import android.webkit.*; +import android.net.Uri; +import org.json.JSONObject; +//import android.webkit.WebView; +//import android.webkit.WebMessage; +//import android.webkit.WebMessagePort; +import java.io.InputStream; +import java.io.File; + + + +public class AppActivity extends Activity { + + private static final String BASE_URI = "https://alexmahr.de"; + public String readFileFromAssets(String filename) { + String filecontents = ""; + try { + InputStream stream = getAssets().open(filename); + int filesize = stream.available(); + byte[] filebuffer = new byte[filesize]; + stream.read(filebuffer); + stream.close(); + filecontents = new String(filebuffer); + } catch (Exception e) { + // I <3 java exceptions + } + return filecontents; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // this removes the title bar (a ~1cm big strip at the top of the app showing its name + this.requestWindowFeature(Window.FEATURE_NO_TITLE); + // we create the webview (at least on the android 14 that is a webview that features avif + websockets etc....) + WebView myWebView = new WebView(this);//activityContext); +// MyJavascriptInterface myJavaScriptInterface = new MyJavascriptInterface(this,myWebView); + // we create a webview (there is also setwebviewclient-vs-setwebchromeclient + WebViewClient myWebViewClient= new WebViewClient(); + myWebView.setWebViewClient(myWebViewClient); + // to setup settings + WebSettings myWebSettings = myWebView.getSettings(); + myWebSettings.setBuiltInZoomControls(true); + myWebSettings.setDisplayZoomControls(false); + myWebSettings.setJavaScriptEnabled(true); + myWebView.addJavascriptInterface(this, "myJavaScriptInterface"); + // load the html from assets file + String html = readFileFromAssets("index.html"); + myWebView.loadDataWithBaseURL(BASE_URI,html, "text/html", "UTF-8",null); + //myWebView.loadData(encodedHtml, "text/html", "base64"); + // alternatively this could be to load a website + //myWebView.loadUrl("https://alexmahr.de/ru"); + setContentView(myWebView); + } + @JavascriptInterface + public String toString() { +// this.webview.evaluateJavascript("(setTimeout(()=>{document.body.innerHTML='all gone';},2000)()",null); + return "this is good"; + } +} +APPACTIVITYJAVA diff --git a/app/.Makefile.scripts/make--app-config.sh b/app/.Makefile.scripts/make--app-config.sh index 7b35f2c..b2915ba 100755 --- a/app/.Makefile.scripts/make--app-config.sh +++ b/app/.Makefile.scripts/make--app-config.sh @@ -54,17 +54,17 @@ done #APP_PACKAGE -while test -z "${APP_PACKAGE:-}" +while test -z "${APP_PACKAGE:-}" do APP_PACKAGE_DEFAULT="${APP_NAME,,}" - APP_PACKAGE_DEFAULT="${APP_PACKAGE_DEFAULT//[!a-z0-9]/_}" + APP_PACKAGE_DEFAULT="app.${APP_PACKAGE_DEFAULT//[!a-z0-9]/_}" APP_PACKAGE="$(READ "Please provide a Package.Name for the App [default=$APP_PACKAGE_DEFAULT]: " 'Create new Android-App step (2/)' )" APP_PACKAGE="${APP_PACKAGE:-$APP_PACKAGE_DEFAULT}" APP_PACKAGE="${APP_PACKAGE,,}" APP_PACKAGE="${APP_PACKAGE//[!a-z0-9\.]/}" - test -d "apps/$APP_PACKAGE" && { - ECHO "There is already an app with APP_PACKAGE '$APP_PACKAGE'. Choose other APP_PACKAGE name" >&2 + grep -qe '_\._' <<< "${APP_PACKAGE//[^.]/_}" || { APP_PACKAGE="" + ECHO "error: package name needs to contain a '.' (dot)" } done diff --git a/app/Makefile b/app/Makefile index 0c18963..b142065 100644 --- a/app/Makefile +++ b/app/Makefile @@ -1,124 +1,73 @@ - - - SHELL=/bin/bash +# symlink +./app.apk: ./result/app.apk + ln -sfrv ./result/app.apk ./app.apk -#shell: -# bash - -app.apk: ./result/app.apk - ln -srv ./result/app.apk ./app.apk - +# zipalign and sign again (second signing) ./result/app.apk : ./result/signed.apk app-config.sh source app-config.sh; $${ANDROID_SDK_ROOT}/$$(tr ';' '/' < android-sdk/.installed.buildtools.version.current)/zipalign -v -f 4 $< $@ source app-config.sh; $${ANDROID_SDK_ROOT}/$$(tr ';' '/' < android-sdk/.installed.buildtools.version.current)/apksigner sign \ --ks ToyKey.keystore --key-pass pass:armena --ks-pass pass:armena $@ +# sign the apk file (first sign) ./result/signed.apk : ./result/unsigned.apk ./ToyKey.keystore ./result jarsigner -verbose -keystore ./ToyKey.keystore -storepass armena -keypass armena -signedjar $@ $< helljniKey -android-sdk/installed: app-config.sh - ./.Makefile.scripts/make--android-sdk.sh - -AndroidManifest.xml: app-config.sh - ./.Makefile.scripts/make--AndroidManifest.xml - -app-config.sh: - ./.Makefile.scripts/make--app-config.sh - - -srcj/package: app-config.sh - source app-config.sh; PKGDIR=$$(echo "$$APP_PACKAGE" | tr '.' '/'); mkdir -p src/$$PKGDIR; ln -srv src/$$PKGDIR $@ - -obj/package: app-config.sh - source app-config.sh; PKGDIR=$$(echo "$$APP_PACKAGE" | tr '.' '/'); mkdir -p obj/$$PKGDIR; ln -srv obj/$$PKGDIR $@ - -./result /bin /assets /src/ obj: - mkdir -p "$@" - +# make a "keystore" for the cryptographic signing stuff ./ToyKey.keystore : keytool -genkeypair -validity 1000 -dname "CN=alexander,O=Android,C=JPN" -keystore $@ \ -storepass armena -keypass armena -alias helljniKey -keyalg RSA -v -./src/package/R.java : $(shell find ./res -type f) app-config.sh src/package - source app-config.sh; $${ANDROID_SDK_ROOT}/$$(tr ';' '/' < android-sdk/.installed.buildtools.version.current)/aapt package \ - -v -f -m -S ./res -J ./src -M ./AndroidManifest.xml \ - -I $${ANDROID_SDK_ROOT}/$$(tr ';' '/' < android-sdk/.installed.platforms.version.current)/android.jar - -./obj/package/AppActivity.class : ./src/package/AppActivity.java ./src/package/R.java obj/package - javac -d ./obj -classpath $${ANDROID_SDK_ROOT}/$$(tr ';' '/' < android-sdk/.installed.platforms.version.current)/android.jar \ - -sourcepath ./src $< - - -./result/signed.apk : ./result/unsigned.apk ./ToyKey.keystore ./result - jarsigner -verbose -keystore ./ToyKey.keystore -storepass armena -keypass armena -signedjar $@ $< helljniKey - - -./result/unsigned.apk : ./bin/classes.dex ./result ./assets +# aapt "package" together the dalvik/hex stuff (and "assets" and "res") +./result/unsigned.apk : ./bin/classes.dex ./result ./assets ./bin ./AndroidManifest.xml rm -rvf "$@" source app-config.sh; $${ANDROID_SDK_ROOT}/$$(tr ';' '/' < android-sdk/.installed.buildtools.version.current)/aapt package \ -v -u -f -M ./AndroidManifest.xml -S ./res \ -I $${ANDROID_SDK_ROOT}/$$(tr ';' '/' < android-sdk/.installed.platforms.version.current)/android.jar -A ./assets -F $@ ./bin - -./bin/classes.dex : ./obj/package/AppActivity.class ./obj/package/AppActivity$$1.class /bin - source app-config.sh; $${ANDROID_SDK_ROOT}/$$(tr ';' '/' < android-sdk/.installed.buildtools.version.current)/d8 ./obj/package/*.class \ - --lib $${ANDROID_SDK_ROOT}/$$(tr ';' '/' < android-sdk/.installed.platforms.version.current)/android.jar --output bin +# convert "java class"es files (i.e bytecode to dalvic/d8 android thing +./bin/classes.dex : ./obj/package ./obj/package/AppActivity.class ./bin + ls ./obj/package/*.class + source app-config.sh; $${ANDROID_SDK_ROOT}/$$(tr ';' '/' < android-sdk/.installed.buildtools.version.current)/d8 $$(realpath --relative-to=. $<)/*.class \ + --lib $${ANDROID_SDK_ROOT}/$$(tr ';' '/' < android-sdk/.installed.platforms.version.current)/android.jar --output bin + +# compile (javac) the class from +./obj/package/AppActivity.class : ./src/package/AppActivity.java ./src/package/R.java ./obj/package + javac -d ./obj -classpath $${ANDROID_SDK_ROOT}/$$(tr ';' '/' < android-sdk/.installed.platforms.version.current)/android.jar \ + -sourcepath ./src $$(realpath --relative-to=/src $<) + +# generate teh AppActivity.java (template) +./src/package/AppActivity.java: ./src/package app-config.sh + ./.Makefile.scripts/make--AppActivity.java.sh > $@ + +# make the resources "R.java" thing +./src/package/R.java : $(shell find ./res -type f) app-config.sh ./src/package ./AndroidManifest.xml + source app-config.sh; $${ANDROID_SDK_ROOT}/$$(tr ';' '/' < android-sdk/.installed.buildtools.version.current)/aapt package \ + -v -f -m -S ./res -J ./src -M ./AndroidManifest.xml \ + -I $${ANDROID_SDK_ROOT}/$$(tr ';' '/' < android-sdk/.installed.platforms.version.current)/android.jar + +# install the necessary android sdks +./android-sdk/installed: app-config.sh + ./.Makefile.scripts/make--android-sdk.sh + +# generate the AndroidManifest.xml +./AndroidManifest.xml: app-config.sh + ./.Makefile.scripts/make--AndroidManifest.xml + +# recipe to make directories (if) needed +./result ./bin ./assets ./src/ ./obj: + mkdir -p "$@" + +# make symlinksa and directories (to cater for the "helpful" java thing, to use folders for package names and yes we need a package name :( ) +./src/package: app-config.sh + set -x; source app-config.sh; PKGDIR=$$(echo "$$APP_PACKAGE" | tr '.' '/'); mkdir -p src/$$PKGDIR; rm -rf $@ ; ln -sfrv src/$$PKGDIR $@ + +./obj/package: app-config.sh + source app-config.sh; PKGDIR=$$(echo "$$APP_PACKAGE" | tr '.' '/'); mkdir -p obj/$$PKGDIR; rm -rf $@; ln -sfrv obj/$$PKGDIR $@ + +app-config.sh: + ./.Makefile.scripts/make--app-config.sh FORCE: @true - -#ANDROID_HOME = /opt/android -#ANDROID_VERSION = 33.0.2 -#PLATFORM = android-$(shell echo $(ANDROID_VERSION) | sed 's/\..*//') -#TOOLCHAIN = /Users/amon/grive/development/Android/NativeToolchain -#GCC = $(TOOLCHAIN)/bin/aarch64-linux-android-gcc -#CXX_FLAGS = -march=armv8-a --sysroot=$(TOOLCHAIN)/sysroot - - - -#all: build -# -#.PHONY : build -#.PHONY : deploy -#.PHONY : clean -# -#build : ./result/example.app.apk -# mv ./result/example.app.apk app.apk -# true -# -#env: -# set > set ; env > env -#./result/example.app.apk : ./result/signed.apk -# $(ANDROID_HOME)/build-tools/$(ANDROID_VERSION)/zipalign -v -f 4 $< $@ -# $(ANDROID_HOME)/build-tools/$(ANDROID_VERSION)/apksigner sign --ks ToyKey.keystore --key-pass pass:armena --ks-pass pass:armena $@ -# -#./result/signed.apk : ./result/unsigned.apk ./ToyKey.keystore ./result -# jarsigner -verbose -keystore ./ToyKey.keystore -storepass armena -keypass armena -signedjar $@ $< helljniKey -# -#./result: -# mkdir -p "$@" -# -#./result/unsigned.apk : ./bin/classes.dex ./result -# rm -rvf "$@" -# $(ANDROID_HOME)/build-tools/$(ANDROID_VERSION)/aapt package -v -u -f -M ./AndroidManifest.xml -S ./res \ -# -I $(ANDROID_HOME)/platforms/$(PLATFORM)/android.jar -A ./assets -F $@ ./bin -# -#./bin/classes.dex : ./obj/app/example/ExampleApp.class ./obj/app/example/ExampleApp$$1.class -# $(ANDROID_HOME)/build-tools/$(ANDROID_VERSION)/d8 ./obj/app/example/*.class --lib $(ANDROID_HOME)/platforms/$(PLATFORM)/android.jar --output bin -# -#./src/app/example/R.java : $(shell find ./res -type f) -# $(ANDROID_HOME)/build-tools/$(ANDROID_VERSION)/aapt package -v -f -m -S ./res -J ./src -M ./AndroidManifest.xml \ -# -I $(ANDROID_HOME)/platforms/$(PLATFORM)/android.jar -# -#./obj/app/example/ExampleApp.class : ./src/app/example/ExampleApp.java ./src/app/example/R.java -# javac -d ./obj -classpath $(ANDROID_HOME)/platforms/$(PLATFORM)/android.jar -sourcepath ./src $< -# -#./ToyKey.keystore : -# keytool -genkeypair -validity 1000 -dname "CN=alexander,O=Android,C=JPN" -keystore $@ \ -# -storepass armena -keypass armena -alias helljniKey -keyalg RSA -v -# -#clean: -# rm -f ./bin/* ./lib/arm64-v8a/* ./result/* -