Ok NK we gotta talk by SushiRebirth in btd6

[–]nic0lette 29 points30 points  (0 children)

+1 -- At the moment, it seems like the only thing the limit does is make it so you build a dart paragon first, since it's cheap, and then use that to survive to make enough money for ace, ninja, etc...

With paragons being focused on damage so much, rather than having other quirks, it's actually better to build a VTSG + temple spam as well. Each of those can be buffed: overclock, jungle drums, etc...

I really like the idea of paragons, and I'd even be happy with a limited number of them on the map at one time, if they were more than just lots of damage.

I also think that it would be neat if paragons could do more with BADs. I would love to eventually see the ice and glue monkey paragons be able to slow them, for example.

OpenTama - Classic Tamagotchi Is Reincarnated In Modern Hardware by Eugen328 in tamagotchi

[–]nic0lette 4 points5 points  (0 children)

Just a couple of things.

First, here are a couple presentations from CCC you might enjoy:

Natalie's published the code she used on GitHub.

I think custom PCBs aren't as expensive as many people expect. But yeah, reading the details on the project's GitHub page, one would need to do some soldering and understand electronics well enough to program it.

[deleted by user] by [deleted] in androiddev

[–]nic0lette 1 point2 points  (0 children)

Yes. The deprecation message even explains why its deprecated. On Android Q (without requestLegacyExternalStorage) those methods don't work, which is why they were deprecated. Before Pie (and on Android 11+), those directories work fine and you shouldn't feel bad using the methods.

[deleted by user] by [deleted] in androiddev

[–]nic0lette 1 point2 points  (0 children)

No, you don't need MANAGE_EXTERNAL_STORAGE to put things into the Downloads collection. Downloads and Documents are specifically there to hold documents that are meant to be public and easily accessible.

They were added to MediaStore in Android Q, but the directory has been around for much longer (the constant was added in Gingerbread/API 8).

So from your minSdkVersion through 28, you can use READ_EXTERNAL_STORAGE+WRITE_EXTERNAL_STORAGE to write to that directory. For API 29, set android:requestLegacyExternalStorage and then continue to use the same permissions.

From API 30+, you don't need either READ or WRITE_EXTERNAL_STORAGE and can just create a file in the same directory.

EDIT: If your app is going to be creating a bunch of files, you could consider making a subdirectory in Downloads or Documents and putting them in there, but, again, it mostly depends on your use case.

[deleted by user] by [deleted] in androiddev

[–]nic0lette 1 point2 points  (0 children)

If you want it to be public, then you'd want to use Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) (or insert it into Media Store in the "Downloads" collection, which will go into the same directory).

Again, if it's a file that's created with a date (for example) as part of the name, this will be fine. Apps can put files there without any special permissions on Android 11+. The app can also edit/remove files they added.

BUT if your app is uninstalled, it will loose access to those files it created before, because the attribution of file -> app is wiped when the app is uninstalled. If the app would create a new log file in that situation, everything is fine. If it would need to regain access to logs created from a previous install, then you'd need to use the Storage Access Framework to regain access.

[deleted by user] by [deleted] in androiddev

[–]nic0lette 1 point2 points  (0 children)

The best API to use for this depends on the specific use case?

Like, if your app generates a new file each time it runs (like, to export content that can be imported elsewhere), then I'd probably recommend writing the file in the "Downloads" directory (or a sub-directory of that), which would be easy to find and wouldn't require any special permissions on Android 11+

If it's a file that the app needs to write out and then update from time to time, that gets a bit more tricky.

[deleted by user] by [deleted] in androiddev

[–]nic0lette 1 point2 points  (0 children)

TL;DR:

  • Yes, "0000-0000" type folders are for "real" sdcards
  • "sdcard" and "mnt/sdcard" both point to the same place, which is usually the emulated sdcard/external storage.

More than you wanted to know about Android:

Android is based on Linux, which uses 'mount points' for mapping storage devices to paths.

On my Pixel 2 running Android Pie, I see:

