Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
b0lt
Apr 29, 2005

netcat posted:

Is it possible to build Android with OEM unlocking enabled and dm-verity disabled by default? That does not involve hacking the uboot source and figuring out whatever magic the OEM unlocking service does? Or is it vendor specific?

bootloading locking is orthogonal to the build, -eng builds have verity disabled by default

Adbot
ADBOT LOVES YOU

VideoGameVet
May 14, 2005

It is by caffeine alone I set my bike in motion. It is by the juice of Java that pedaling acquires speed, the teeth acquire stains, stains become a warning. It is by caffeine alone I set my bike in motion.
My Android App, which works fine via. Google Play, isn't acceptable for the Amazon App Store.

Two issues:

1. Amazon only likes the arm64-v8a-release.apk, the rest it says 0 devices.

2. And that fails: "We are unable to test your app due to install/launch failure in all compatible devices. Please fix the issue and re-submit the app."

So what magic is needed to get these android apps onto the Amazon Store?

Google Play link (it's free): https://play.google.com/store/apps/details?id=com.wvolk.climate

Volguus
Mar 3, 2009
Amazon has an "App Store"? For what?

VideoGameVet
May 14, 2005

It is by caffeine alone I set my bike in motion. It is by the juice of Java that pedaling acquires speed, the teeth acquire stains, stains become a warning. It is by caffeine alone I set my bike in motion.

Volguus posted:

Amazon has an "App Store"? For what?

Well, for one the FireTV and the dev. system I use supports that.

I've talked to some publishers and it's worth doing.

Volguus
Mar 3, 2009

VideoGameVet posted:

Well, for one the FireTV and the dev. system I use supports that.

I've talked to some publishers and it's worth doing.

Oh, they don't go through the normal google store? How special are they to require their own app store?

Lutha Mahtin
Oct 10, 2010

Your brokebrain sin is absolved...go and shitpost no more!

Is this honestly the first time that all of you geniuses are hearing about Android app stores other than Google Play? I don't know if I'd trust Android dev advice from anyone who isn't aware of that, holy crap :psyduck:

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Volguus posted:

Oh, they don't go through the normal google store? How special are they to require their own app store?

If you have a Kindle fire tablet, that's where all the apps are going through. Getting the Play Store on your device requires getting approval and agreeing to various terms you may not want such as not allowing the device to be fully locked down, while Amazon wants a walled garden and wants to take that revenue cut for themselves.

I don't know what licensing magic they do for the all access kids tablet setup, but it's pretty swell and they really do have quite a decent library at this point.

Volguus
Mar 3, 2009

Volmarias posted:

If you have a Kindle fire tablet, that's where all the apps are going through. Getting the Play Store on your device requires getting approval and agreeing to various terms you may not want such as not allowing the device to be fully locked down, while Amazon wants a walled garden and wants to take that revenue cut for themselves.

I don't know what licensing magic they do for the all access kids tablet setup, but it's pretty swell and they really do have quite a decent library at this point.

Oh, interesting. Had no idea that amazon's Fire tablets had a special treatment. I didn't even know they were running Android.

FAT32 SHAMER
Aug 16, 2012



Hopefully you guys have heard of room and know about it, because i dont know how to google this question

We're porting our local storage from shared preferences to room. Currently we convert a given object to json then store it as a string after doing some magic to it. I have an object that i need to port to room but before i bother trying i wanted to make sure:

Kotlin code:
data class Foo(
        var pojo: POJO?,
        var string: String?,
        var pojo2: POJOTheSecond?,
        var pojo3List: List<POJOTheThird>?,
        var pojo4: POJOTheFourth?)
Can I store POJOs as part of the object i want to store? Can I even store lists? Or do i need to boil them down to String/Integer/whatever first? If no, how exactly do i do that? Do i have to make each pojo an entity first?

All of the examples use primitives so i wasnt sure

e; I almost think Realm would be better suited for what we're trying to do especially given Google's track record for projects, but the spec calls for room unless i can convince them otherwise

FAT32 SHAMER fucked around with this message at 03:09 on Oct 5, 2019

Splinter
Jul 4, 2003
Cowabunga!
You can write TypeConverters to convert objects to and from a type that SQLite can handle (have to do this even with dates iirc).

You can include lists of other entities using the @Relation annotation (initially this could only handle one to many relations, but I believe they added many to many recently).

You can use the @Embedded annotation to include another entity, or another POJO who's fields you want to be able to reference in a query (again iirc).

Memory is a little foggy, but this should at least point you towards the right documentation.

FAT32 SHAMER
Aug 16, 2012



Splinter posted:

You can write TypeConverters to convert objects to and from a type that SQLite can handle (have to do this even with dates iirc).

You can include lists of other entities using the @Relation annotation (initially this could only handle one to many relations, but I believe they added many to many recently).

You can use the @Embedded annotation to include another entity, or another POJO who's fields you want to be able to reference in a query (again iirc).

Memory is a little foggy, but this should at least point you towards the right documentation.

welp, Realm it is

(mostly because i needed to access databases from okhttp interceptors and you need context to do it)

FAT32 SHAMER
Aug 16, 2012



Does anyone know how to implement a 302 redirect with the new single activity navigation component in Jetpack?

We’re refactoring since it’s currently at 2015 quality of code and I know I can get the app from approximately 25 activities to 3, but I’m not sure how to have the user click the login button, enter their login info in chrome, then get redirected back to the app and retrieve the data we currently get as an intent.

Do I just like incorporate the intent filtering as part of the single activity? Is this what they’re calling deep linking for some reason? Can you have more than one activity when using the navigation component?

Googling this poo poo just yields a bunch of medium articles with two fragments pointing at the sky

kitten smoothie
Dec 29, 2001

https://developer.android.com/guide/navigation/navigation-deep-link#implicit

Have you already looked at this? I haven't tried this but it looks like you can set URI matchers on a specific state in the navigation graph, and the toolchain will auto-generate the intent filters for the container activity accordingly.

FAT32 SHAMER
Aug 16, 2012



kitten smoothie posted:

https://developer.android.com/guide/navigation/navigation-deep-link#implicit

Have you already looked at this? I haven't tried this but it looks like you can set URI matchers on a specific state in the navigation graph, and the toolchain will auto-generate the intent filters for the container activity accordingly.

I’ve not tried anything yet since it was the weekend, but I couldn’t find any documentation on how to get any data in the intent.

[url=https://www.reddit.com/r/androiddev/comments/dh71r0/android_navigation_and_intents_from_chrome/?utm_source=share&utm_medium=ios_app&utm_name=iossmf]i asked on reddit and they say just handle the token callback in your main activity then do logic to determine what screen to show, but idk

I have a Droidcon Berlin video queued up for tomorrow about Navigation AAC and Single Activity so I’m hoping it’ll get mentioned there. It’s odd that they don’t talk about this when it’s such a major usecase for activities over fragments in the first place

Unkempt
May 24, 2003

...perfect spiral, scientists are still figuring it out...
Don't do much android and haven't for 3-4 years so this is probably a really stupid thing, but...

I pulled out an old project, let Android Studio do all its updates, SDK update, SDK tools updates and all that sort of stuff, and somethings broken somewhere as when I try to build most of my dependencies are screwed. It's looking like this:



The wearable stuff seems fine so I assume there's something wrong here:




- presumably with
code:
implementation fileTree(dir: 'libs', include: ['*.jar'])
- but that seems to be the bog-standard line that's in all the examples etc, so I have no idea what's broken or where. Anyone got any ideas?

edit: it's just found another 2-odd GB of stuff to update, maybe that'll do something.
edit2: nope. gently caress it, starting another project.

Unkempt fucked around with this message at 21:53 on Oct 16, 2019

FAT32 SHAMER
Aug 16, 2012



I'm not entirely sure, but it looks like androidx broke your build

FAT32 SHAMER
Aug 16, 2012



FAT32 SHAMER posted:

I’ve not tried anything yet since it was the weekend, but I couldn’t find any documentation on how to get any data in the intent.

[url=https://www.reddit.com/r/androiddev/comments/dh71r0/android_navigation_and_intents_from_chrome/?utm_source=share&utm_medium=ios_app&utm_name=iossmf]i asked on reddit and they say just handle the token callback in your main activity then do logic to determine what screen to show, but idk

I have a Droidcon Berlin video queued up for tomorrow about Navigation AAC and Single Activity so I’m hoping it’ll get mentioned there. It’s odd that they don’t talk about this when it’s such a major usecase for activities over fragments in the first place

oh so in case anyone else has this question

code:
    private fun handleIntents() {
        when {
            intent?.action == Intent.ACTION_VIEW -> {
                Timber.d("Intent received")
                if (!intent.data.getQueryParameter(RESPONSE_TYPE_KEY).isNullOrBlank() &&
                    !intent.data.getQueryParameter(STATE_KEY).isNullOrBlank()) {
                    Timber.d("Forwarding URI from to MainViewModel")
                    viewModel.processNewIntent(intent.data)
                }
            }
        }
    }
That's all you have to do in your single activity. Then just handle the received intent data in your viewmodel and you're good to go. You can handle other intent types in the same way, and Jetpack Navigation will handle a lot of other stuff as well.

Head Bee Guy
Jun 12, 2011

Retarded for Busting
Grimey Drawer
If any of you guys are based in NYC and need a job, the public-safety app Citizen recently posted some openings for iOS (and Android) engineers. If you're interested, pm me, and I can forward your info along.


e: fixed the link

https://jobs.lever.co/citizen/38dea578-b6db-4386-9b0a-dadb7a76b250

Head Bee Guy fucked around with this message at 14:16 on Nov 12, 2019

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Head Bee Guy posted:

If any of you guys are based in NYC and need a job, the public-safety app Citizen recently posted some openings for iOS (and Android) engineers. If you're interested, pm me, and I can forward your info along.

https://jobs.lever.co/citizen/38dea...0a-dadb7a76b250

Your actual link has ellipses in it, please try again.

Horse Inspector
Aug 11, 2005
privacy publicly displayed
Does anyone have any knowledge of the Media2 apis? I pretty much have it all working for an audio app, but I'm trying work out if I have found a bug or if my stupidity has caught up to me again.

Setting a MediaItem/Playlist while the player is in an idle state is literally noted as the correct thing to do here. Understandly this internally triggers a callback which queries the underlying exoplayer instance for the duration of the item, presumably so it can be correctly displayed in the notification. Unfortnately though, the exoplayer wrapper has a state check when the duration is requested, and that state check is...
code:
getState() != MediaPlayer2.PLAYER_STATE_IDLE
... which, yeah.

It appears that you should set your initial MediaItem while the player is idle, but the code literally throws an IllegalStateException if you do exactly that. Unless I am missing something utterly obvious and have gone about this a stupid way.

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

That should be fine - the MediaPlayer code that calls getDuration() catches IllegalStateExceptions and returns UNKNOWN_TIME

version 1.0.2 of the media2 library basically reinforces that behaviour

quote:

Fixed a bug where ExoPlayer would not throw an IllegalStateException when getDuration() is called in an IDLE state (aosp/987246)

so it seems like it's all intended. Are you actually getting crashes?

Horse Inspector
Aug 11, 2005
privacy publicly displayed
Hey thanks for the reply!

You're absolutely right about that, I assumed it wasn't intended behavior because it causes the notification to display nonsense info, and I expected the SessionResult to have an error status rather than just throwing an exception in the thread.

The other thing that threw me was that the documentation for play() indicates you don't need to call prepare() before playing, however the fix for this (for me at least) is to call prepare immediately after setting the media. I have to say though, that sort of feels like I am relying on a race condition going my way... but I just checked google's own integration test and that's exactly what they do.

I'm clearly not understanding something about the executors and need to research that. Anyway I'm rambling, your post helped me get further in my quest to make this work, thanks!

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

It says the methods in MediaController are thread safe (up near the top of the docs) so I'm guessing it's just queueing commands on the executor? So it'll only run one at a time, and if it gets a prepare() call when it's already done one, it'll just ignore it? I haven't looked at the source or anything though!

Horse Inspector
Aug 11, 2005
privacy publicly displayed
Really just posting for posterity and for anyone who has the same issues in future, but it looks like my hunch on the race condition was right.

The state check happens on a different thread to the original setMediaItem()/setPlaylist() call and the reason Google's integration test works is because the call to prepare() is hit before the state check. If you delay the prepare() call at all (I used an RxJava timer to simulate a delay) the problem resurfaces.

I'm going to look closer at the callbacks and hopefully they get called in the right order and the answer will be to call prepare() from one of them. Even then that means calling play() without prepare() isn't an option, so this seems like a bug? If not I guess I'll try supplying the session and controller callbacks with the same executor? This is my first foray in to Android dev so I'm fumbling in the dark mostly.

danishcake
Aug 15, 2004
I'm driving myself mad with some basic basic basic Android crypto, using the fancy new StrongBox backed key storage.

code:
    /**
     * Generates an 2048 bit RSA keypair
     */
    private fun generateRsaKeypair(alias: String, isStrongboxBacked: Boolean): KeyPair {
        val keyGenParameterSpec = KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_WRAP_KEY or
                KeyProperties.PURPOSE_DECRYPT or KeyProperties.PURPOSE_ENCRYPT)
            .run {
                setIsStrongBoxBacked(isStrongboxBacked)
                setDigests(KeyProperties.DIGEST_SHA256)
                setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
                setBlockModes(KeyProperties.BLOCK_MODE_ECB)
                setAlgorithmParameterSpec(RSAKeyGenParameterSpec(2048, RSAKeyGenParameterSpec.F4))
                setUserAuthenticationRequired(false)
                build()
            }
        val keypair = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore").let {
            it.initialize(keyGenParameterSpec)
            it.genKeyPair()
        }

        return keypair;
    }


@Test
    fun canRsaRoundtrip() {
        // This test only works if I generate the RSA keypair with isStrongboxBacked = false
        val wrappingKey = generateRsaKeypair("roundtrip", isStrongboxBacked = true)

        val input = ByteArray(32)

        val spec = OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)

        val encCipher = Cipher.getInstance("RSA/ECB/OAEPPadding")
        encCipher.init(Cipher.ENCRYPT_MODE, wrappingKey.public, spec)
        val ciphertext = encCipher.doFinal(input)

        val decCipher = Cipher.getInstance("RSA/ECB/OAEPPadding")
        decCipher.init(Cipher.DECRYPT_MODE, wrappingKey.private, spec)
        val cleartext = decCipher.doFinal(ciphertext)
    }
