Monday, September 5, 2011

Android Market Horror Story

As a registered Android developer with a published application on the Android Market, I'm becoming more amazed each day by how bad the Android Market team is supporting their developers.

The relationship between developers and the Android Market has never been good, caused to a large degree by the many bugs and issues developers are facing on that Android Market.

The reason for me writing this post was something that happened a couple of days ago on the Android Market. Have a look at the video below to see what happens when users try to search for my application :


A couple of days before, a fellow developer contacted me that his sales dropped to almost zero since the new Android Market was released. When I went on the Market to search for his app, I noticed the following:



It's not only end users who are facing serious issues in finding, downloading and purchasing applications, but developers are having a very difficult time in getting any kind of support from Google for the many issues they are facing.

One should not forget that Google is taking 30% of all sales. Something that they are entitled to, and something I don't have any issue with whatsoever, but on the other hand, developers should expect some level of quality and support coming from the Android Market when working in such a model.

A couple of weeks ago, Google has decided to close the Market Technical Forum for developers, making it an end-user forum only. To quote Google, "Because of the nature of developer issues, we feel that one-on-one support is best for the types of threads that have historically been posted to this forum by app developers."

The Android Market forum was a place where developers could interact with each other on market specific issues, however, it seemed Google noticed that the forum was full of frustrated developers, making the Market look bad. Every once in a while, external sites like The Register started picking up stories from the forum, like when developers were not getting paid for a part of their app sales.

Every once in awhile a Google employee posted something on the forum, mostly to state that they are looking into the issue.No due dates, no updates, effectively leaving developers all alone to rant about the various issues they are having.

A forum might indeed not be the best way to deal with issues, but obviously a one-on-one support model also does not work in its current form. Either their support team is heavily under-staffed, or issues are given very low priority. I have the impression that Google is trying to hide these issues from the public instead of actually put effort in resolving them properly.

Like me, many developers have logged tickets via email and don't get any response beyond "look at the known issues page", or worse, no response at all. This seems very strange for a service that is taking 30% of your profits. I wonder what kind of support big companies are getting when it comes to getting their issues resolved.

Clearly, there is a need for support giving the many (sometimes serious) issues users and developers are facing with the Android Market. Just have a look at the known issues pages for both users and developers.
The issues that stand out for me, that have been open for a long time, and are hurting independent developers are listed below.

It's about time Google starts taking the Android Market seriously, but putting in place a decent support model, staffing the team appropriately and really start looking into resolving these issues. If not, I'm convinced that many developers will steer away from Android as a development platform.

Saturday, August 6, 2011

Google Latitude API and OAuth 2.0

Introduction

In this article, I'm going to discuss OAuth 2.0 and the Latitude API. A couple of days ago, OAuth 2.0 support was announced for the Latitude API, and I figured it might be a good idea to take a more in-depth look on how OAuth 2.0 can be used with the Latitude API and how the
Google APIs Client Library for Java implemented the Oauth 2.0 spec.

The article is accompanied by a sample application on Github. It's heavily inspired by existing samples for Google APIs Client Library for Java. In order to run the sample, clone the Git repo, import the project in Eclipse, fill in the Oauth constants (see subsequent section) and run the LatitudeSample class. In order to resolve the project dependencies, it's advised to use the Maven2 plugin for Eclipse.

The goal here is to start executing requests on the Latitude API, secured via OAuth 2.0. For this, we'll use a simple command line application. For the same flow using the Latitude API on the Android platform, checkout Oauth 2.0 flow in Android

Monday, July 18, 2011

Accessing the Google Public Location Badge programmatically

Introduction

The Google Public Location Badge provides a convenient way to share your Latitude location with others. The Google Latitude apps page allows you to enable your Public Location Badge, and provides you with an HTML snippet that you can add to your blog or website, where it will render a Google Map.


JSON responses

Another way of accessing your location through the Public Location Badge is by using JSON. This allows for a more programmatic access of your location that you can embed in your applications.

This method is very handy if you want to access the current location of someone who has exposed his location through the Public badge.

Each public location badge is associated with a userid. This numeric value is associated with each google account.

If you want to access the JSON string, you can type the following URL in your browser.

http://www.google.com/latitude/apps/badge/api?user=3356651955207924992&type=json

It should return a string like this :

{"type": "FeatureCollection", "features": [
{ "type": "Feature",
"geometry": {"type": "Point", "coordinates": [4.47658, 51.02511]},
"properties": {
"id": "3356651955207924992",
"accuracyInMeters": 0,
"timeStamp": 1311050105,
"reverseGeocode": "Arrondissement of Mechelen, Belgium",
"photoUrl": "http://www.google.com/latitude/apps/badge/api?type=photo&photo=gJsAQTEBAAA.rGdvZsJpNd7LFS7MT5g_Bg.YtjvkPGuqXl4iqhY7QGOyg",
"photoWidth": 96,
"photoHeight": 96,
"placardUrl": "http://www.google.com/latitude/apps/badge/api?type=photo_placard&photo=gJsAQTEBAAA.rGdvZsJpNd7LFS7MT5g_Bg.YtjvkPGuqXl4iqhY7QGOyg&moving=true&stale=true&lod=4&format=png",
"placardWidth": 56,
"placardHeight": 59
}
}
]
}