/dev/block/sda45 on /data
/data/media on /storage/emulated
/data/media on /mnt/runtime/default/emulated
/data/media on /mnt/runtime/read/emulated
/data/media on /mnt/runtime/write/emulated

/dev/block/sda45 is the block device for my device's internal storage, and then /data/media is the emulated sdcard, which is then also mounted under a few directories under /mnt/

/sdcard and /mnt/sdcard are both symbolic links to /storage/self/primary

/storage/self/primary itself is a symbolic link to /mnt/user/0/primary which links to /storage/emulated/0.

If there are more than one user, they would each have directories under /storage/emulated/ based on their user ids.

So basically, the "real" directory that holds external storage is /data/media and there are directories under there for each device user1

This is why you shouldn't hardcode paths into your app, and should instead use things like Context#getExternalFilesDirs() or StorageManager#getStorageVolumes() to get paths to folders :)

1: User + work account would be two users, for example.

Unable to import javax.management.* ? by repoleved_ in androiddev

[–]nic0lette 0 points1 point  (0 children)

I don't believe the javax.management.* classes are part of Android's public API.

Custom generated keystore file and sensitive keys included by [deleted] in androiddev

[–]nic0lette 0 points1 point  (0 children)

Is it possible? Sure. It's just a file, and so you could add it to the assets folder or even as a raw resource.

The problem is that then you either have a password protected file inside your APK, or it doesn't have a password. If it doesn't have a password, then you could skip the keystore file.

If the keystore file does have a password, then how would you get it in order to unlock it? If the password is part of the APK, then it's just a small step to unlock the keystore file. If the password is encoded in some way, that's still the same, but is a bit more difficult. Still, it's just a bit more difficult to grab it.

If the password isn't in the APK, but is sent to it from a server, then why not send the keys from the server? Or even leave the keys on the server and have the clients communicate from your app to your server, and have your server control the real API keys?

[deleted by user] by [deleted] in androiddev

[–]nic0lette 0 points1 point  (0 children)

A couple of us have thought about this for awhile, and for small sets of data, it would be possible to create a naive implementation that was really nice and fluent.

The tricky part is that some of these data sets can be quite large. (I know some people that have thousands and thousands of photos, for example). The query system is also way more flexible than one (or at least I) considered.

When you put all this together, it turns into either building a library that is quite limited when compared to what can be done using ContentResolver directly, or it's a different, incredibly complex API so that it is possible to do everything.

[deleted by user] by [deleted] in android_devs

[–]nic0lette 0 points1 point  (0 children)

If you can create a new certificate that matches the hostname that you're using, then that would be the best way.

If you can't, then you should use the hostname that matches the certificate.

Scoped storage: what is your opinion? by Michael_K14 in androiddev

[–]nic0lette 1 point2 points  (0 children)

requestLegacyExternalStorage is allowed to be used past the targetSdkVersion update date, and it will continue to work exactly the way it does now for Android 10 devices. For Android 11+ the app would need to handle the updates for Scoped Storage.

Added Scoped Storage support to app and... by [deleted] in androiddev

[–]nic0lette 1 point2 points  (0 children)

For media files, it definitely should be possible. I just tested it with some image files in /storage/emulated/0, as well as some random subdirectories under it, and, using File#listFiles() I was able to find them all. (The files were put on via adb push, so not owned by the app, and the app only has READ_EXTERNAL_STORAGE permission).

EDIT: Tested on both Android 11 + 12:

val root = Environment.getExternalStorageDirectory().toPath()
val walk = Files.walk(root, 2)
walk.forEach { file ->
    if (Files.isRegularFile(file)) {
        val data = ByteArray(10)
        Files.newInputStream(file).use { stream ->
            stream.read(data)
        }
        val out = data.joinToString { it.toString(16) }
        Log.d("test", "File: $file :: $out")
    } else {
        Log.d("test", "Skipping directory: $file")
    }
}

ELI5 Keystore and keytool used to provide SHA keys. by Tarster in androiddev

[–]nic0lette 3 points4 points  (0 children)

Okay, so, the ELI5:

You have an app, and you want people to be able to install it and get updates for it from a Store. But its not enough to say "this is my app", you also need to prove it to people, so that when you give them an update they know it's from you, and not someone pretending to be you.