It seems to be related to usage of SHA-256 somehow. If I change the spec to
code:
        val spec = OAEPParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)
then everything works. Super stumped, and it's hard to debug as the failure occurs in a hardware blackbox. The error reported is android.security.KeyStoreException: Unknown error (-1000), which I think is just wrapping a code returned by the hardware crypto.

Help?

FAT32 SHAMER
Aug 16, 2012



I’m still using bouncycastle for crypto since it Just Works and they have a lib for iOS as well, so we can guarantee our implementation is the same across platforms

danishcake
Aug 15, 2004
If I want it to just work I can set the isStrongboxBacked=false :p

This is all in aid of importing keys securely into hardware via WrappedKeyEntry. This allows some cool stuff like keys never being decrypted in RAM, even in a secure enclave. It also mandates the crypto I've got to use, which is the bit I can't get to work. Bah.

hooah
Feb 6, 2006
WTF?
I've tried Googling this, but no luck. Is there a way to get a list of the file names in a res directory? I'm going through a Udemy course to learn Android development, and the current app is a quiz app that is set up initially to ask "which country's flag is this?". The instructor is hard-coding all the question data, but I thought it'd be nice to be able to generate the options and correct answer from the list of flag image files.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

hooah posted:

I've tried Googling this, but no luck. Is there a way to get a list of the file names in a res directory? I'm going through a Udemy course to learn Android development, and the current app is a quiz app that is set up initially to ask "which country's flag is this?". The instructor is hard-coding all the question data, but I thought it'd be nice to be able to generate the options and correct answer from the list of flag image files.