Java access

We can use the Google APIs Client Library for Java to access your public location badge from a java application. It provides a simple an elegant way to make the REST call, and transform the JSON string into a java based model.

The sample application I'll be showing here is very simple, and is made up of 1 java class that contains a main method.

We start by creating our HttpTransport and requestfactory, required to perform the REST call.

private static final HttpTransport transport = new ApacheHttpTransport();
 private static final String PUBLIC_BADGE_URL = "http://www.google.com/latitude/apps/badge/api";

 public static HttpRequestFactory createRequestFactory(final HttpTransport transport) {
     
    return transport.createRequestFactory(new HttpRequestInitializer() {
     public void initialize(HttpRequest request) {
      GoogleHeaders headers = new GoogleHeaders();
      headers.setApplicationName("Google-Latitue-Public-Badge-Sample");
      request.headers=headers;
      JsonHttpParser parser = new JsonHttpParser();
      parser.jsonFactory = new JacksonFactory();
      request.addParser(parser);
     }
  });
 } 

The Java model

We also need to model the JSON string into java. As we're interested in the users location, the simplest model I could come up with looks like this :

public static class PublicBadge {

  @Key
  public Feature[] features;
  
  @Key
  public String type;
  
  public static class Feature {
   @Key
   public Geometry geometry;
  }

  public static class Geometry {
   @Key
   public float[] coordinates;
  }

 }

Performing the REST call

What's left now is to perform the actual call, and parse the response into our java model.

public static void main(String[] args) throws Exception {

  HttpRequestFactory httpRequestFactory = createRequestFactory(transport);
  HttpRequest request = httpRequestFactory.buildGetRequest(new GenericUrl(PUBLIC_BADGE_URL));
  request.url.put("user", "INSERT USER ID HERE");
  request.url.put("type", "json");
  //System.out.println(request.execute().parseAsString());
  PublicBadge publicBadge = request.execute().parseAs(PublicBadge.class);
  System.out.println("Longitude " + publicBadge.features[0].geometry.coordinates[0]);
  System.out.println("Latitude " + publicBadge.features[0].geometry.coordinates[1]);
 }

Project setup

You can copy paste these bits of code into a single java class. In order to use the
Google APIs Client Library for Java, you need to have the following dependencies in place :



The easiest way to do that is to define the Google APIs Client Library for Java dependencies in a pom.xml, and use maven to resolve the dependencies for you. The pom.xml to have this sample up and running looks like this :


  4.0.0
  
    com.google
    google
    5
  
  com.ecs.latitude
  publicbadge
  1.0-SNAPSHOT
  
    
      
        maven-compiler-plugin
        
          1.6
          1.6
        
      
    
  
  
   
      com.google.api.client
      google-api-client
      1.4.1-beta
    
   
      com.google.api.client
      google-api-client-googleapis
      1.4.1-beta
        
  
  
   
  google-api-services
  http://mavenrepo.google-api-java-client.googlecode.com/hg
 
  
  
    UTF-8
  



The sample app will simply output the latitude / longitude associated with the Public Badge.

Latitude 4.47658
Longitude 51.02511

References

Monday, July 11, 2011

Samsung Galaxy S GPS issues after Gingerbread upgrade

After upgrading my Samsung Galaxy S to Gingerbread, I was having some serious GPS issues.
The unability to get a location fix in a timely fashion, and the many drops during location requests were driving me crazy.
Screenshots below show my daily commute. Location fixes were requested every 30 seconds. You can clearly see the difference before and after the fix.

Before the fix
After the fix


How it got fixed ? By "patching" the GPS receiver with a simple piece of paper....
It seems to do the trick, but I'll need to do some more field testing to be sure. 










