• Breaking News

    [Android][timeline][#f39c12]

    Tuesday, November 3, 2020

    Jetpack Compose on Desktop is in preview! Android Dev

    Jetpack Compose on Desktop is in preview! Android Dev


    Jetpack Compose on Desktop is in preview!

    Posted: 03 Nov 2020 04:57 AM PST

    Android 11 dodges a bullet - apps creating a folder at top level maybe able to simply move that to Music/Photos "shared storage" folder (requiring single line change in java) - without needing to resort to complications of SAF

    Posted: 02 Nov 2020 10:18 PM PST

    EDIT: what is described below applies not only for File API for java - but also for your C code i.e. apps using JNI/NDK native C libraries (if you are doing fopen(), and other standard file io). I say this because our tests included native file io using C as well.

    Summary

    Google is moving to restrict android storage. They had initially telegraphed a much stronger change that would have broken android. For Android 11 someone at Google seems to have convinced the others that retaining file paths and fopen() is essential (this was something we have been harping about for ages on reddit - as absence of file paths and fopen() spelled the death of standard storage).

    Here I provide a quick overview of the storage changes, and advice for migrating for app developers who do not want to spend time on storage migration. Specifically developers who have no interest in spending time on Storage Access Framework (SAF) - the flawed and inefficient "alternative" that Google tried to push devs to adopt (much like they pushed SAF as the alternative when they killed seamless ext SD card access in KitKat).

    Many apps just need ability to save files to a location that will be persistent (not go away once app is uninstalled). This is the case for apps like audio recorders, camera apps and such.

    That is now possible with something as little as a one line change to your code for Android 11.

    The end result will be that you will not need to change your app's file handling (except one or two lines of java code). The simplest of apps (like audio recorder apps) will only need to change one line, and keep behaving much as before.

     

    Backstory

    As discussed here before, Google has been on a march to kill traditional storage on Android.

    Just as Google killed seamless external SD access with KitKat (and later providing an inadequate replacement - SAF - which expectedly never took off, leading to the demise of seamless ext SD card storage) - similarly Google had announced a flurry of changes for storage. These changes are expected to make persistent storage as before harder to do. Because the only way to continue using old storage code was to use the app-specific folders (which are removed when app is uninstalled). This would have left cloud storage as an attractive alternative (to mirror the app-specific folders) - with few other easy options for storage persistence.

    Use of SAF is non-trivial for devs, and it comes with it's own set of caveats and performance limitations. In addition, there was earlier a shadow over use of SAF as well (whether one would need Google Permissions Declaration Form for this as well - since SAF does allow writing in many more places and currently is used to routinely grant top folder access). Now for Android 11, Google medium.com post has clarified that SAF does not require special permission from Google - and Google themselves will limit SAF so it cannot access the top level folder, and some other folders (this means those devs using SAF will need to check user flows to ensure their SAF use works under new restrictions).

     

    Android 11 solution

    Android 11 arrives with changes:

    • file paths can be used as before and File API - for a few specific folders (Music, Photos .. i.e. the so-called "shared storage" folders).

    • fopen(), delete, instantaneous move of files - can be done (again for a few specific folder locations)

    • these capabilities were not available in Android 10

    In practice this means an app could choose to no longer house it's app folder (where it stores persistent audio recordings etc.) at the top level folder on internal storage - but instead locate it in the Music folder (which is one of the "shared storage" folders).

    If your app saves files in a folder "folder1" (that was previously located at top folder) - that "folder1" now can be saved in the Music folder.

    Just change this line in your code - where you discover the parent directory where "folder1" should be stored:

    File sdcardRoot = Environment.getExternalStorageDirectory();

    to:

    File sdcardRoot = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);

    And similarly for Photos etc. For Downloads there is some additional restriction (apps cannot see files created by other apps). While for Music/Photos etc. apps CAN see files (read-only) created by other apps (as long as you keep using the READ_EXTERNAL_STORAGE permission in AndroidManifest.xml.

    Now your "folder1" will be located in Music/folder1, but you can continue to use the rest of your code as before. Manipulating file path strings etc. ..

     

    Android 11 caveats

    The only caveat or restriction is:

    • if you use the Music folder, you can only create "audio" files there (.wav, .ogg, .mp3 and perhaps others). If you need to create a dummy file "dummy", you can create it, but you will have to name it "dummy.mp3" etc. i.e. with an audio-like extension.

    • you can create folders within the Music folder - example: Music/folder1

    • two apps can use the same folder i.e. app1 creates folder1 and app2 also creates folder1. One app can delete the folder created by another app (if folder is empty). Files created by app1 can be read by app2 (if it uses the READ_EXTERNAL_STORAGE permission), but cannot be written or deleted by app2. This means if you delete folder1 from app1, it will delete all the app1-created files in folder1, but will leave the files created by app2 there untouched (and so folder1 will not be deleted). But if Music/folder1 was created by app1, it can be deleted by app2 (if the folder1 is empty or only contains files created by app2).

     

    Android 10 and earlier

    Since Android 10 was missing these file path and fopen() capabilities, that means it will cause problems if you don't use "requestLegacyExternalStorage=true" in your AndroidManifest.xml.

    This is why Google also recommends that apps use this flag in your AndroidManifest.xml:

    requestLegacyExternalStorage="true"

    This will allow their app to perform the same as before all through to Android 10. And somewhat so on Android 11 as well (as long as app is targeting below Android 11).

    Once your app starts targeting Android 11, this "requestLegacyExternalStorage" will be ignored.

    This means once you start targeting Android 11 (targetSdkVersion=30) your app should be using "Music/folder1" etc. instead of "folder1".

    Thus, the app developer HAS to ship his app for Android 10 using the "requestLegacyExternalStorage" flag set to TRUE (to opt out of the new storage changes) - if they want to not change their app code.

    If you don't use this for Android 10, then your app will be subject to Android 10 rules, and because Android 10 did not have file path and fopen() support, you will not be able to introduce the "Music/folder1" way of doing things.

    So keep using "requestLegacyExternalStorage" while you targetSdkVersion=29 (Android 10).

    Once you targetSdkVersion=30 (Android 11), the "requestLegacyExternalStorage" is ignored, and your app should be ready to use "Music/folder1" etc. So you should have a behavior in place so files are stored in the Music folder or Photos folder (one of the "shared storage" folders) instead of at top level folder of internal storage.

     

    How to adapt to new restrictions

    Google has announced that Android 11 will now again support File API and fopen() type methods (Android 10 did not - i.e. if you were targeting Android 10).

    The only restriction in Android 11 is that these capabilities can only be used for files and folders that are stored within Music, Photos etc. - the so-called "shared storage" folders.

    This means all you have to do is ensure the folder where you saved audio recorder files (usually a folder at top level of internal storage), can now be saved within the Music folder on internal storage:

    change:

    File sdcardRoot = Environment.getExternalStorageDirectory();

    to:

    File sdcardRoot = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);

    And make sure you are using this in your AndroidManifest.xml (as Google recommends, this is to cover for the aberration that was Android 10 which does not support file paths and fopen() - Android 11 will ignore this flag):

    requestLegacyExternalStorage="true"

     

    Eveything else can be kept as before - you can:

    • create a folder within this Music folder (just as you created a folder at top level on internal storage)

    • you can manpipulate the path, create a path for a sub-directory by appending to the file path

    • you can create a folder, and create files there

    • basically nearly all your old java code and NDK/JNI native C code will work as before - use fopen() using file path strings, manipulate path strings etc. (just make sure the paths you want to reference are within the Music folder)

     

    What you cannot do:

    • you can only create audio files (more precisely files that have extension that indicate it is a file like .wav, .ogg, .mp3 etc.) within the Music folder (similar restrictions may apply to Photos).

    • evidently the file extension is the only thing used to screen - so you can create a file holding arbitrary data - just ensure it is named file.mp3 etc. (standard music file extensions)

    • if you try to create a file that does not have an audio extension, or another type of extension, it will fail

     

    Some other different behaviors:

    • two apps can write to the same folder

    • so you can have two of your apps write to the same folder (within Music for example)

    • a folder created by app1 can be deleted by another app2 (if it is empty)

    • a file created by app1 cannot be deleted by another app2

    • this means app2 cannot delete a folder that contains a file created by app1

    • a file created by app1 CAN be read by app2 (if app2 uses the READ_EXTERNAL_STORAGE permission in it's AndroidManifest.xml)

     

    Thanks

    Thanks to /u/oneday111 for outlining the possibilities - which led to testing app behavior when the app folder is simply relocated to Music folder etc.

     

    NOTE TO MANUFACTURERS

    Please ensure your devices running Android 11 use the source tree with the latest changes for Android 11.

    Because (as has happened before) - manufacturers sometimes choose an earlier Beta as their starting point (which can sometimes miss the final behaviors promised).

    So manufacturers, please don't mess up by failing to comply with this file path and fopen() behavior in Android 11 - since this is an essential feature of Android. If you fail to ensure this is supported in your Android 11 version, a huge number of apps will break.

    I say this because the storage nuances seem to have been changing a lot in the last few months - so it is possible that a manufacturer picks up a Beta version as their starting point - but which fails to have the final behaviors now promised for storage in Android 11.

    submitted by /u/stereomatch
    [link] [comments]

    I wrote a blog post about solving coding problems with Kotlin. It's not exactly about Android, but I hope it will help you to understand some features of Kotlin a bit more.

    Posted: 03 Nov 2020 12:46 PM PST

    I'm an Android developer, but I used to solve coding problems on Leetcode with Java, but recently I have switched to Kotlin. I learned something during this process and decided to share it with you. It might be not about Android, but having those things in mind when writing Android code might be helpful.

    https://proandroiddev.com/solving-coding-problems-with-kotlin-collection-functions-3d2b1ef7fe2c

    Do you practice solving coding problems on Leetcode, Codeforces or maybe you participate in JetBrains' Kotlin Heroes programming contest?

    submitted by /u/OrangeRedAndRed
    [link] [comments]

    Semantics and TalkBack with Jetpack Compose · Bryan Herbst

    Posted: 03 Nov 2020 10:50 AM PST

    Is there anyone on the play store who doesn't use fake reviews?

    Posted: 03 Nov 2020 11:14 AM PST

    After uploading my app I got offers for 5-star reviews and downloads for a price. I then got an offer of a service which you can use to get hundreds of 5-star reviews for free.

    As if that "ASO" crap wasn't bad enough where amazing console quality games get less than a thousand downloads while games called "Call of Battlefield Sniper 3d FPS great graphic" that look like they were made in 2 minutes get 10 million downloads each.

    submitted by /u/BoozeBumAddict
    [link] [comments]

    Play Console: Way to see source of third-party referrals?

    Posted: 03 Nov 2020 03:48 AM PST

    I have a small app, published on the Play Store, that is jugging along at a steady pace of about 200 downloads a day. However, a couple of weeks ago, I got two big spikes on specific days with thousands of downloads.

    Looking at the statistics, I can see that these spikes came from one country and almost exclusively through third-party referrals. So someone must have posted something about this app online.

    Is there a way to find the source of the referrals in the Play Console? I've tried googling for mentions from only that country and only in the past month, but have had no luck.

    Thanks for any ideas :)

    submitted by /u/schwerbherb
    [link] [comments]

    Best way to wake up a device remotely

    Posted: 03 Nov 2020 08:46 AM PST

    Scenario:

    device1 sets some values

    device2 (which could be under Doze) wakes up and performs some operations in the background

    What's the best and most effective way to achieve this?

    Is Firebase Cloud Messaging a viable option?

    submitted by /u/iClaude10x
    [link] [comments]

    Versioning Android apps

    Posted: 03 Nov 2020 04:41 AM PST

    How can I download a Video from S3 amazon?

    Posted: 03 Nov 2020 07:33 AM PST

    Returning to android dev after 2 years, feeling kinda lost with so many new libraries and methodologies

    Posted: 03 Nov 2020 06:47 AM PST

    It feels like all of a sudden everyone has moved on to making apps with dozens of modules, navigation components, coroutines, viewmodels, lifecycle something, architecture components and what not.

    I'm not sure where to start and I feel like the old methods are hopelessly outdated so much so that I'm afraid to push code that a dev with newer knowledge might see.

    I know constantly learning is part of this industry, but I would love some advice on where to start (e.g. which new libraries can easily fit into older ways of android dev and expand gradually).

    Does your stack include these recent changes to the stack? How much of this is "medium articles/online hype"? If you had to start from scratch, what would you stack look like today?

    Just want to get back up to speed quickly :)

    submitted by /u/calipso_athena
    [link] [comments]

    How do I make a cardview scrollable?

    Posted: 03 Nov 2020 06:38 AM PST

    What is proper method for loading admob banner ads with MVVM architecture?

    Posted: 03 Nov 2020 06:25 AM PST

    I am trying to load banner ads with mvvm. Can i load banner ads from viewmodel? Would that cause memort leak? Or loading banner from activity suitable for MVVM architecture?

    submitted by /u/socialhub96
    [link] [comments]

    Multitasking: Float windows over other apps on Android

    Posted: 03 Nov 2020 05:54 AM PST

    Changes to subscriptions

    Posted: 03 Nov 2020 05:49 AM PST

    I recently (a couple of months) introduced subscriptions on my apps, then shortly after I got the email about new changes to subscriptions.

    According to the Play Console ` You must have account hold and restore implemented in your app by November 1, 2020. Subscription pause and resubscribe will also be enabled by default, unless you explicitly opt out. `

    I read the documentation and I'm not sure what I have to do on my app to support this.

    Currently when a user is subscribed I show a button that takes you to `Your Subscriptions` on the Google Play App, so they can manage the subscription there.

    It's already past Nov 1st and I didn't get any notification about my app. Is this functionality enough?

    Thanks

    submitted by /u/benexus
    [link] [comments]

    Automate Dependencies Upgrades With Releases Hub

    Posted: 03 Nov 2020 02:49 AM PST

    Automatically keep your Gradle project dependencies up to date.

    The Releases Hub Gradle Plugin helps developers to keep their dependencies up to date, reducing some tedious manual tasks like remembering to look for dependencies upgrades, upgrading the dependencies on the Gradle configuration and creating a PR with the changes.

    https://medium.com/swlh/automate-dependencies-upgrades-with-releases-hub-8eac6d7f43d6

    submitted by /u/maxirosson
    [link] [comments]

    What do you think about MVI Architecture on Android?

    Posted: 03 Nov 2020 01:51 AM PST

    Is it possible to write a gradle task to clean project when I switch git branch ??

    Posted: 03 Nov 2020 12:15 AM PST

    getting sqlite data off phone from dev testing?

    Posted: 02 Nov 2020 09:22 PM PST

    Hi folks, my little app is for a grad school cognition experiment, and so I'd like to start collecting data as soon as possible, even while finishing the app. I'm wondering whether it's possible for me to start logging answers a sqlite db and start using it on real phone, downloading the db occasionally. (before I make a proper export function I mean). Any suggestions for that kind of thing most appreciated!

    iain

    submitted by /u/tremendous-machine
    [link] [comments]

    I have a Question.

    Posted: 02 Nov 2020 08:36 PM PST

    I want to make a computer state check application. So, I am used to "Runtune.getRuntime.exec("ping -c 1 -w 100 (IP ADDRESS))." (Android Application -> Ping Commend -> Computer) But, It isn't working. How to make a computer state check application?

    submitted by /u/GDevlop
    [link] [comments]

    No comments:

    Post a Comment

    Fashion

    Beauty

    Travel