• Stars
    star
    2,674
  • Rank 16,679 (Top 0.4 %)
  • Language
    C
  • License
    MIT License
  • Created over 4 years ago
  • Updated about 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Build android apps without any java, entirely in C and Make

rawdrawandroid

Update: Works with OpenXR on Meta Quest!

rawdrawandroid

Ever wanted to write C code and run it on Android? Sick of multi-megabyte packages just to do the most basic of things. Well, this is a demo of how to make your own APKs and build, install and automatically run them in about 2 seconds, and with an apk size of about 25kB (with API 26). API 30 (Android R+) is unfortunately at 45kB to support ARM64 + ARM32.

With this framework you get a demo which has:

  • To make a window with OpenGL ES support
  • Accelerometer/gyro input, multi-touch
  • An android keyboard for key input
  • Ability to store asset files in your APK and read them with AAssetManager
  • Permissions support for using things like sound. Example in https://github.com/cnlohr/cnfa
  • Directly access USB devices. Example in https://github.com/cnlohr/androidusbtest

Youtube Video

DISCLAIMER: I take no warranty or responsibility for this code. Use at your own risk. I've never released an app on the app store, so there may be some fundamental issue with using this toolset to make commercial apps!

For support, you can try chatting with folks on my discord: https://discord.com/invite/CCeyWyZ

Why?

Because sometimes you want to do things that don't fit into the normal way of doing it and all the discussions online revolve around doing it with all the normal processes. And those processes change, making it difficult to keep up and do specific things. By using Makefiles it's easy to see what exact commands are executed and add custom rules and tweak your build. C is a universal language. Rawdraw operates on everything from an ESP8266, to RaspberryPi, Windows Linux and now, even Android. Write code once, use it everywhere.

When you don't fill your build process with hills of beans, you end up being left with the parts that are important, and not the frivilous parts. This makes it easier to develop, deploy, etc, because everything takes much less time.

A little bit of this also has to do to stick it to all those Luddites on the internet who post "that's impossible" or "you're doing it wrong" to Stack Overflow questions... Requesting permissions in the JNI "oh you have to do that in Java" or other dumb stuff like that. I am completely uninterested in your opinions of what is or is not possible. This is computer science. There aren't restrictions. I can do anything I want. It's just bits. You don't own me.

P.S. If you want a bunch of examples of how to do a ton of things in C on Android that you "need" java for, scroll to the bottom of this file: https://github.com/cntools/rawdraw/blob/master/CNFGEGLDriver.c - it shows how to use the JNI to marshall a ton of stuff to/from the Android API without needing to jump back into Java/Kotlin land.

Development Environment

Most of the testing was done on Linux, however @AEFeinstein has done at least cursory testing in Windows. You still need some components of Android studio set up to use this, so it's generally easier to just install Android studio completely, but there are instructions on sort of how to do it piecemeal for Windows.

Linux install Android Studio with NDK.

This set of steps describes how to install Android Studio with NDK support in Linux. It uses the graphical installer and installs a lot more stuff than the instructions below. You may be able to mix-and-match these two sets of instructions. For instance if you are on Linux but don't want to sacrifice 6 GB of disk to the Googs.

NOTE You probably should use the WSL instructions instead of these instructions as it will produc a more lean installation.

  1. Install prerequisites:
sudo apt install openjdk-11-jdk-headless adb
  1. Download Android Studio: https://developer.android.com/studio
  2. Start 'studio.sh' in android-studio/bin
  3. Let it install the SDK.
  4. Go to sdkmanager ("Configure" button in bottom right)
  5. Probably want to use Android 24, so select that from the list.
  6. Select "SDK Tools" -> "NDK (Side-by-side)"
  7. Download this repo
git clone https://github.com/cnlohr/rawdrawandroid --recurse-submodules
cd rawdrawandroid
  1. Turn on developer mode on your phone (will vary depending on android version)
  2. Make your own key
make keystore
  1. Go into developer options on your phone and enable "USB debugging" make sure to select always allow.
  2. Plug your phone into the computer.
  3. Run your program.
make push run

Steps for GUI-less install (Windows, WSL)

If you're developing in Windows Subsystem for Linux (WSL), follow the "Steps for GUI-less install" to install the Android components from the command line, without any GUI components.

Extra note for actually deploying to device in Windows

In order to push the APK to your phone, you need adb installed in Windows as well. You can do that by getting the full Android Studio from https://developer.android.com/studio#downloads or directly https://dl.google.com/android/repository/platform-tools_r24.0.4-windows.zip. Installing the full Android Studio is easier, but you can also get the "Command line tools only" and install adb from there. The steps below outline how to do this with the direct link.