I found the possible solution (that I didn't really believe at first) at the Dutch AndroidWorld forum.
For more details on the solution, check the XDA Developers forum.







Monday, May 23, 2011

Introducing the Google Places API

A couple of weeks ago, at the Google I/O developer conference in San Francisco, Google announced the opening up and general availability of the Google Places API. The Google Places API is an API that returns information about Places. It is part of the Google Maps API Web Services, a collection of HTTP interfaces to Google services providing geographic data for your maps applications. The goal of this article is to go over the API by using a sample application that actually does these API calls. We'll cover each API request in detail, look at the raw JSON response coming back from the Google Places API, see how to process the response using the Google APIs Client Library for Java. We'll also convert the JSON response into a java based model, and use that model to display the results.


Monday, May 16, 2011

Introducing the Google Fusion Tables API


In this article, I'll be providing you with a quick overview of the Fusion Tables API.
Google Fusion Tables is a modern data management and publishing web application that makes it easy to host, manage, collaborate on, visualize, and publish data tables online. We'll go over the API by creating a sample application that interacts with our Fusion Tables. The sample app will use the Google APIs Client Library for Java and the complete source code is available on GitHub.


Tuesday, May 10, 2011

Google Places API now available for all developers !


The Google Places API has been made available to all developers.

Where before, the Places API was available through Google invitation only (via the Google Places API Application Form) :


The Places API can now be activated in the Google API Console.


Let the coding begin !


Sunday, May 8, 2011

Having fun at the Google OAuth Playground

Introduction


The Google OAuth playground is a great way to test the integration with Google services using the various Google APIs. The OAuth playground focusses on those APIs that use OAuth as an authentication mechanism.
In this post, I'll be showing you how to interact with the Google Buzz API from the OAuth playground.


Saturday, May 7, 2011

Street View Explorer

If you thought Google Street View was pretty cool, wait untill you checkout the StreetView Explorer.
Instead of just viewing the StreetView images you can walk around in them!
Image and depth data is automatically downloaded from the official Google Street View servers.

Watch the video here :

And checkout the site :

Friday, May 6, 2011

Google URL Shortener

Introduction


In this short article, we'll be taking a look at using the Google URL shortener API, using the Google APIs Client Library for Java.
The Google URL Shortener at goo.gl is a service that takes long URLs and squeezes them into fewer characters to make a link that is easier to share, tweet, or email to friends. You can also use the Google URL Shortener API to programmatically interact with the Google URL Shortener service. This way, you can embed the service in your own applications, and use a simple REST API to store, share, and manage goo.gl short URLs from anywhere on the Internet.

A good starting point for the Google URL shortener API is the Google URL shortener API documentation page. It covers authentication, and the various operations supported by the API. These operations include
  • Shorten a long URL
  • Expand a short URL
  • Look up a short URL's analytics
  • Look up a user's history

In this article we'll focus on shortening a long URL.

Setting up the project


We're going to be using Maven2 to handle the dependencies of our project. We add the com.google.api.client:google-api-client dependency to our pom.xml to ensure that our project has all the required dependencies.

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelversion>4.0.0</modelversion>
 <groupid>com.ecs.google.urlshortener</groupid>
 <artifactid>urlshortener</artifactid>
 <packaging>jar</packaging>
 <version>1.0-SNAPSHOT</version>
 <name>urlshortener</name>
  <build>
    <plugins>
      <plugin>
        <artifactid>maven-compiler-plugin</artifactid>
        <version>2.3.2</version>
        <configuration>
          <source>1.5</source>
          <target>1.5</target>
        </configuration>
      </plugin>
    </plugins>
    </build>
 <dependencies>
    <dependency>
      <groupid>com.google.api.client</groupid>
      <artifactid>google-api-client</artifactid>
      <version>1.2.1-alpha</version>
      <exclusions>
        <exclusion>
          <artifactid>jsr305</artifactid>
          <groupid>com.google.code.findbugs</groupid>
        </exclusion>
      </exclusions>
      </dependency>
    </dependencies></project>

Setting up the HTTP Transport

Now that we have the dependencies setup, we can start with the actual coding. The first thing we need to do is setup the HttpTransport. The HttpTransport will be setup using the GoogleHeaders, and we'll be specifying the application/json content-type. (as we'll be sending and receiving JSON strings over HTTP). We also configure the JSON parser on the transport to properly parse the request/response.

// setup the anonymous Google HTTP transport.
        HttpTransport transport = GoogleTransport.create();

        // configure the headers on the transport.
        GoogleHeaders defaultHeaders = new GoogleHeaders();
        transport.defaultHeaders = defaultHeaders;
        transport.defaultHeaders.put("Content-Type", "application/json");

        // configure the JSON parser on the transport.
        transport.addParser(new JsonHttpParser());

Execute the API call

Now that we have the transport setup correctly, we can execute our API call. We'll be using the https://www.googleapis.com/urlshortener/v1/url endpoint and issue a POST request.

public static final String GOOGLE_SHORTENER_URL = "https://www.googleapis.com/urlshortener/v1/url";

        // build the HTTP GET request and URL
        HttpRequest request = transport.buildPostRequest();
        request.setUrl(GOOGLE_SHORTENER_URL);
We'll create a JSON GenericData object, containing the longUrl that we want to shorten. We'll put the GenericData on the request.

// Prepare the JSON data structure.
        GenericData data = new GenericData();
        data.put("longUrl", "http://latifymobile.com/");
        JsonHttpContent content = new JsonHttpContent();
        content.data = data;

        // Set the JSON content on the request.
        request.content = content;

Parsing the response

When executing this request, we can parse the HTTP response using a class we created specifically for the Google Url Shortener.

// Execute the request, and parse the response using our Result class.
        HttpResponse response = request.execute();
        UrlShortenerResult result = response.parseAs(UrlShortenerResult.class);

        // Print the result.
        System.out.println(result.shortUrl);
As you can see, this is what we're getting as a response from the Google Shortener API.

{
"kind": "urlshortener#url",
"id": "http://goo.gl/vl02B",
"longUrl": "http://latifymobile.com/"
}
We create a UrlShortenerResult object to parse the JSON string above, and capture the shortUrl (embedded in the id attribute).

/**
  * JSON UrlShortenerResult object, capturing the id as the shortUrl
  */
    public static class UrlShortenerResult extends GenericJson {
        @Key("id")
        public String shortUrl;
    }
And that's basically it. Our longUrl has been shortened by the API.

References