How To Cast Your Android Screen To Mac

I’ve been doing Android demo meetings for a while by pointing a webcam at a phone and hoping the automatic exposure doesn’t go wild half way through, always slightly envious of the iOS simulator that actually almost works, and the wide support for casting or airplay-ing an iPhone screen to your laptop / projector screen (which can then of course be shared very easily via Skype).

Ever since the “cast screen” settings appeared in Android 4.4 Kitkat I’ve thought that it must be possible to send your screen to a mac, but apparently that only works with a Chromecast, which of course my Mac is not, and nor can it pretend to be.

Well, this evening I have discovered the solution to my problem:

You’ll run into a problem if your phone isn’t Lollipop (or a rooted KitKat), but if that’s the case, maybe buy yourself a nice cheap Moto E for presentations, or get your boss to.

Update 25th August 2015: There’s also another way to this, over USB so it’s more reliable. Download the Vysor app in Chrome, and connect your device.

Android Design 2014: Dropping iOS Patterns

At the last GDG Brighton I spoke on the difference between designing for iOS and Android.

Here are the slides and a recording of the talk:

Android Design – Dropping iOS Patterns from Jason Fry

For those that remember, it’s an updated version of the talk I did a few years ago at Brighton Digital Festival.

Disable Chrome Back / Forward Gestures

If you’re on a Mac and have been finding that Chrome’s two finger back and forward gestures keep triggering at really inappropriate times (for years), you can disable them without disabling for every app on your Mac.

Just close Chrome, open up Terminal, copy the command below, and press enter!

defaults write com.google.Chrome AppleEnableSwipeNavigateWithScrolls -bool FALSE

Export Springpad to Plain Text

I used to use springpad.com to take notes on my iPad and Android phone, but ended up switching to just using plain text files, synced with Dropbox for speed and simplicity. However this left me with a few hundred notes tied into Springpad’s ecosystem that I wanted to suck out…

Thankfully Springpad lets you create backups (in settings->services) and download them as on big html file, which with a little magic can be converted into a series of plain text files, and with a little more magic can even be put into folders corresponding to the notebook they were stored in with Springpad!

But How!?

I’m glad you asked! I’ve written a litte ruby script which you can download from gist and run from the command line.

It only exports text notes and books, and there are sometimes some funky characters that invade notes that are rich text, but minor issues…

Dropbox Android Sync API Error: Dropbox isn’t initialized

Just got caught out by this little mistake for a few minutes. If you call the DbxAccountManager startLink method in your onCreate, onStart or onResume methods for your Activity then the your app will crash after you’ve authenticated.

Solution: Don’t try and link before the activity is fully running. See the Activity API reference for details about the activity lifecycle.

Update: Turns out this has nothing to do with when you start the authentication. After an email exchange with a developer at Dropbox (they contacted me!) we deduced that this was due to a low memory situation, and it just happened by chance that waiting until the activity had fully started fixed the issue. Apparently a fix will be coming for this in a future update…

Here’s the error from the logcat:

E/AndroidRuntime(23572): java.lang.RuntimeException: Unable to resume activity {your.namespace/com.dropbox.sync.android.DbxAuthActivity}: java.lang.IllegalStateException: Dropbox isn't initialized.
E/AndroidRuntime(23572):        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2567)
E/AndroidRuntime(23572):        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2595)
E/AndroidRuntime(23572):        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2109)
E/AndroidRuntime(23572):        at android.app.ActivityThread.access$600(ActivityThread.java:132)
E/AndroidRuntime(23572):        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1157)
E/AndroidRuntime(23572):        at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(23572):        at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(23572):        at android.app.ActivityThread.main(ActivityThread.java:4575)
E/AndroidRuntime(23572):        at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(23572):        at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(23572):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
E/AndroidRuntime(23572):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
E/AndroidRuntime(23572):        at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(23572): Caused by: java.lang.IllegalStateException: Dropbox isn't initialized.
E/AndroidRuntime(23572):        at com.dropbox.sync.android.DbxAccountManager.getInstance(DbxAccountManager.java:144)
E/AndroidRuntime(23572):        at com.dropbox.sync.android.DbxAuthActivity.finishAuth(DbxAuthActivity.java:72)
E/AndroidRuntime(23572):        at com.dropbox.sync.android.DbxAuthActivity.onResume(DbxAuthActivity.java:51)
E/AndroidRuntime(23572):        at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1154)
E/AndroidRuntime(23572):        at android.app.Activity.performResume(Activity.java:4539)
E/AndroidRuntime(23572):        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2557)
E/AndroidRuntime(23572):        ... 12 more