Rest of steps

  1. Install Windows Subsystem for Linux (WSL). You can find instructions here: https://docs.microsoft.com/en-us/windows/wsl/install-win10 - we use "Ubuntu" for this.

  2. Install prerequisites:

sudo apt install openjdk-11-jdk-headless adb unzip zip
  1. Download "Command line tools only": https://developer.android.com/studio#downloads - you can get a URL and use wget in WSL to download the tools by clicking on the "Linux" toolset, then right-clicking on the accept link and saying copy link to location. Then you can say wget <link> in WSL.
  2. Create a folder for the Android SDK and export it. You may want to add that export to your ~/.bashrc:
mkdir ~/android-sdk
export ANDROID_HOME=~/android-sdk
printf "\nexport ANDROID_HOME=~/android-sdk\n" >> ~/.bashrc
  1. Unzip the "Command line tools only" file so that tools is in your brand new android-sdk folder.
  2. Install the SDK and NDK components:

For earler versions of tools see note for pre-SDK-32-Tools.

If your platform command-line tools are 30, the command-line tools will be placed in the cmdline-tools folder. So, you will need to execute the following:

yes | $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_HOME} --licenses
$ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_HOME} "build-tools;30.0.2" "cmake;3.10.2.4988404" "ndk;21.3.6528147" "patcher;v4" "platform-tools" "platforms;android-30" "tools"

NOTE If you are upgrading NDK versions, you may need to remove old versions, this Makefile does not necessarily do the best job at auto-selecting NDK versions.

You can see all avialable versions of software with this command:

$ANDROID_HOME/cmdline-tools/bin/sdkmanager --list --sdk_root=${ANDROID_HOME}
  1. Install the Windows ADB toolset.
mkdir -p $ANDROID_HOME/windows
cd $ANDROID_HOME/windows
wget https://dl.google.com/android/repository/platform-tools_r24.0.4-windows.zip
unzip platform-tools_r24.0.4-windows.zip
export ADB=$ANDROID_HOME/windows/platform-tools/adb.exe
printf "\nexport ADB=$ANDROID_HOME/windows/platform-tools/adb.exe\n" >> ~/.bashrc

Alternatively, you may want to use https://dl.google.com/android/repository/platform-tools_r30.0.5-windows.zip for r30.

  1. NOTE: because of updates to environment variables, you may want to close and re-open your WSL terminal.
  2. Download this repo
git clone https://github.com/cnlohr/rawdrawandroid --recurse-submodules
cd rawdrawandroid
  1. Turn on developer mode on your phone (will vary depending on android version)
  2. Go into developer options on your phone and enable "USB debugging" make sure to select always allow.
  3. Plug your phone into the computer.
  4. Make your keystore.
make keystore
  1. Compile and run your program.
make run

If you are going to use this

  • Check out the example here: https://github.com/cnlohr/rawdrawandroidexample

  • You may want to copy-and-paste this project, but, you could probably use it as a submodule. You may also want to copy-and-paste the submodule.

  • You MUST override the app name.

    • See in Makefile APPNAME and PACKAGENAME you should be able to include this project's makefile and override that.
    • You must also update AndroidManifest.xml with whatever name and org you plan to use.
    • You will need to update: package in <manifest> to be your PACKAGENAME variable in Makefile.
    • Both android:label labels need to reflect your new app name. They are in your <application> and <activity> sections.
    • Update the android:value field in android.app.lib_name
  • If you are using permission you have to prompt for, you must both add it to your AndroidManifest.xml as well as check if you have it, and if not, prompt the user. See helper functions below. You can see an example of this with sound_android.c from ColorChord. https://github.com/cnlohr/colorchord/blob/master/colorchord2/sound_android.c

  • Be sure to uninstall any previously installed apps which would look like this app, if you have a different build by the same name signed with another key, bad things will happen.

  • You can see your log with:

adb logcat
  • If your app opens and closes instantly, try seeing if there are any missing symbols:
adb logcat | grep UnsatisfiedLinkError

Helper functions

Because we are doing this entirelly in the NDK, with the JNI, we won't have the luxury of writing any Java/Kotlin code and calling it. That means all of the examples online have to be heavily marshalled. In rawdraw's EGL driver, we have many examples of how to do that. That said, you can use the following functions which get you most of the way there.

struct android_app * gapp;

int AndroidHasPermissions(const char* perm_name);

void AndroidRequestAppPermissions(const char * perm);

void AndroidDisplayKeyboard(int pShow);

int AndroidGetUnicodeChar( int keyCode, int metaState );

