"android" entries

Four short links: 9 October 2013

Four short links: 9 October 2013

Android Malware Numbers, Open Networking Hardware, Winning with Data, and DIY Pollution Sensor

  1. Android Malware Numbers — (Quartz) less than an estimated 0.001% of app installations on Android are able to evade the system’s multi-layered defenses and cause harm to users, based on Google’s analysis of 1.5B downloads and installs.
  2. Facebook Operations Chief Reveals Open Networking Plan — long interview about OCP’s network project. The specification that we are working on is essentially a switch that behaves like compute. It starts up, it has a BIOS environment to do its diagnostics and testing, and then it will look for an executable and go find an operating system. You point it to an operating system and that tells it how it will behave and what it is going to run. In that model, you can run traditional network operating systems, or you can run Linux-style implementations, you can run OpenFlow if you want. And on top of that, you can build your protocol sets and applications.
  3. How Red Bull Dominates F1 (Quartz) — answer: data, and lots of it.
  4. Ground-Level Air Pollution Sensor (Make) — neat sensor project from Make.

Upward Mobility: Dear Apple, Please Stop Hogging All the Good Stuff

Forget Touch ID, we're still waiting for access to Siri!

As I mentioned last week, the new Touch ID feature of the iPhone 5S is (at least for the moment) only usable by Apple created software. What this means is that a developer can’t take advantage of the feature to authenticate a user inside an application, it can only be used to unlock the phone and authenticate to iTunes.

This continues a troubling trend we’ve seen with Apple lately. Nearly two years after the release of Siri, the voice UI is still locked out for anyone but Apple and their chosen partners (such as Wolfram Alpha.) I understand that opening up a technology for third party usage takes planning and work, but twice in a row now, Apple has released what could be a transformative technology, and left the developer community out of the picture.

Read more…

Four short links: 27 August 2013

Four short links: 27 August 2013

Web Broken, Android Ads, Password Cracking, and Adobe Brackets

  1. Bomb in the Garden (Matthew Butterick) — de­sign ex­cel­lence is in­hib­it­ed by two struc­tur­al flaws in the web. First flaw: the web is good at mak­ing in­for­ma­tion free, but ter­ri­ble at mak­ing it ex­pen­sive. So the web has had to rely large­ly on an ad­ver­tis­ing econ­o­my, which is weak­en­ing un­der the strain. Second flaw: the process of adopt­ing and en­forc­ing web stan­dards, as led by the W3C, is hope­less­ly bro­ken. (via Alex Dong)
  2. Google’s New Play Store Policies on Ads (The Next Web) — the walls of civilisation holding back the hordes of assclowns. Imagine the behaviour responsible for each of these restrictions.
  3. Inside Password Cracking (Wired) — how pros go about cracking your password once they have the encrypted hash. (And gosh, how those “but I used numbers and symbols!” passwords fall)
  4. Brackets (Github) — open source web code editor by Adobe.

The Ever-Changing Landscape of Mobile Gaming

Unity, iOS 7, and the Quest for a Great Mobile Game Experience

Jon Manning (@desplesda) and Paris Buttfield-Addison (@parisba) talk with me about where mobile gaming is going in the next 12 months.

Key highlights include:

  • Game-specific APIs and standardized gaming accessories in iOS 7 [Discussed at 0:20]
  • Android needs to catch up [Discussed at 1:55]
  • Are tablets putting handheld consoles from Nintendo and Sony out of business? [Discussed at 3:13]
  • Independent developers vs big game studios – fight! [Discussed at 4:53]
  • Unity is now free for mobile game development [Discussed at 6:02]

You can view the full interview here:

Read more…

Upward Mobility: Android for iOS Developers, Part 4

Sensors indicate activity on the planet's surface, captain!

Our mini-Encyclopedia Galactica can do a few things now, but it’s hardly ready to offer up the recipe for a Pan-Galactic Gargle Blaster yet. If we want to take things to the next level (or at least the next screen), we need to learn how to move between Activities.

