I have a simple application to prototype: take a wired USB webcam, display it on the screen on a computer device (ideally a small device/screen), and draw a few GUI elements on top of it.
Using Python scripting and OpenCV, I had a working cross-compatible script in 10 minutes, for both Linux and Windows.
Then I realized I'd love this to work on an Android phone. I have devices with USB OTG, and a USB-C hub for the webcam. I confirmed the hardware setup working using someone else's closed source app.
However the development process has been awful. Android Studio has so much going on for a 'Hello World', and trying to integrate various USB webcam libraries has been impossible, even with AI assistants and Google guiding me. Things to do with Gradle versions or Kotlin versions being wrong between the libraries and my Android studio; my project not being able to include external repos via dependencies or toml files, etc.
In frustration I then tried a few python-to-android solutions, which promise to take a python script and make an APK. I tried: Kivy + python for android, and then Beeswax or Briefcase (may have butchered names slightly). Neither would build without extremely esoteric errors that neither me nor GPT had any chance to fix.
Well, looks like modern mobile phones are not a great hacker's playground, huh?
I guess I will go for a raspberry pi equivalent. In fact I already have tested my script on a RPi and it's just fine. But what a waste, needing to use a new computer module, screen display, and battery, when the smartphone has all 3 components nicely set up already in one sleek package.
Anyways that's my rant, wanted to get others' takes on Android (or smartphone in general) dev these days, or even some project advice in case anyone has done something similar connecting a wired webcam to a smartphone.
GPT does poorly with beginners - it's definitely something humans have advantage with AI and I expect the gap to get bigger.
I do not touch legacy projects anymore because they're always horribly broken, half the libraries no longer exist. Many of them are easier to rewrite than fix. You get weird bugs where A needs to be 1.71.0 but B needs A at 1.69.0 or 2+. Upgrading A to 2.0.1 will fix A and B but break CDEFG. Upgrading everything to max breaks switch-case, turns some of your brackets to lambdas, requires you to change your UI from XML to Kotlin, etc, etc.
If you want something to hack stuff with, I made this: https://github.com/smuzani/android-minimalist-template
Originally it was designed for AI with smaller context windows. But it works as a simplified version of our production codebase. The principle behind this is that you should have good peripheral vision and that the shape of the code resembles what it's trying to build.
Coming back a decade later for a side project, I guess I have the same opinion.
Now with the help of GPT-like assistants, I'm sure I could slog through some fairly vanilla development tasks like I did in the past, but when it comes to building anything a bit 'outside the box', no thanks.
Thankfully there are hardware equivalent packages (mini linux development machines like raspberry pi) that fit the bill, but they aren't as ubiquitous or nicely packaged as a modern smartphone unfortunately.
One wonders if there's some opportunity there, take all this great generic smartphone hardware (a $100 phone now is crazy) and package it with a developer-first OS. It could just be a linux system with a dumb, button-focused frontend for users to mimic Android/iOS.
Sounds like "modern" web development.
Reactive programming is useful for front end because the UI will update as soon as the data downloads, so it scales linearly with complexity and API calls, instead of an exponential mess of if-else.
You can use the github repo I linked. I designed it to be complex enough to handle the harder tasks but simple enough for a beginner to reverse engineer. Just download, run to see it work, and hack it into what you need.
(I look in on Android every few years, but I haven't done any real work in it.)
I believe deprecating kapt now also breaks data binding, though I don't know if it breaks all the other basic XML layout stuff.
On the flip side, consider PalmOS. It was SotA at its debut in 1996. In the early aughts, Palm made Treo smartphones when almost no one knew what a smartphone was. It had a multiyear lead, yet it got easily marginalized by iOS and Android. Its technical debt was from maintaining backward compatibility with 90's apps, and cost it dearly. To be fair, company management sucked too.
The moral is: caked-in issues suck, but if you're going all in with a design, the most important thing is to time it with the explosion of the market. Palm was too early, others like Maemo and Windows Phone were too late.
Dart-Flutter still supports them better natively though, instead of having to hack things like reactive programming via Kotlin Flow.
I can't remember if it was Compose or Flutter, where I spent a ridiculous amount of time trying to get something to stay centered on the screen regardless of orientation. Something that I could do pretty easily and quickly with my own UI tech library in C++. However I can't use that code without having to jump through all the annoying hoops you have to jump through with JNI crap in order to use it. So I just don't bother with Android anymore.
It's the classic "I would like to serve 5 terabytes"[0] Google problem.
(Their engineering culture reeks of this. See the tools they have released. Angular, Bazel, Go, Kubernetes, etc. The last one escaped the usual decline of incompetence because the community showed up.
Go has GOPATH. Even in a language designed for "simplicity" initially getting it set up had this roadblock.)
And no doubt the roots of the problem are manifold, but it seems all stemming from ongoing management incompetence (creation of shareholder value[1] maaaybe excluded, though I am very curious what kind of inane metrics the Android SDK team is whipped to chase).
But it is very clear that the guard rails were down especially for the first few years in trying to acquire functionality and market share by any means possible. Now Google is in space of trying to lock down the system while not breaking things.
https://recorder.easeus.com/screen-recording-resource/macos-...
https://lifehacker.com/tech/mac-os-sonoma-update-fixes-scree... ... okay I don't even know what's this :D
> to be covered with a thick, dry layer of something
[0] https://android.googlesource.com/platform/frameworks/base/+/...
[1] https://cs.android.com/android/platform/superproject/main/+/...
The fact your [1] link is a class that's not even used in the TextView class isn't lost on me to start. They share an interface though, scary!1!!
The fact your [0] link is to a copy of the TextView from 2017 is even funnier.
> Just look at the sourcecode for TextView[0] if you want to see for yourself. 8,700 lines of code to show text on the screen? Well actually, TextView is actually a full blown text editor with the editing functionality turned off as a flag.
Hmm yes, 8,700 lines to "just show text". No hyperbole detected there. Who cares about fonts, shadows, or any other visuals on or around the text, all we're showing is "just text".
> Well actually, TextView is actually a full blown text editor with the editing functionality turned off as a flag.
And? It's called code de-duplication. While realistically I think the better approach would have been to have TextEdit be the barebones display only and Editor add the editing functionality, sometimes code is so tightly coupled for reasons that you can't do that easily. This approach is much better than hitting cmd+c/cmd+v and copying the code into a new class.
The funniest part to me is that your rant is about TextViews though. When that's been soft deprecated for 5 years already (replaced by Compose Text element).
The [1] link is only used by TextView. It is completely reliant on TextView and can't be used by other components. And yes, it is used, right here: https://android.googlesource.com/platform/frameworks/base/+/... mEditor is used over 400 times in TextView.java. Did you even read it before commenting?
>The fact your [0] link is to a copy of the TextView from 2017 is even funnier.
Why is that funny? Most of it has not changed. I linked to the up to date one in the second link. I searched "TextView source code" on Google to get the first one. It gets the point across and doesn't matter how old it is.
>Hmm yes, 8,700 lines to "just show text". No hyperbole detected there. Who cares about fonts, shadows, or any other visuals on or around the text, all we're showing is "just text".
I'm pretty sure a lot of that is handled by DynamicLayout, not TextView, although correct me if I'm wrong here. If if it isn't, it should be, and is indicative of poor software design. Shadows certainly should not be handled by TextView, I have no idea why anyone would think that.
Take a look at Flutter's implementation. Text is just 1,400 lines, a large portion of which is documentation (another thing the Adnroid SDK sorely lacks,) and it just shows text to the user.[0] Somehow all the "tight coupling" issues have gone away here, and there is no need to throw a text editor into the code. How does Flutter edit text? It has a base EditableText class[1] that is then exposed by simpler widgets like TextField[2]. Now if I want to make my own custom editable text I can without having to recreate the whole thing.
>And? It's called code de-duplication
No. You don't get rid of separation of concerns to save a few bytes. If TextView cannot be made into a separate component that EditText uses then it should implement the functionality of TextView on its own. This is called the single-responsibility principle. A TextView should not be a texteditor. It can't get any simpler than that. Either refactor the text viewing components into something that can be shared by TextView and EditText, or separate them completely.
>The funniest part to me is that your rant is about TextViews though. When that's been soft deprecated for 5 years already (replaced by Compose Text element).
I wonder why this great piece of code was deprecated if it's so great? And yes, that's another great thing about the Andorid SDK. Everything is deprecated while its replacements are only supported on new devices. Then you end up having to do:
if(onReallyOldDevice){
useDeprecatedMethod1()
}else if (onOldDevice){ useDeprecatedMethod2()
}else{ useSoonToBeDeprecatedMethod()
}See eg. accessing file systems.
[0] https://github.com/flutter/flutter/blob/master/packages/flut...
[1] https://github.com/flutter/flutter/blob/master/packages/flut...
[2] https://github.com/flutter/flutter/blob/master/packages/flut...
Happy to answer any questions or help you out if you decide to keep going down this road, shoot me an email at kevmo314@gmail.com. Ultimately an Android phone is still just a Linux computer but jumping through the hoops is definitely hard.
> ninja: error: 'lib/libjpeg.so', needed by 'C:/Users/ADMIN/AndroidStudioProjects/kineticstreamer/app/build/intermediates/cxx/Debug/3xf5p505/obj/arm64-v8a/libkinetic.so', missing and no known rule to make it
That being said, I browsed through the code some more and while I think it's a great Android project, I don't think (assuming I got it working) it would be advisable for me to build on top of this. The existing complexity, and my lack of faith on cross-compatibility (different phones, SDK updates, etc) are a turn off. Heck I've even seen certain libraries and includes fail because they require different versions of Java/JDK that I have available.
So in summary, I think the solution for myself at least for now, will be to explore a different hardware route. A cheap raspberry pi equivalent, with a small display, and battery - annoying to have all these extra components but at least I know it'll work reliably.
https://developer.android.com/about/versions/15/behavior-cha...
Gradle is deprecated now though. And Jetpack Compose is about as convenient as Flutter.
What is the new hotness replacing Gradle?
Library management got a LOT nicer when it was introduced, but surely we didn't need all of that to achieve it.
At this point I have a clean repo with Blaze set up that I use as a starting point for Android applications. Then Android Studio with the Blaze plugin and I'm set.
They proceeded to tell me what to download on my laptop. I repeated my question, emphasizing "ON Android". They gave me blank looks. I said, "I want to install a toolchain ON an Android device, and run it there. How do I do that?"
They had no idea.
I asked, "What if you want to compile something that requires compiling something, then using that something further down the line, like Perl?"
Again, no idea.
A platform without a native toolchain is a very awkward place to be. I stopped trying to wrap my head around it and stopped playing with Android.
For fun, I managed to get a full X environment running, including Intellij! The amazing thing was that it actually ran fairly decently on a Pixel 5, though it did tend to run out of memory with anything more than trivial projects.
I had been soured by the Android platform because I bought a brand new device, mostly because it had a physical keyboard, only to find out that it wouldn't get any new updates, nor could I use Skype on it, nor could I tether with it. Android was supposed to be the "open" platform, but at the time (which, admittedly, was something like ten or so years ago), it wasn't.
If I can use Termux to get a modern OpenSSH on to my device, it may get used yet! Thank you :)
What you want is to cross compile using the NDK toolchain. That should get you 95% of the way there (barring tweaking with downstream project flags to work with bionic libc and limited Android user land and other Android idiosyncrasies)
Termux was F-droid only, but 4 years later is back on the Play Store: https://github.com/termux-play-store#current-status-for-user...
Termux has both glibc and musl libc. Android has bionic libc.
One time I got JupyterLab to run on Android in termux with `proot` and pip. And then the mobile UI needed work in a WebView app or just a browser tab t. Maybe things would port back from Colab to JupyterLab.
conda-forge and Linux arm64 packages don't work on arm64 Android devices, so the only option is to install the *-dev dependencies and wait for compilation to finish on the Android device.
Waydroid is one way to work with Android APKs in a guest container on a Linux host.
That Android Studio doesn't work on Android or ChromiumOS without containers (that students can't have either).
> There are docker and containerd in termux-packages. https://github.com/termux/termux-packages/tree/master/root-p...
But Android 13+ supports rootless pKVM VMs, which podman-machine should be able to run containers in; (but only APK-installed binaries are blessed with the necessary extended filesystem attributes to exec on Android 4.4+ with SELinux in enforcing mode.)
- Android pKVM: https://source.android.com/docs/core/virtualization/architec... :
> qemu + pKVM + podman-machine:
> The protected kernel-based virtual machine (pKVM) is built upon the Linux KVM hypervisor, which has been extended with the ability to restrict access to the payloads running in guest virtual machines marked ‘protected’ at the time of creation.
> KVM/arm64 supports different execution modes depending on the availability of certain CPU features, namely, the Virtualization Host Extensions (VHE) (ARMv8.1 and later).
- "Android 13 virtualization lets [Pixel >= 6] run Windows 11, Linux distributions" (2022) https://news.ycombinator.com/item?id=30328692
It's faster to keep a minimal container hosting VM updated.
So, podman-machine for Android in Termux might help solve for development UX on Android (and e.g. Android Studio on Android).
podman-machine: https://docs.podman.io/en/latest/markdown/podman-machine.1.h...
OpenCV also has a warning and a guide for people trying to use it for Android dev https://opencv.org/android/. Did you look through this?
Also why do you want to use a USB camera when every phone has a couple cameras built in? I think you're going down a road of frustration if you think mobile OSes aren't built with completely different use cases in mind than desktop environments.
Theres a lot of information the Android dev site about getting up and running with the camera. You can pass a lot of the photo stuff off to other camera apps on your phone, but if you really need to do stuff in the app theres an official Android library for making your life easier. Theres also a lot of official Android libraries and well known libraries for images and videos that might be easier to work with than OpenCV. You don't actually say what you are trying to ultimately do.
Gradle is the part of Android dev everyone hates.
(But really, Android dev is a qualitatively different level of fucked up compared to React or any major Python framework I can think of. React Native, though...)
Sadly the golden age of the app store is long gone. I used to make thousands monthly around 2015 with silly apps, but all went down the drain by 2018. Making apps isn't worth anymore.
I wrote an app and had it running in both iOS and Android in no time (with minimal iOS dev and zero Android xp prior to that).
My app included the Jitsi video extension (with very customized Jitsi controls and self-hosted backend), so not just a simple CRUD app.
(To be fair, my background is mostly Node and React, but those skills made it a breeze.)
"You do not need to root your device. And - if you prefer - you do not need a separate development machine (PC or laptop): All can be done in a terminal on the device, and even in a Lisp REPL while the App is running."
What took you 10 minutes would take me a long time to learn. I rather enjoyed making some basic Android apps. I didn't work with much hardware stuff and heard that part is tough due to all the variations.
Yes it's become quite clear to me that using an Android phone is not a good development platform to work with external hardware devices. I understand this has never been it's intended purpose, but come on, we have a linux kernel sitting under the hood. Just feels like a waste of potential.
10 Install an app that is able to use UVC cameras
20 If works goto 50
30 Else Use a different phone and goto 10
50 Find an open-source app that is able to use UVC cameras
60 If it doesn't work goto 50 (find another app)
70 Try compiling the open-source app
80 If it works goto 150
90 ???
150 Reduce open-source app to minimum code necessary
160 Add own code
170 Make sure the phone doesn't overheat and/or develop a bloated battery when you leave it running for weeks and weeksSo you either reimpmentent the whole thing in a native way (using Java/Kotlin or C++ for lower level integration) or you’re SOL. You can embed Python libraries, but you’re better off learning to use wherever native analogues and frameworks the platform already support.
I personally stay the heck away from Android Studio (I got a very early start in Android development, so most of my projects are just Gradle/pom.xml or a Makefile atop a “normal” Java tree).
That said, you have _a lot more flexibilty_ in incorporating multiple languages and non-native frameworks than, say, in iOS.
If you ever have to work with native code (or things like OpenCV) start praying from day one and never stop.
You need bigger and bigger laptops to even run that disgrace of an IDE Android Studio. This always gets me!
So dev tools/env? Oh, god! Fuck Google!
Trying to do userland USB in an Android app to talk to a UVC webcam connected through USB OTG is not something even a niche of apps care for, and the native camera framework definitely doesn't care about because if it was trying to workaround the UVC spec Android phone cameras would have never left the original Gameboy camera age.
So with no native support for your use case, you are now having to wrangle the pretty shitty libusb and the even more terrible libuvc in working within the confines of an Android app. And to the credit of Android, this is possible! People have made it work! People with in depth knowledge of how the parts fit together, that is, and so GPT won't be of any help.
Android development is not simple. Take time to learn the architecture and underlying concepts. It took me a couple of weeks and some false starts to make sense of things (although back then I was a college student; a professional can probably get started faster).
You are not crazy and the pain you feel is the pain of commercial IT. Not strictly need to commerce of course, but that's the modern common practice. The cure is FLOSS, mandatory, from the start.
I think we're going to see the tendency accelerate to develop and validate ideas on iOS first and only later outsource a crappy Android port.
Using an external webcam with an Android device seems a fairly exotic scenario doesn't it? Whatever, I would intuitively expect (disclaimer: almost no experience in mobile development) the Android OS to detect a USB-attached camera as another built-in camera and expose it via common APIs rather than let you access it via some sort of low-level libs reading the USB.
But I feel you, if you don't have enough experience dealing with different Android, Gradle, AS errors then you're really having a bad day. But shouldn't be a deal breaker, just give it some time and more familiarity.
I want to jump back to Android dev contracting, my two questions for the up-to-date Android devs: - Do you have any resource to catch up with what I missed in the past 4-5 years of Android development? - How is the Android job market these days, compared to the iOS one?
-
You won't have to touch any horrible Kotlin nor Swift but still be able to publish the app on the stores if you want to.
Why is Android Development so difficult/complex? (compared to Web and Desktop)
Python packaging is notoriously bad, and while you can get a Linux/Windows compatible script without too much work, getting to a single executable that just runs is much harder. Cloning a repo, setting up a virtualenv, installing an openssl dependendcy or whatever, is just not something that exists in the mobile world. We have to put more effort into the packaging, and that means a higher bar for things like this. There are answers to this in Python that claim to produce single, relocatable, Python binaries, and I've never seen one without a huge list of caveats. Even yesterday I was patching an open source library that didn't work inside one of these because it had the gaul to use... checks notes, os.path.
> Well, looks like modern mobile phones are not a great hacker's playground, huh?
This sums it up. They are not. The security environment on these devices pretty much ends this before you even get to writing any code, and that's generally a good thing. Phones are appliances for most people. There's a reason why "apps" took off in a way that boxed desktop software never did, and there's a reason why boxed desktop software on Windows did far better than package managers on Linux. Almost everyone wants more a more polished experience. Shipping a Python script running OpenCV to a phone is not going to produce a polished experience.
I don't buy your "security through difficulty" argument for that reason alone.
OP writing this prototype as a web app would likely have been the path of least resistance to having something work on mobile.
Which toolkit did you use?
but I never had trouble loading in C/C++ libraries with the NDK beyond the debugging issues
Known fact, take it or leave it :)
To be fair UI development can not be simple in itself.
Because of the exponentially growing state machine => simple Rails style general purpose frameworks are impossible, it will always be a challenging problem.
I'm also curious if it is just me. I am a grey hair now, with many other responsibilities. Why were C, Python and Go so easy for me when kotlin seems so hard to penetrate (for me)? Is there a way to quantify language complexity?
Take the K&R C book. It describes the language itself only - not the standard library. The Kotlin docs describe the language _plus_ parts of the Kotlin standard library which is why it appears to have lots of features. You'd have to read through half the standard C library documentation & pthreads docs in addition to K&R C to get the equivalent experience.
Kotlin compiles now to JS, WASM... even LLVM bitcode if you want it to. Coming to Kotlin from a pure lang perspective, I'm not sure what it would be like, it might not be you. I know as someone who came to it through Java that it is a massive improvement on what I had before.
`
enum class Sample { A, B }
val x: Sample = Sample.A
val y = when (x) {
Sample.A → 0
Sample.B → 1
}`
I think if you give it time you might like it. It takes some getting used to, sure, but especially compared with the alternatives (Java to use JVM, Java on Android, etc) it's pretty great.
Cross-platform Kotlin is very new but it works surprisingly well.
Jetpack Compose feels underrated around here. It basically has most of the upsides of React, but with far fewer downsides. If it weren't for the fact that it's basically Android-only[0], I would probably stick to Kotlin for all my side projects.
[0] I know there's Compose Multiplatform, but I don't trust cross-platform compilation to be reliable.
> Well, looks like modern mobile phones are not a great hacker's playground, huh?
I'm using a GNU/Linux phone and I'm super happy with how playgroundish it can get if I want.
A wireless webcam is the simplest thing that might work. Hosting a video stream on other hardware might be the second simplest thing.
Good luck.
https://stackoverflow.com/questions/78244976/package-resolve...
OTOH, Apple does a better job at handling things like languages, currencies, and all those experience, whereas Google is notoriously unreliable despite all the best practices. It's common practice to just "force" the wrong locale on an app to handle translations because a user's device would be English-US and yet someone wants the display in another language. OR someone wants a certain local currency in the form of 1.000,00 and not 1,000.00 (which also wreaks havoc with BigDecimal etc) and yet they'll keep the language and formatting as English and you'd have to do some override. We spent weeks on things like this and the iOS solution would just be "use device settings lol"
Sounds fun at first, but it always ends in tears.