int android_width, android_height;

extern int android_sdk_version; //Derived at start from property ro.build.version.sdk

Departures from regular rawdraw.

Also, above and beyond rawdraw, you must implement the following two functions to handle when your apps is suspended or resumed.

void HandleResume(); void HandleSuspend();

In addition to that, the syntax of HandleMotion(...) is different, in that instead of the mask variable being a mask, it is simply updating that specific pointer.

Google Play

As it turns out, Google somehow lets apps built with this onto the store. Like ColorChord https://github.com/cnlohr/colorchord.

Part 0: Changes to your app.

  1. Make sure you are using the newest SDK.
  2. You will need to add a versionCode to your AndroidManifest.xml. In your AndroidManifest.xml, add android:versionCode="integer" to the tag where "integer" is a version number.
  3. In your AndroidManifest.xml, change android:debuggable to false.
  4. You may want to support multiple platforms natively. Add the following to your Makefile: TARGETS:=makecapk/lib/arm64-v8a/lib$(APPNAME).so makecapk/lib/armeabi-v7a/lib$(APPNAME).so makecapk/lib/x86/lib$(APPNAME).so makecapk/lib/x86_64/lib$(APPNAME).so
  5. You will need to specify target and Min SDK in your AndroidManifest.xml See: <uses-sdk android:minSdkVersion="22" android:targetSdkVersion="28" />
  6. Those target / min versions must match your Makefile. Note that without a minSdkVerson google will wrongfully assume 1. This is dangerous. Be sure to test your app on a device with whichever minSdkVersion you've specified.
  7. You will need to disable the debuggable flag in your app. See <application android:debuggable="false" ...>

Get a google play account. Details surrounding app creation are outside the scope of this readme. When getting ready to upload your APK.

Keys: You will want a key for yourself that's a real key. Not the fake one.

First you will need to make a real key. This can be accomplished by deleting our fake key my-release-key.keystore and executing the following command (being careful to fill #### in with real info):

make keystore STOREPASS=#### DNAME="\"CN=####, OU=ID, O=####, L=####, S=####, C=####\"" ALIASNAME=####

The alias name will be standkey. You will want to verify you can build your app with this key. Be sure to fill in STOREPASS the same.

make clean run STOREPASS=####

Let Google create and manage my app signing key (recommended)

Export and upload a key and certificate from a Java keystore

If you want to use the play store key with "Export and upload a key and certificate from a Java keystore" Instead of Let Google create and manage my app signing key (recommended) and follow PEKP instructions.

Prepping your app for upload.

You MUST have aligned ZIPs for the Play store. You must run the following command:

zipalign -c -v 8 makecapk.apk

Upload your APK makecapk.apk made with your key.

Pre-SDK-32-Tools

If you are using Android 29 or older, do this.

yes | $ANDROID_HOME/tools/bin/sdkmanager --sdk_root=${ANDROID_HOME} --licenses
$ANDROID_HOME/tools/bin/sdkmanager --sdk_root=${ANDROID_HOME} "build-tools;29.0.3" "cmake;3.10.2.4988404" "ndk;21.1.6352462" "patcher;v4" "platform-tools" "platforms;android-30" "tools"

If your platform command-line tools are 30, the command-line tools will be placed in the cmdline-tools folder. So, you will need to execute the following:

yes | $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_HOME} --licenses
$ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_HOME} "build-tools;30.0.2" "cmake;3.10.2.4988404" "ndk;21.3.6528147" "patcher;v4" "platform-tools" "platforms;android-30" "tools"

If your platform command-line tools are 32, the command-line tools will be placed in the cmdline-tools folder. So, you will need to execute the following (This appears to be backwards compatbile to some degree with Android 30):

yes | $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_HOME} --licenses
$ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_HOME} "build-tools;32.0.0" "cmake;3.22.1" "ndk;25.1.8937393" "platforms;android-32" "patcher;v4" "platform-tools" "tools"

TODO

Try a bunch of these cool priveleges, see what they all do.

  • permission.ACCESS
  • permission.INTERNET
  • permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS
  • permission.ACCESS_NETWORK_STATE
  • permission.WRITE_EXTERNAL_STORAGE
  • permission.READ_PHONE_STATE
  • permission.GET_TASKS
  • permission.REORDER_TASKS
  • permission.WRITE_APN_SETTINGS
  • permission.READ_SECURE_SETTINGS
  • permission.READ_SETTINGS
  • permission.REAL_GET_TASKS
  • permission.INTERACT_ACROSS_USERS
  • permission.MANAGE_USERS
  • permission.INSTALL_PACKAGES
  • permission.DELETE_PACKAGES
  • permission.INTERACT_ACROSS_USERS_FULL
  • permission.READ_MEDIA_STORAGE
  • permission.WRITE_MEDIA_STORAGE
  • android.permission.VR
  • android.permission.INSTALL_PACKAGES