Moving between Activities is the Android equivalent of switching between view controllers, but more formalized. In some ways, it’s very similar to the storyboard and segue metaphor introduced in iOS6. To begin with, we need to create a new Activity in ADT, using the File->New->Other menu pick, and then choosing Android Activity from the choices under Android. I chose to name mine DetailActivity, and place it hierarchically under the MainActivity. By doing this, the back button will return me to the original Activity when I hit it.

Screen Shot 2013-07-01 at 10.51.56 PM

Using the blank template, I then added a large TextView at the top, an ImageView, and another TextView set to 10 lines of smaller text at the bottom.

Screen Shot 2013-07-02 at 12.33.29 AMNow we need to teach the MainActivity to navigate to this new page. I added a Button to the MainActivity layout, and then wired a listener up to it in the code in the onCreate method:

final Button button = (Button) findViewById(R.id.moreInfo);
     button.setOnClickListener(new View.OnClickListener() {
         public void onClick(View v) {
        	 Intent a = 
                     new Intent(getApplicationContext(),DetailActivity.class);
        	 a.putExtra("PLANET_NAME", (String) spinner.getSelectedItem());
             a.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
             startActivity(a);
         }
     });

The mechanism that you use to transition between Activities is called an Intent. You create an Intent with the application context and the class of the Activity you wish to navigate to. Notice that unlike iOS, you don’t actually instantiate the new view you’re going to, so there’s no way to pre-populate values in the next view. So how do you pass in values? You stick them on the Intent, using the putExtra method. In this case, we put the planet name into the Intent, so that the detail page will know which planet to display.

One of the big gotchas with passing data via Intents is that you can’t just throw any old object onto it. Because of the Android architecture, it either has to be a simple object like a String, a primitive, or something that implements Serializable. You can also put Bundles or Parcels onto it.
Read more…

Location Functionality in Mobile Apps

OSCON 2013 Speaker Series

Andy Gup (@agup) is a Developer Evangelist at ESRI and OSCON 2013 Speaker. In this interview we talk about location capabilities in apps as well as location analytics.

NOTE: If you are interested in attending OSCON to check out Andy’s talk or the many other cool sessions, click over to the OSCON website where you can use the discount code OS13PROG to get 20% your registration fee.

Key highlights include:

  • Mobile apps must have location capabilities [Discussed at 0:25]
  • Consider your goals when incorporating location into an app [Discussed at 1:05]
  • Is it difficult to add location functionality? [Discussed at 2:19]
  • A real-world example of where it made a big difference [Discussed at 3:32]
  • Location analytics are very powerful [Discussed at 5:11]
  • Augmented reality and location capabilities [Discussed at 6:38]

You can view the full interview here:

Read more…

Upward Mobility: Android for iOS Developers, Part 3

Handling Input Events

Now that our Android app lets you choose what planet you’re on, we should use that information to update our “Hello, world” message based on the selection. To do that, we’re going to need to handle the selection event on the spinner we created.

To do this, we need to set the setOnItemSelectedListener property on our spinner to something that implements the OnItemSelectedListener interface. The simplest way to do this is to implement it in our activity.