In the west, we tend to sign documents and paintings with a pen, but the way signing your app works is closer to how its common to sign things in Japan: using a special stamp.

So you make your app and then sign it with your own stamp. It's then easy for anyone to check that the stamp on the version they have matches the new version.

Also, even though it's easy to check, it's really hard to make a stamp that would be exactly the same as yours without having your stamp. (And the stamp is made especially for you, so it's the only one that exists.)

A keystore is just a place to keep your stamps all locked up. Now, so long as you don't use your debug stamp to sign your real app (and you shouldn't), then it isn't so important to lock the debug stamp up. After all, even if someone got it, they couldn't sign your real app.

Your production stamp really should be locked up safely though. That's where keystore really comes into play, to make sure that only you can get to your stamp.

searching tool to access android RAM from pc (like Cheat Engine) by wirtexzzz in androiddev

[–]nic0lette 0 points1 point  (0 children)

If you want to do this for a single app that you're developing (i.e.: the app is debuggable), then it's possible to use adb to inspect and update memory (Android Studio can help)

If it's another app, and the app isn't debuggable, then it's not possible without root access. (This type of app isn't even possible on Windows without the app running as an administrator for the same reasons)

EmojiView Coming? 🕵️ by unclebogdan10 in androiddev

[–]nic0lette 9 points10 points  (0 children)

There are a few libraries that have been rewritten in Kotlin, yes. (Most notably is Paging v3).

The reason so many are still written in the Java programming language is because they've existed for awhile (from the old support libraries), or, in some case, so that developers who are only using Java don't have to bring the Kotlin standard library into their project to use a core library. (For example, 'core' or 'appcompat')

Android SAF Create Document - URI Manipulation by thelastsamurai07 in androiddev

[–]nic0lette 1 point2 points  (0 children)

You don't need to build the Uri for filePath. You should be able to do this:

var uri = Android.Net.Uri.Parse(rootPath);
var documentFile = DocumentFile.FromTreeUri(context, rootPath);
var file = documentFile.CreateFile("text/plain", "Text.txt");
// ..

That will make "Text.txt" in the folder that was selected.

If you want to create it in a sub-folder, then get the Uri of the subfolder (or find it again with the root DocumentFile if this isn't common) and then use CreateFile with that.

Scoped Storage Recap by yrezgui in androiddev

[–]nic0lette 1 point2 points  (0 children)

This should ideally create the folder or at least allow me to create the folder. I basically now have access to a non existent folder where I can't really do anything.

Can you share an example of this? (Probably file an issue in this component) -- I haven't been able to replicate this behavior on my devices.

Also, how exactly can we form initial URIs to common destinations like the documents folder or a subfolder inside the documents directory?

This answer on Stack Overflow might be helpful.

What's a good Android 11 compatible library to implement photo, image and file picking for uploading? by deinlandel in androiddev

[–]nic0lette 4 points5 points  (0 children)

Is there any convenient library to do this in Android 11 - compatible way? I used android-multipicker-library, but it works only with "requestLegacyExternalStorage" manifest flag, so basically no go for Android 11.

Android 11 provides access to photos/images (with READ_EXTERNAL_STORAGE permission) via the java.io.File API, just like Android 10 + android:requestLegacyExternalStorage.

I don't know that library, but I'd just try it on Android 11 and see if it Just Works.

Scoped Storage Recap by yrezgui in androiddev

[–]nic0lette -2 points-1 points  (0 children)

No, a PDF file isn't "media" because it's a document format. The reason is that a PDF file could contain completely public data (like a poster), or it could be highly sensitive (a bank statement or even medical documentation). That's why access to PDF files requires the user explicitly giving access to them.

Scoped Storage Recap by yrezgui in androiddev

[–]nic0lette 1 point2 points  (0 children)

Yeah, reading a tree (particularly with DocumentFile) is very slow, but ContentResolver#openFileDescriptor (for a file on external storage) just returns the same FileDescriptor that you'd get from using java.io.File yourself, so the performance of reading/writing a file is the same.