More Repositories

1

espusb

Software-only ESP8266 USB Device
C
1,445
star
2

mini-rv32ima

A tiny C header-only risc-v emulator.
C
1,410
star
3

channel3

ESP8266 Analog Broadcast Television Interface
C
1,277
star
4

ch32v003fun

An open source software development stack for the CH32V003, a 10ยข 48 MHz RISC-V Microcontroller
C
674
star
5

colorchord

Chromatic Sound to Light Conversion System
C
658
star
6

noeuclid

Non-euclidean GPU Raytraced Game
C
641
star
7

esp8266ws2812i2s

ESP8266-based I2S-output WS2812(B) Driver
C
534
star
8

avrcraft

Minecraft server optimized for 8-bit devices.
C
435
star
9

rv003usb

CH32V003 RISC-V Pure Software USB Controller
C
328
star
10

ws2812esp8266

DEPRECATED. Please use esp8266ws2812i2s. No really, stop forking and starring this.
C
298
star
11

esp82xx

Useful ESP8266 C Environment
C
288
star
12

espthernet

ESP8266 10-Base-T Ethernet Driver
C
246
star
13

nosdk8266

Trying to make ESP8266 projects without a big SDK.
C
235
star
14

esp8266rawpackets

Raw Packet Experiments on the ESP8266
JavaScript
148
star
15

fx3fun

Treat your Cypress FX3 a little like a logic analyzer or software defined bus.
C
147
star
16

epaper_projects

C
145
star
17

voxeltastic

View 3D Volume with Translucency in WebGL
JavaScript
143
star
18

shadertrixx

CNLohr's repo for his Unity assets and other shader notes.
ShaderLab
137
star
19

cnovr

CNLohr's OpenVR Misadventures
C
126
star
20

ethertiny

A firmware-only half-duplex 10Base-T implementation for AVRs
PostScript
121
star
21

cnixxi

My experiment with nixie tubes.
C
112
star
22

wiflier

ESP8266-based Quadcopter Brain
KiCad Layout
93
star
23

embeddedDOOM

"emdoom" - a port of DOOM targeted for memory-strapped systems.
C
90
star
24

espwebc3

An in-browser integrated development platform for the ESP32-C3
HTML
84
star
25

esplocalizer

ESP8266 with IMU, Barometer and Battery
C++
83
star
26

esp8266oddclock

What happens when you rip the ESP8266's stable clock source out from under it's feet?
C
81
star
27

esptracker

Lighthouse-based tracker using the TS4231
C
60
star
28

rawdrawandroidexample

Example app using rawdrawandroid as a submodule.
C
59
star
29

wifirxpower

Linux-based WiFi RX Power Grapher
C
59
star
30

pylotron

Embedded VNC-based FPS.
C
58
star
31

esp32s2-cookbook

Low-level tests with the ESP32-S2
C
48
star
32

androidusbtest

Access external devices from Android apps directly in C.
C
46
star
33

superlongexposure

FFMPEG-based tool for non-linear compositing video into long exposures.
C
41
star
34

tplink-raw-wifi

Test using tp-links to do raw wifi.
C
41
star
35

pi_tpi

Using a Raspberry Pi to program an ATTiny10 9 5 or 4
C
39
star
36

what_im_up_to

Just my dumping ground for ideas.
37
star
37

tsopenxr

Single-file header for simple OpenXR Framework use with C
C
36
star
38

t85loudspeaker

ATTiny85 Sound Output
C
35
star
39

avr_vhf

Channel 3 VHF Broadcasting with an AVR
C++
34
star
40

esp8266_dmx_explorer

C
32
star
41

esp8266duplexi2s

Generic duplex communication on the I2S bus in the ESP8266.
C
31
star
42

lamenet

A way of making a really awful network connection.
C
31
star
43

dumbcraft8266

My first stab at a Minecraft-enabled firmware for the ESP8266
C
30
star
44

swadges2017

MAGFest Swag Badges 2017 Firmware
C
29
star
45

cnhardware

C
28
star
46

esp8266_link_test

Test link between an ESP8266 and a base station or another ESP8266 easily.
KiCad Layout
26
star
47

cnballpit-vrc

C#
26
star
48

brokeredupdateandsync

CN's VRC Tools and Prefabs
C#
26
star
49

tinycc-win64-installer