I don't believe there's a convenient built in way, you may need to use reflection to examine all of the fields in the R class, then use the appropriate method in the Resources class to fetch them. There's no directory structure save for resource type, as Android wants to fetch the best resource for your current configuration, so it doesn't really want to expose that unless you ask. The directory structure for res is one deep, and the form of resource is pulled from the directory name (in a pretty elegant way imo).

hooah
Feb 6, 2006
WTF?
Why the hell are some constants in android.graphics.Typeface ints and some Typefaces? That means I can do e.g. view.typeface = Typeface.DEFAULT but for bold I have to do view.setTypeface(view.typeface, Typeface.BOLD).

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

hooah posted:

Why the hell are some constants in android.graphics.Typeface ints and some Typefaces? That means I can do e.g. view.typeface = Typeface.DEFAULT but for bold I have to do view.setTypeface(view.typeface, Typeface.BOLD).

Per the docs:

quote:

Sets the typeface and style in which the text should be displayed, and turns on the fake bold and italic bits in the Paint if the Typeface that you provided does not have all the bits in the style that you specified.

Fun fact: You can pass null as the typeface to that one, which creates a new typeface!

Anyway, the idea is that, behind the scenes, your typeface gets replaced with another from the same family that has the requested styles. If your typeface family does not support those styles, one will be appointed to you by a court set via the Paint by over-drawing (bold) or by skewing.