public class MainActivity extends Activity 
                               implements OnItemSelectedListener {
.
.
.
boolean spinnerActive = false;

public void onItemSelected(AdapterView<?> parent, View view, 
            int pos, long id) {
    	if (!this.spinnerActive) {
    		spinnerActive = true;
    		return;
    	}
    	TextView message = (TextView)findViewById(R.id.textView1);
    	String planet = (String) parent.getItemAtPosition(pos);
    	if (planet.equalsIgnoreCase("pern")) {
    		message.setText("Hello, Lessa");
    	}
    	if (planet.equalsIgnoreCase("barsoom")) {
    		message.setText("Hello, John Carter");
    	}
    	if (planet.equalsIgnoreCase("equestria")) {
    		message.setText("Hello, Twilight Sparkle");
    	}
    	if (planet.equalsIgnoreCase("ringworld")) {
    		message.setText("Hello, Louis Wu");
    	}
    }

    public void onNothingSelected(AdapterView<?> parent) {
    	TextView message = (TextView)findViewById(R.id.textView1);
    	message.setText("Hello, World");
    }

This is pretty straight-forward stuff. You use the parent.getItemAtPosition call (where parent is the spinner) to get the item that you selected. The item is just the string value of the selection, so we can use a simple string compare to select the appropriate message. In the same way that we got the spinner using it’s id, we can get a handle on the text view at the top of the screen, and then set the message using setText.

There are a couple of things to point out here, however. For one, the onItemSelected message gets called when the widget is created, a fact that irritates the heck out of Android developers. This means that you need to ignore the first call to the method. Thus, the purpose of the spinnerActive flag. Secondly, because we’re using the Activity as the listener, you could end up with problems if you have multiple spinners on the screen, since they would all call the same listener. You could either use the AdapterView value to determine which spinner fired the event, or use private inner classes to handle the various spinners.

Now that we’ve got our listeners implements, the last step is to tell the spinner to use the Activity as the handler.

    protected void onCreate(Bundle savedInstanceState) {
.
.
. 
     spinner.setOnItemSelectedListener(this);
    }

Now when we fire up the app and select a value from the spinner, we get a personalized welcome message!

Screen Shot 2013-06-21 at 6.13.45 AM

Upward Mobility: Android for iOS Developers, Part 2

Turning Hello World into something useful

When we last left our application, it was running on the emulator, but didn’t do much.  This week, we’ll add some more controls to our activity and wire up some functionality.

As a reminder, activities are roughly equivalent to view controllers in iOS. Right now, there’s not much in our activity, because all we have is a single label in our activity. As iOS developers, we’re used to never looking at our XIB files in the raw, because they’re pretty much human-unreadable. By contrast Android layout files (which end up in the res/layout folder in a standard Eclipse project) are both readable and intended to be edited. At the moment, here’s what ours looks like:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</RelativeLayout>

Read more…

Upward Mobility: Android for iOS Developers, Part 1

Welcome to the dark side: we have cookies

Like many hardcore iOS developers, I’ve eschewed learning “the other platform” because I was happy in Apple-land. In addition, the few forays I’ve made into Android development seem to show that it was a more complex and difficult platform to work with. However, recent developments (e.g., a new job) have placed me in a position where I’m going to need to have at least a casual familiarity with Android development, so I thought I’d bring you all along on my journey.

Getting the Development Environment Set Up on OS X

The good news is that, unlike iOS, Android is a development-platform agnostic OS. If you go to the Android developers site on a Mac, you’re going to be immediately presented with the option to download a zip file with the complete Android Developer Tools package. Fair warning that it’s pretty large, nearly 400MB. Of course, for folks used to downloading multi-gigabyte XCode drops, that may seem pretty reasonable.

Once it’s downloaded, unzip the file and move the resultant adt-bundle-mac folder into somewhere permanent. The install documentation recommends the /Developer folder, but since /Developer has been deprecated lately, you might want to just create a top level /Android folder instead.)

# sudo mkdir /Android
# sudo mv adt-bundle-mac-x86_64-20130522 /Android/
# cd /Android/adt-bundle-mac-x86_64-20130522/eclipse/
# mv Eclipse.app ADT-Eclipse.app

One additional step I took was to rename the version of Eclipse that ships with ADT to ADT-Eclipse. I already have a version of Eclipse that I use for general Java development, and I don’t want to launch the wrong one from Spotlight accidentally.

Once you’ve finished installing ADT, you can launch their version of Eclipse from Spotlight and, just like every other version of Eclipse, the first thing you’ll be asked is where you want to create your workspace. Just as with the renaming of the Eclipse application, I gave my workspace a unique Android-y name, and told Eclipse not to ask me again. This should prevent me from accidentally opening my normal Java development workspace.

Writing Your First App

Once Eclipse launches, it’s going to ask you if you want to send anonymous statistics to Google. This is a choice between you, your maker, and the NSA, so choose whatever makes you feel happy. The next thing that you’ll be presented with is a welcome popup, with the option to either create a new Android app, or run through some basic tutorials.