A quick way to use tinyCC on Windows.
NSIS
25
star
50

wificompositer

Various tools I used to collect and composite data from a wifi device into an image.
C
24
star
51

miniosc

Single-file-header OSC library for C (includes platform-independent sockets)
C
21
star
52

esp32-cnlohr-demo

My always-incomplete ESP32 fun zone
C
20
star
53

spreadgine

An OpenGL ES engine with WebGL Output.
C
19
star
54

slapsplat

GLSL
19
star
55

oledscope

Playing around with a 128x128 OLED module
C
19
star
56

cnlohr_social_media_tools

Various social media interface tools.
C
18
star
57

assembly-notes

My repo for a guide to and notes on assembly lagnuage, inling, etc.
18
star
58

x11framegrab

Small static program for taking screenshots of x11 screens and saving/streaming as a variety of formats.
C
18
star
59

usb2812

ATMega32u2 USB driver for WS2812 LEDs.
C
18
star
60

esp8266lighthouse

DO NOT USE THIS PROJECT - WILL BE SUPERCEDED
C
17
star
61

wasm_integrated

An example of how you can fully integrate wasm into a webpage. No need for fetching or any of that jazz.
HTML
17
star
62

swadge-vrchat-bridge

C
16
star
63

magfestbadges

The codebase, schematics, etc. of the MAGFest Badges.
C
16
star
64

cntools

Incomplete-ish C "libraries"
C
16
star
65

wi07clight

Using the wi07c's ESP8266 to control a desk light.
C
16
star
66

avrjslinux

JSLinux Running on an AVR with I/O Port Remapping
JavaScript
14
star
67

tinyispterm

An SPI terminal for USB Tiny ISP compatible AVR prorgammers.
Python
14
star
68

esp32-c3-cntest

C
13
star
69

h264fun

Fun with h264 (mostly encoding)
C
13
star
70

tensigral_lamp

My PCB Tensegrity structure lamp.
C
12
star
71

addressable_leds

Charles's list of addressable LEDs
12
star
72

kelvindmmwifi

Adding some sweet wifis to a kelvin multimeter.
KiCad Layout
11
star
73

attiny85_tb

ATTiny85 Test Bench Tool with Screw Terminals
Eagle
10
star
74

voxeltastic-vrc

Voxel Tracing Shader for VRChat
ShaderLab
10
star
75

esp32s2_dmx512_usb

C
10
star
76

rawdrawwasm

My stab at rawdraw on wasm.
HTML
10
star
77

swadgeguide

My guide for making swadges.
HTML
9
star
78

terriblewordsearch

A C tool for making terrible word searches.
C
9
star
79

cndvr

Assembly
9
star
80

flexcrt

A header for CRTs to allow for scattered writes.
HLSL
8
star
81

swadge2019

the repo for the 2019 swadge
C
8
star
82

donut

MAGFest /is/ a donut.
C
8
star
83

minimal_stm32f407

STM32F407 Minimal self-contained Makefile-based build environment (Plus printf!)
C
8
star
84

esp8266irxmit

ESP8266 IR Transmistter
C
7
star
85

espbadapple

My shot at bad apple on an '8266.
C
7
star
86

minimal_stm32f303

STM32F303 Minimal self-contained Makefile-based build environment (Plus printf!)
C
7
star
87

netlink_without_libnl

Testing using the kernel's netlink, more specifically nl80211 without libnl or genl
C
7
star
88

wxrchat

Distributed WebXR Chat Application
C
6
star
89

esp32_ethernet_test

My Ethernet on the ESP32 Test (incomplete!)
C
6
star
90

tinyisp-micro

My USBTinyISP (with an ATTiny44)
KiCad Layout
6
star
91

esp_network_rgb

JavaScript
6
star
92

charlesvideotools

Linux Video Creation Notes and Tools
C
5
star
93

esp_nonos_sdk

Patchwork of various esp_nonos_sdk subsystems.
C
5
star
94

in99

Gain a superficial of topics in 99 seconds.
5
star
95

shader_perf_grass_comparison

Fake test for checking perf of different shader types.
ShaderLab
5
star
96

bridgesim

Project abandoned. Library code probably has problems.
C
4
star
97

stm32f042_fun

My fun repo for the STM32f042
C
4
star
98

avr_ledprojector

Using an AVR with an mlx90614 to project temperatures!
KiCad Layout
4
star
99

esp8266_32x32panel

An attempt at driving 32x32 panels with an ESP8266.
KiCad Layout
4
star
100

sk6812rgbyspectraldata

Just an email I got from Andrew Sowa
4
star