Yes, there could be a convenient "setBold" flag. There is not.

E: I think I misunderstood your question. There is actually a DEFAULT_BOLD typeface as well. The idea was that, for performance reasons that are no longer necessarily valid, you would want to use intflags. Because you want to potentially set multiple styles, bit flags tend to be most performant. The DEFAULT typeface is just a convenience for you, you could also call Typeface.defaultFromStyle but most people don't need to do that.

Volmarias fucked around with this message at 22:07 on Jul 10, 2020

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

hooah posted:

I've tried Googling this, but no luck. Is there a way to get a list of the file names in a res directory? I'm going through a Udemy course to learn Android development, and the current app is a quiz app that is set up initially to ask "which country's flag is this?". The instructor is hard-coding all the question data, but I thought it'd be nice to be able to generate the options and correct answer from the list of flag image files.

You could stick them all in a folder in assets and use #list to grab all the filenames

hooah
Feb 6, 2006
WTF?
Thanks for the detailed answer, Volmarias.

baka kaba posted:

You could stick them all in a folder in assets and use #list to grab all the filenames

But I'm just using the built-in ones.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

hooah posted:

But I'm just using the built-in ones.

What built in ones? I don't think any flag resources are packed with Android (for political reasons at a minimum)

hooah
Feb 6, 2006
WTF?

