Category: Android App

READ_CONTACTS Permission Before and After Marshmallow

The READ_CONTACTS permission is required if you look up a contact (using the code below) on a pre-Marshmallow device (API 23). But, on Marshmallow or above, you don’t seem to need READ_CONTACTS even though READ_CONTACTS is a dangerous permission.

I don’t see why these two cases should be different.

In particular, if you launch the user’s contacts app with this:

val intent = Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI)
startActivityForResult(intent, RC_CONTACT_LOOKUP)

and then read the contact’s phone number with this in onActivityResult:

RC_CONTACT_LOOKUP -> if (resultCode == RESULT_OK) {
    lateinit var cursor: Cursor
    if (data != null) {
        try {
            cursor =  applicationContext.contentResolver.query(data.data,
                    null, null, null, null)
            cursor.moveToFirst()
            val column = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
            val phoneNumber = cursor.getString(column)
            contactButton.text = phoneNumber
            errorTextView.text = ""
        } catch (exception: Exception) {
            Log.e(tag, "Could not query column db", exception)
        } finally {
            cursor.close()
        }
    }
}

it won’t work in the pre-Marshmallow case unless you’ve required the READ_CONTACTS permission in the manifest. But, for the Marshmallow case, you don’t need to request it (which you would do, of course, at runtime on an as-needed basis because it’s Marshmallow).

Comment

Being a Good Android Citizen

From Previewing Android P:

In Android P we continue to refine Doze, App Standby, and Background Limits to further improve battery life; please be sure to try your apps with these and send feedback.

They don’t point to any specific improvements for Doze, App Standby and Background Limits. Maybe they didn’t quite reach their goals for these features. Or maybe developers and apps are not using these “good citizen” types of features enough to make the overall android experience better.

Comment

Flutter’s Hot Reload is Extremely Fast

Trying out Flutter’s “hot reload” feature, I have to say: it’s really fast.

Hot reload looks like a big step forward in productivity, even compared to conventional Android’s “Instant Run” feature.

Great job, Team Flutter.

Comment

To Change the Option Menu’s Text Color and Typeface, I Got Rid of the Whole Thing

For a Halloween mapping app I was working on recently, I wanted to change the color and typeface of items in the standard options menu.

After trying some obvious things, like experimenting with text/color/font related attributes on the ‘item’ tag and monkeying around with the app’s theme, I found that I do not know how to do this.

So, I looked at this, this, this, and this. But, I never quite managed to change both the color and the typeface on the individual menu items. (Maybe I could have created a custom class that merges the features of a ForegroundColorSpan and a TypefaceSpan and a SpannableString or something, but I ran out of patience.) It started to look like more work than I wanted to do. And I’m not a big fan of the options menu anyway.

So I gave up on the options menu and started to look for something else. Eventually, I found Nightonke’s Boom Menu. Compared to most free android libraries hosted on GitHub, Boom Menu is awesome. Changing the text color and typeface are EASY. And the documentation is solid.

It was easy to change a Boom Menu button’s text color and typeface. I read the doc pages. Then I was like, Boom:

TextInsideCircleButton.Builder builder = new TextInsideCircleButton.Builder();
builder.typeface(ResourcesCompat.getFont(this, R.font.my_custom_font));
builder.normalTextColor(R.color.colorAccent);

Thank you, Nightonke!

Comment

Looking Forward to Final Release of Android Studio 3

Over three months ago, when the android team first announced Android Studio 3 , I installed it alongside Android Studio 2. But, after I ran into some mysterious bad behaviors, I decided to uninstall both versions. That solved the problem. But, I ultimately decided to reinstall only version 2 and wait for the stable 3.0 release to do a complete transition. I figured it would hit RC status pretty fast.

Today I noticed that the android team has withdrawn the beta 3 version..

Due to an issues with the Android Plugin for Gradle in Beta 3 (64527520), we’ve pulled it down and recommend that you not accept the update. If you already did, you can go back to Beta 2 by downloading here.

It looks like they have fixed a recurring bug in the upcoming beta 4 version. Hope that’s out soon. Still looking forward to all the nifty new features.

Comment

Quick Notes On Dockter’s 2015 BABBQ Talk on the Android Gradle Build System

Hans Dockter gave a talk about the Android Gradle build system at Big Android BBQ 2015(No bbq for me … saw it on youtube … woo hoo) 

Dockter addresses the issue of Android build performance in the last half of the talk. A few of my takeaways, for what they’re worth:

  • Android developers should try an upgrade to Gradle 2.8
  • Build times are slow mostly because of dexing and pre-dexing. There’s nothing Gradle can do to improve dexing time, per se.
  • Right now, a clean build deletes your pre-dexed libraries. So, they must be re pre-dexed each time. But, in the future, there will be an optimization where pre-dexed versions of libraries necessary to your project are cached resiliently. So, even if you clean your project, their dexed versions persist.
  • Future improvements in the Android toolchain or Gradle for Android will include incremental dexing and concurrent dexing.

Dockter also mentioned the possibility of caching pre-dexed libraries on a CI Server so they’d be available to all developers in the organization. (Or something like that.)

I wonder if teams that use a third party, CI server in the cloud will also be able to take advantage of this sort of optimization. 

Comment

Why I Try Not to Implement Parcelable

The short answer is: Parcelable implementations are overly complicated and brittle,  I’m bad at finding and fixing “Unmarshalling unknown type code” errors and I’m tired of being surprised by them.

There are hundreds of questions about Parcelable errors on StackOverflow. I’ve had my fill of trying to implement solutions (e.g. proguard configuration adjustments, read/write out of order, etc) and then hoping that the errors stop happening.

If my app runs in a single process and I want to pass some arbitrary custom object to an Activity or Fragment, I’ll create a singleton and store the object as a property on that singleton. Then my Activity or Fragment can get that custom object by calling a “get” method on the singleton. (Of course, it’s important to keep that singleton from holding on to excessive amounts of memory.)

Anyway, the official documentation apparently says we should avoid using Parcelable unless we have to pass an object instance to another process.

And, even in that case, there are questions about the performance gains attributed to Parcelable as compared to Serializable. 

 

Comment

Android Percentage Based Layouts

It looks like Android is now offering percentage based spacing in a new layout object.

I believe Cascading Style Sheets had specified that feature by 1998.

Comment

Saving State in a Compound Control

If you’re writing an android compound control and you want to save state between config changes, you may want to tell the Android SDK to butt out.

That is, you may want your compound control to be fully in charge of saving and restoring the states of its internal views.

Why would you want to do that – why not just let the Android SDK save and restore those interior view states?

Because in order to correctly save the states of those interior views, the Android SDK needs each of them to have unique ids.

And when does that become problematic?

When a client of your compound control puts multiple instances of it into a single one of their layouts. In this case, the interior views will all get the same ids or no ids at all. (Unless you want to deal with a certain amount of awkwardness in code.)

So, if, for example, your compound control consists of a LinearLayout which wraps some other stock views, it can be desirable for your LinearLayout to tell Android to simply avoid saving the states of those interior views. You can do this by calling dispatchFreezeSelfOnly and dispatchThawSelfOnly.

A helpful example of this is Charles Harley’s Lock Combination Picker on GitHub.

A discussion about how BaseSavedState should be used to save the state of your compound view is found in this StackOverflow question.

Comment

TextView Plus SeekBar

One way to couple a dynamically updating TextView with a SeekBar is to use a TextSeekBar.

Comment