The tutorials aren’t actually built into the ADT. Instead, clicking on one of the links will bring you to a web page with a walkthrough. There’s not a lot of value in having me take you through a tutorial that’s already been written in detail, so I’ll hit the high points.

To start, create a new Android project. If you still have the welcome screen up, you can do that by clicking on the New Android Application... button. Otherwise, you can get to it from the File->New->Android Application Project toolbar item. You’ll immediately be presented with the New Android Application dialog.

The Android New Project Screen

The Android New Project Screen

There are a couple of important decisions you need to make here. The first is the package name for the project. This is equivalent to the bundle identifier in iOS development, and it needs to be unique. Luckily, iOS chose to adopt a Java-like reversed domain-name structure for bundle identifiers, so you should already be familiar with this concept.

The other big decision is the minimum version of the SDK that you will support. In iOS, we’re used to dropping support for old versions of iOS on a regular basis. Most iOS developers don’t support iOS4 anymore, and it’s not uncommon to see iOS6 as the required version for newer apps. This is because Apple has been very aggressive about carrying forward devices to new versions of the operating system; about the only things left behind by iOS6 were the original iPad and some iPod touch models.

By contrast, most Android users are at the mercy of their carriers for OS upgrades, and the story isn’t pretty. If you check Google’s own adoption stats, nearly half of all Android users are still stuck back on Gingerbread, a release now more than two years old. And, in fact, the wizard recommends you go back even further, to Froyo.

Does this mean that you can’t take advantage of the latest and greatest features in Android, and still deploy an app that the majority of users can run? No, but it does mean that you’re going to have to fail gracefully when new features aren’t available. iOS developers have had to occasionally do this in the past. For example, when new callback methods were delivered in iOS6, we had to keep both versions around to make iOS5 work. But the long, long version tail of Android means that you will have to take this practice to the next level.
Read more…

Four Simple Rules to Avoid DisplayMetrics Antipatterns in Android Code

Effectively combine characteristics and qualifiers for optimum layouts

The DisplayMetrics Red Flag

A search of GitHub returns more than 42,000 hits for the class name DisplayMetrics. This is a red flag. Although there are safe and valuable uses for this information, a quick look at the code using this class reveals that most programs query it to determine screen dimensions, using code like this:

DisplayMetrics displaymetrics = new DisplayMetrics();
        ((WindowManager)context.getSystemService("window")).getDefaultDisplay().getMetrics(displaymetrics);
        int i = Math.max(displaymetrics.heightPixels, displaymetrics.widthPixels);
        sScreenNailSize = i / 2;
        sThumbNailSize = i / 5;

The programs then make decisions about how the program should present its user interface. This is dangerous, because it tempts the programmer to make decisions with awful long-range consequences, when these decisions should be left up to the Android run-time.

How to Break Lots of Apps in One Easy Step

How dangerous is it? Pull up a random app on your Android device, go to the Settings and select Font Size, then select Huge.

Now see how many apps break:

  • How many have fixed-size views in their layouts where text overflows its bounds?
  • How many “fixed” that bug by setting the font size, and ignoring your preferences?
  • How many make incorrect layout decisions where objects don’t quite fit?
  • How many lock the app’s UI to a landscape or portrait orientation?

When you make your own decisions, based on screen dimension and other parameters, about how to present the user interface, you enter a danger zone that spawns bugs that can easily escape detection in both automated and manual testing. If bugs are caught late in the game, they create pressure to implement lame fixes.

The Only Way To Win Is Not To Play the Game

Aren’t you forced to make decisions about presentation? The answer is “No.” You should not be asking “How high, how wide, how dense, what font,” etc.

You should let Android ask the questions and make decisions about presentation. The only question, then, is how many answers you need to provide. Using multiple layouts for different configurations, and avoiding fixed values in layouts, you can make a system of layouts and let Android choose which layouts to use for different screen sizes and orientations.

Read more…