Volmarias posted:

What built in ones? I don't think any flag resources are packed with Android (for political reasons at a minimum)

Whoops, I just saw that Baka quoted me, not which post was quoted...

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

You mean whatever ones are in the project you're working with for the course right? Yeah in that case as far as I know you'd need to do what Volmarias said, reflection on the com.example.hooah.R class, grab the fields, filter out the drawable ones...

personally I'd probably do that early and generate a lookup map or something

e- ok someone's gonna start throwing pies in a minute

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
Yeah, Baka Kaba has the right idea if you want to have an arbitrary list of content to enumerate over, although given that you're trying to make something that matches flags to languages / countries / moon treaties, you'll have to have the matching somehow anyway, whether in code or another file.

ringu0
Feb 24, 2013


I'm providing a configuration file for the app in the Android 11 environment. I have a stock emulator running the latest Android 11 image. I have a configuration file in /Download.

Now, with the advent of Scoped Storage, /Download is no longer accessible. I'm trying to manually copy this configuration file into the app-specific directory: sdcard/Android/data/<package_name>/files. My only option currently is to use the stock Files app. But for some reason it doesn't see sdcard/Android/data directory. It only sees sdcard/Android/media directory. How do I copy the file?

--

If you have a feeling I'm doing something fundamentally wrong, you might be correct. Let me ask you a question: how DO you provide a configuration file for the app in the Android 11 environment? Basically I need to point the app to the web services, and the URL for these services is stored in the configuration file.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

ringu0 posted:

I'm providing a configuration file for the app in the Android 11 environment. I have a stock emulator running the latest Android 11 image. I have a configuration file in /Download.

Now, with the advent of Scoped Storage, /Download is no longer accessible. I'm trying to manually copy this configuration file into the app-specific directory: sdcard/Android/data/<package_name>/files. My only option currently is to use the stock Files app. But for some reason it doesn't see sdcard/Android/data directory. It only sees sdcard/Android/media directory. How do I copy the file?

--

If you have a feeling I'm doing something fundamentally wrong, you might be correct. Let me ask you a question: how DO you provide a configuration file for the app in the Android 11 environment? Basically I need to point the app to the web services, and the URL for these services is stored in the configuration file.


code:

adb shell
su
cp /Download/filename sdcard/Android/data/<package_name>/files

Or whatever the actual paths are.

Are you writing and installing the app? If so, maybe you can have the app download the configuration file yourself, or look in the public storage directories? Or, as Jabor suggests below, just package it with your app?

Volmarias fucked around with this message at 00:40 on Jul 17, 2020

Adbot
ADBOT LOVES YOU

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Either package it with the binary you're shipping, or have a first-run state where the user can provide that information.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply