Archive for the 'Technology' Category

Using Flurry with a Android Home Screen Widget

Saturday, April 24th, 2010

Flurry is a great tool for tracking the users of your mobile application, producing the sort of data visualisation that makes marketing men smile with glee.  Unfortunately, I have discovered that the Android API is good for monitoring usage of Android Activities, but not suited for tracking Android Home Screen Widgets.

The main issue here is that Widgets have a very different (i.e. much longer) life-cycle.  For Activities, Flurry documentation recommends tying into the “onStart” and “onStop” life cycle methods, which provide a clear mapping with the creation and subsequent deletion of a given Activity context.

For widgets it’s a little more complicated.  What you want to do it tap into the “onEnabled” and “onDisabled” life-cycle methods, so you know how long at least one of your widgets has been installed on the home screen.  The problem here is that the widget does not maintain the same context between these two calls, and (if well designed) shouldn’t spend much time being in memory at all.

Take for example a Clock widget, which is triggered repeatedly by an AlarmManager intent and manages to update its UI within the short permitted time span of a BroadcastReceiver.  This is extremely efficient from a saving battery perspective(AlarmManager can be configured not to wake up the device), but gives Flurry no scope to maintain a session, or report back usage data over the network (I have no idea how Flurry have implemented this functionality?).

Flurry data

Hence I am seeing incorrect session length values in my Flurry reports, i.e. Flurry is reporting 3-10 seconds (probably the time it takes to initialise my widget) and not the time the widget spends being shown on the home screen (in this example several days).

Unfortunately Flurry have locked down their own forums, and are not returning my support emails.
Does anyone know if this kind of tracking is this possible?  Would it help if I spun up a service or cached the context (i.e. leak some memory)?  As Flurry reports are delayed, this is very difficult to debug.  Could anyone suggest another usage tracking tool that supports Android Home screen widgets?

Posted on Android Developers forum.

Hand Warmer on Android Market

Monday, March 15th, 2010

Problem:
So you need to verify the upgrade life cycle of the Android Market *before* you launch your product, so you give yourself the goal of putting a completely new application together in the space of one hour.  It can be anything, preferably something original (iFart has already been done), so long and you can turn it around from concept to release in 60 minutes and don’t include any of your own company branding.

**Remember the goal is to evaluate the Market, not to spend time dwelling on the code.**

Handwarmer icon

So behold world, I give you “Hand Warmer!”

A one word concept, of an App that warms up your device (and doesn’t require any permissions to do so).  The idea came from an early product build that deallocated too many Java objects in a loop, which as  a by product would run the Android Garbage collector like crazy.  The overtaxed processor on the HTC Magic then generate a lot of heat… toasty.

Screenshot 1

State: Off

Disclaimer

State: Warning - show disclaimer to user before enabling the warmer.

screenshot 2
State: On.

Implementation:
Version 1.0 did nothing but show the hot water bottle (warming metaphor) go from black (off) to orange (on), and of course show the longest legal disclaimer I could write (i.e. will drain your battery, I do not take liability if you melt your device, etc.)  Apart from the welcome Activity, most of the code ran as an ongoing service, which displayed a “warming” notification in the top bar when the application was active.

I also went with the following (if partially untrue) tag line:
Causes the device to warm up in your hands.  Useful in winter.

Version 2.0 was an opportunity to test the upgrade life cycle and see how well it worked on the range of devices available at the time.  I will discuss the strange Android Market side effects in more detail in a later post.

I added the following claims to the description:

  • QVGA and WVGA support.” - Upgraded from 1.5 to 1.6 SDK, with the new “supports screens” Manifest tags.
  • Fixed Service Leak bug” - First time around my application “leaked” unused services (i.e. kept them running), this was due to an ambiguity in the SDK documentation which I have since fixed.
  • Now App is 25% hotter!!” - Mostly true, as I doubled the speed of a wasteful object deallocator loop which was providing the heating, although I’m sure the screen was using more energy (and thereby providing more heat).

Battery

Version 3.0 was particularity interesting because I added the Flurry Agent, so I could collect more interesting analytics that what I could get out of Google Market.  Also to encourage downloads (or upgrades), I added the claim: “Now App is now 20% hotter than before”.  Of course, for an application that doesn’t actually do anything, your results may vary.

Critical reaction:
Considering that this was an hour off work, I was absolutely gob-smacked by the shear volume of downloads.  Review were mixed (obviously) with many highlighting the dangers this application posed to the device.

Moral review

And of course this being the Android Market, I got my fair share of…

Bad review

Obviously if I wanted to warm the device I would lock the screen to maximum brightness, vibrate constantly and probably max-out the processor as much as I could.  Other supposedly “copycat” applications which have sprung up since, even tie-in the temperature sensor API (available on some devices) which would make such an application workable (i.e you can’t control what you can’t measure).

Also, in our development team any battery draining code is now said to be “taken from the Hand warmer app”.

Learnings:
Quite a lot actually…

I was able to write up the Market publishing process from end to end, with its capability’s, quirks and outright bugs.  This drove the direction of the company’s product publishing strategy (more in a later post).

Flurry is also a great (if legally dubious – again, more in a follow-up) tool for tracking your users.   I was able to deploy and track a real world deployment, before writing up recommendations for other platform teams (Flurry supports iPhone, Blackberry, etc.).

Flurry User Data

Look at my massive user base, giving stuff away for free on Android actually works (try that on JavaME or Series 60!).

User locations

Android is still a North America (read USA) based operation, which should change as more (and better) devices become available in the rest of the world.  This will be helped greatly if Google role-out their (currently quite limited) coverage for paid applications on the market.

Events

The interesting part here is that 2.2% of sessions ended without the user enabling that application.  That tells you how effective legal disclaimers (even nasty ones) are in real world settings.

Finally, I end with a promise to be publishing (and blogging) some of my *serious* applications in the near future.

Data SMS – An Annoying Android Fragmentation Bug on the Samsung Galaxy

Friday, September 25th, 2009

A code contained in a Data SMS is required to authenticate the MSISDN of the device running my product.

When I receive a data SMS on the Samsung Galaxy, the Intent “android.intent.action.DATA_SMS_RECEIVED” is not thrown and the Data SMS arrives in the Inbox as a blank text message.  Any data contained in the Data SMS seems to be lost once it arrives in the Inbox.

Here is a little app I wrote which detects the MSISDN (not working on many devices) or lets you enter it, then send either a Data SMS or a Text Message.  The app will then display any incoming Data or Text SMSs by the intent they throw and allow you to interrogate the native Inbox to determine what data was saved.

Time to file a bug!

Bug Report
Forum

Android Cupcake Device Review > HTC Dream

Saturday, September 12th, 2009

HTC Dream

The original Android phone, which came shipped with Android version 1.0 but promptly performed a seamless self update to Cupcake after I took it out of the box and connected it to the internet for the first time.

This device is only interesting for testing (post Cupcake) because it has a hardware keyboard which by default will restart the running Activity every time you flip it out.  This uses a slightly different event notification system to the rotate listener, which is the only way of changing screen orientation on the other 3 Cupcake devices.  The hardware keyboard makes it currently the best available Android phone for writing messages, but the retarded amount of on board memory means you must start deleting stuff after downloading your tenth application.

A lot of developers have a “Android Developer Phone 1” device (now out of stock) which is essentially a pre-rooted HTC Dream, giving developers full Linux level access so they can install their own firmware.

Please note, that a rooted phone is not required if you are only intending to develop Application level software, as any Android device will run a self signed application as long as you check “Unknown Sources” in Menu > Settings > Application settings.

There is no 3.5 audio jack on this device, instead use the ExtUSB connector with the headset provided.  Some editions of this device come with a 3.5 headset and ExtUSB adapter, allowing users to use their own headphones to listen to music.

Device specific test cases:

  • Flip out that keyboard a couple of times on each screen.  Badly written applications will lose UI state (form data, selected tabs, etc), or freeze if they are in the middle of a long running process started from within the Activity (consider using a service in this case).
  • Try and perform all actions using the keyboard (as if the touch screen were broken).
  • Test for trackball slide clicks (i.e. when the user mistakenly presses the trackball when they intended to slide it).  The proper way of handling this is to ignore all trackball clicks that occur less than half a second after a trackball drag.  This test is useful for games that implement trackball events themselves, as we are used to the native Android UI handling this on our behalf.
  • Flash your Developer Phone firmware and test your Application on an early build of Donut.

Android Cupcake Hardware Review

Saturday, August 22nd, 2009

This is a review of all the mobile phones currently being sold (outside of China) that run Android Cupcake.  I am an Android Third party Application developer (i.e. not a Google employee or handset manufacturer) and will be reviewing various technical differences that affect developers like myself.

together

With the late arrival of the Samsung Galaxy, I now finally have the full set to play with.

Group

The Samsung Galaxy comes in a bigger box because it comes with a “PC Studio” and drivers CD.  You shouldn’t need a CD to develop on an Android device, because the ADB and USB drivers are included with the Android SDK (more on this in the Galaxy review).

Comparison table:

HTC Dream (i.e. G1) HTC Magic HTC Hero (+Sense UI) Samsung Galaxy
Internal storage 71MB 291MB 155MB 912MB
Camera 3.2MP 3.2MP 5MP 5MP + LED Flash
Battery 1150mAh 1340mAh 1350mAh 1500mAh
Connector ExtUSB ExtUSB 3.5 Audio + ExtUSB 3.5 Audio + MicroUSB
Keyboard Flip out None None None
Controller Trackball Trackball Trackball D-Pad
OpenGL Hardware Hardware Hardware Software
SD Card 2GB 8GB 2GB Not included
Upgrade OTA OTA Via PC Via PC
Screen 30.0cm2 30.0cm2 30.6cm2 30.7cm2 AMOLED
Edit 254px 254px 229px 212px

Additional information, including unrelased devices is avalaible here (documented by Eric Wong).

Comparison notes:
All devices have roughly a 3.2” HVGA (480×320 pixcel) capacitance touch display, support 3G, WiFi, GPS, Bluetooth, accelerometer, digital compass and Micro-SD memory cards.   Only the HTC Dream and HTC Magic are Google experience phones which support automatic updates, the others instead come bundled with software customisations (both good and bad) developed independently by their respective manufactures.

Internal storage
Currently applications cannot be run off the SD Card (unless you have root access), and I don’t expect this situation to change any time soon.  That means the internal phone storage represents the upper limit on how many applications (including contacts/mail/calendar storage & Web Browser cache) that you can install on your phone.

The Samsung Galaxy’s ~6.7GB internal SD card isn’t included here, because you can’t install Applications onto it.

If you have less than 10MB of space remaining, you will get a low space notification and all synchronisation tasks will stop.  To find out this value for your device, look in the device settings:
Menu > Settings > SD Card & phone storage
Look for “Available space” under the “Internal phone storage” header.

All these values are for a fresh device (i.e. reset to the factory settings) and are running a similar retail Cupcake build.  Your results may vary.

Camera
More Mega-pixels usually denotes a better result, but having a flash is important when taking pictures indoors.

Battery
Bigger the better really.  Android background processes can eat up a lot of juice, but us software developers are working on improving this situation.  Actual battery life was not tested.

Connector
MicroUSB is the new standard (according to the EU), so get ready to replace all your chargers and connection cables once again.  All the HTC devices use the ExtUSB which is a proprietary connector is apparently under some debate.  Also, don’t confuse this with the older Mini USB which you probably already have chargers for, as these will also have to go into the bin.

Keyboard
Cupcake comes with a usable on screen software keyboard, which makes it possible to type one handed with your thumb.  This works quite well as long as you remember that you only type a character when you *remove* your finger from the screen.  This makes accurate typing a click, and then drag affair.

The HTC Dream comes with a flip out keyboard (for use in landscape mode), with a good key layout design but effectively requires two hands to use (i.e. typing with your thumbs).  This is much better for data entry, as you get some good tactile feedback from the keys, and the lack of soft keyboard leaves you with more screen real estate for your application.

Controller
For all practical usages, the click ball and the D-pad are identical.  I am yet to test if this makes any difference to Android game play.

OpenGL
All  the HTC devices come with OpenGL hardware “acceleration”, i.e. calculations are performed on a separate GPU chip.  The same code is implemented in software on the Galaxy, meaning that animations run proportionally slower (compared to processor speed) on this device than you would expect, and there is more animation judder when the processor is asked to perform other tasks.

While this isn’t a big issue today, I expect to see greater use if OpenGL in Games and user interfaces  in the coming year.  A good example  of what to expect would be the Rachael UI prototype from Sony Ericsson.

SD Card
Its nice when the device comes with a decent SD card, although only some applications will make use of this space.

Upgrade
Android is quite new, so new revisions and security fixes are coming out all the time and you want to make sure you are using the latest build.  Google experience devices will upgrade themselves, but it’s a bit unclear at this point how (and how often) non-Google experience devices will be upgraded.

The HTC Hero and Samsung Galaxy currently require PC software to download and install their latest updates.  I expect that most users wont bother (or know how) to upgrade, so Application developers should expect to support Cupcake devices for many years to come.  I will call these devices “Dead Ducks” until someone comes up with a seamless way of bringing everybody over to Donut, then Éclair, etc.

This is one area where owning a Google experience “in the cloud” Android device is advantageous, and I wouldn’t recommend any of the other devices until this issue has been resolved.

Screen
Physical screen display area of the device, measured with a ruler.

Edit
The virtual keyboard is essential, but uses up a lot of on screen real estate that your application must take into consideration.  Surprisingly this size varies considerably between firmware customisations, with the Samsung Galaxy using the greatest space with its oversized keyboard.  HTC Dream users have the option of flipping out their physical keyboards, nullifying this limitation.

I have measured the amount of usable on screen pixels available when the virtual keyboard is shown in portrait mode. This is the distance between the top of the virtual keyboard and the bottom of the on screen notification bar.  Fewer pixels means there is a larger virtual keyboard, but conversely, there is less area for your application to display data in.

Individual device reviews to come…

Fun moving over contacts

Wednesday, May 20th, 2009

Contacts
I don’t know why anyone else would want to do this, but here goes.

So I am between jobs and I have to give back my Android G1 and use my old Nokia 6600 for a few weeks.  That means moving over my contacts, which turns out to be a lot easier than I expected:

  1. Android G1 contacts are synchronised with my Google mail account.  So log into Gmail, then click Contacts > Export.  Export “Everyone” in “vCard format”, saving the .vcf file to your Nokia MMC card.
  2. Download and install Best vCard for S60, and use it to open the .vcf file on your MMC.  Import all contacts and you’re done.

All the regular issues:

  • Umlauts are corrupted, i.e. characters üöäÜÖÄß become split pairs (surrogate pairs), or Mark Münsterman becomes MÄ$nsterman.
  • Contact labels are missing.  So instead of having a Business, Home and Mobile number for someone I have 3x numbers labelled “Telephone”.

Clearly there is room for a global standard for moving, updating and synching contacts between systems.  Most people I know find themselves moving between systems (Outlook, phone, webmail, Facebook, etc) and spend time maintaining their contacts, or just don’t bother at all.

The world awaits my next invention.

Google App Engine on Java

Thursday, April 23rd, 2009

App engine

Two big news items today:

  • Oracle now own Sun.
  • Google App Engine now supports Java.

Oracle on Sun
What I think is being overlooked here is that Oracle have now *inadvertently* bought MySQL (now owned by Sun), i.e. their only serious rival.  This sounds like an anti-trust case to me.

Google App Engine on Java
I came *this* close to binning my GoDaddy account and switching to the App engine for my next big idea (a work in progress).  However I’ve been warned by a current user to be wary of the Google-style process timer limits, and sure enough, looking through the documentation…

Source:
http://code.google.com/appengine/docs/whatisgoogleappengine.html

Application code only runs in response to a web request or a cron job, and must return response data within 30 seconds in any case. A request handler cannot spawn a sub-process or execute code after the response has been sent.

Forcing developers to make their systems responsive is just good programming from Google, however I need to run a low intensity spider in the background once every hour.  Currently this takes about two minutes to complete, but I expect it to run much longer on production data.  Hence I can’t afford to have Google killing my code every 30 seconds. :-(

An application cannot write to the file system. An app can read files, but only files uploaded with the application code. The app must use the App Engine datastore, memcache or other services for all data that persists between requests.
Log4J files anyone?

I’ll have to keep an eye on this to see if anything changes, as “Free lunch” Google hosting sounds too good to resist.

23.4.2009 EDIT
Log4J support is here.

24.4.2009 EDIT
I stand corrected.  It seems that the feature “Task queues for performing background processing” is high in the App Engine product roadmap for a June 2009 release.  Maybe I’ll get my free lunch after all?
http://code.google.com/appengine/docs/roadmap.html

Thanks to all on this thread.

Extracting APK files from your Android “ADP1″

Tuesday, March 10th, 2009

The ADP1 is the Unlocked/Routed version of the HTC G1 (running Android) being sold separately by Google, intended for developer use only.

Prerequisites:
- Android SDK
- Android USB driver

To extract APK files:
(1) Plug your “Routed” Android phone into your computer via the included USB cable.
(2) From your computers command line type “adb shell“.
(3) Switch to root user “su“.
(4) “cd data/app“.
(5) List all the installed apk files with “ls“.
(6) In another command window, pull one of the files on to your computer:
Format:
adb pull /data/app/.apk .apk
Example:
adb pull data/app/com.zedray.snowball.apk snowball.apk

That wasn’t so hard was it?

The Android OS has effectively no protection for downloaded executables, so applications developers should seek alternative mechanisms for securing their applications against piracy.  Now (don’t get me wrong), I’m coming at this not as a user wishing to pirate software, but as a developer looking to sell the fruits of my labour over the Android Market.

Google have implmented their own reginal/device based locking with limited success (e.g. developers can’t see their own applications on the store).  However, I think a real solution would be to allow matching devices/users accounts to actual purchases, so applicaiton developers can monitor legitimately purchased applications on the server side.

HTC G1 Application storage limitation:
Both the HTC G1 and the forthcoming HTC Magic suffer from having extremely limited on-device Application storage.  This amounts to about 70MB after all the default OS applications (email, browser, etc.) have been installed.  This is a serious drawback for the device because Android Market applications can’t be installed off the SD card.  Meaning that a user will be able to typically download ~10 applications before their phone complains of lack of space (so much for trying out the thousands of free applications on the store).  I believe this is an issue which Google have no intention of fixing because of the security problems described above.

This is a real deal breaker when anyone asks me if they should get themselves a G1, and should also be considered by anyone trying to make money by selling applications on the Android market.

This problem will be solved over time as other manufactures start putting out devices with 8GB or 16GB+ of on-device storage.

Overcoming this limitation:
I am told that executing an APK file from an SD card currently requires a Linux file system partition (which I haven’t attempted).  My aim is to remap the SD card to the “data/app/” directory, so I can install Android Market executables directly to my 8GB SD card.  Then I could download and use hundreds of applications at the same time.

Why GoDaddy Linux Virtual Dedicated Hosting Sucks & How to Fix It

Sunday, February 8th, 2009

It’s nice to have a problem over a weekend coding session and have someone blog about how they already solved it (click).

Android Bug/Architectural Issue: How do I handle multiple versions of my own Content Provider?

Thursday, January 8th, 2009

I am writing a component that makes certain functionality available to any application running on an Android device (e.g. an advertising service, stock ticker cache, Snowball server, etc).

cp1.gif
This functionality is useful for application developers, but not interesting to actual users i.e. my component should be included as part of a new application, but not require the end user to explicitly install the additional component themselves.

cp2.gif
I expect that over time multiple applications installed on the phone will want to communicate with my component.  As each new application will have a different certificate, I want to communicate between applications using an Android Content Provider.  To save resources on the device (networking, caching, etc) only one instance of my component should be appointed to handle all queries.

cp3.gif
This works well as Android only registers the first Content Provider for a given URI and then ignores the rest (throwing an “WARN/PackageManager: Skipping provider name xxxx name already used” error each time a new one is installed).

cp4.gif
However if the registered Content Provider is uninstalled, it will immediately break all the other applications that rely on it, even though other instances of the component still exist.

Questions:

  • Does anyone have any suggestions on how to better handle this situation?
  • If I could reregister Content Providers I could handle situations like this, and upgrade components when newer versions are installed.  Perhaps the Android OS could also handle this situation better, by tracking Content Provider naming collisions?
  • Should I be looking at other communication methods to solve this issue?

Note: This has been posted on the following discussion boards:

  • Android Developers (click)
  • Android-platform (click)

Edit 20090108
Just to clarify, the attribute “android:multiprocess” in the “provider” tag seems to have a behaviour that is not relevant to this problem, i.e. it prevents multiple instances of the same Content Provider from existing, rather than affecting multiple Content Providers trying to use the same namespace.

Edit 20090109
Thanks everyone for the replies.  Just to clarify: I am writing an advertising server component at the moment, but other projects that I have in the pipeline essentially have the same requirement.

>>Dianne Hackborn - As far as naming issues, this is why you should use an authority in a namespace/domain you own, so that there will not be naming collisions.<<
My application sits in its own namespace.  I am only having conflicts with different copies of the same Content Provider Component being installed with different applications.

>>Dianne Hackborn - …any client app that is relying on a component that is not part of the base platform needs to deal with the error cases if that component does not exist.<<
If the component is not there, then the application would show an error on start and normally refuse to run.  Result: Bad user experience.

>>Peli - Hm, I think you end up with unnecessary code duplication if you include your component / content provider in every application.<<
This isn’t an issue, as my component is delivered as a small Java class included with the main application.  When activated, the component inflates in size as it downloads content over the internet.  My goal is to manage this process by having only one component activated regardless of how many applications are installed on the device.

>>Peli - I think it would be better if every application that wants to use your component shows a small dialog “You need to install the following component…” with a button that brings you to the download page of the Market for your component…<<
Catching a missing component is easy enough.  It’s just that what you describe adds up to a bad user experience:

  • No user will download a 3rd party advertising server (or any non-core functionality) just to run a game.
  • Installation is already a convoluted process and should only take place once.  Additional APK installations require more downloading, application permission settings, button pressing, confusion, etc.
  • No client of mine will accept a solution that asks the user to jump through any additional hoops (e.g. even the Android Developer Challenge only permitted a single executable).

>>Peli - At OpenIntents we try to resolve dependencies as late as possible - i.e. not at installation time, but the first time the user actually wants to use a particular feature (they may never use it in which case there is no need to install it).<<
This doesn’t work for me as ad funded Applications generally require my component to be available on startup.

>>Peli - I think in the long run Market should have better tools for resolving compulsory dependencies automatically, but for the moment I think this is a good compromise for developers and end users.<<
I agree that this needs to be improved, as there is currently no support for components (downloading, versioning, upgrading, etc) in Android or on the Android Market.  Hence I am trying to get around this issue by “managing” a Content Provider.

>>Dianne Hackborn - Oh wait if what is being talked about is having the same content provider in multiple applications, that is completely the wrong approach.  For a given authority there must be one and only one content provider implementation, living in a single specific .apk.<<
This is how it’s done at the moment, i.e. Android will log a warning (and do nothing) every time an application tries to register a Content Provider URI that’s already in use.  This means that subsequent applications will be broken (and need to be reinstalled) if the original Content Provider is ever uninstalled.  I don’t seem to be able to reregister a missing Content Provider URI at runtime.

>>Muthu Ramadoss - AFAIK, a Content Provider is tied up to a unique Authority.  If you want to support multiple URI’s you do so accordingly by providing different URI paths using the same authority.<<
I explored this approach initially, but it still has the following problem:

Over time, I release a number of versions of my component that other developers subsequently integrate into their own applications.  My component uses the following URI conventions:
content://mynamespace.mycomponentnamespace.version1/
content://mynamespace.mycomponentnamespace.version2/
content://mynamespace.mycomponentnamespace.version3/

Android allows me to search and interrogate each URI to check the status of each Content Provider (allowing me to version my component).  This is fine until v3 of my component becomes really popular and a user installs five games on their phone, each with the same component trying to register the same URI.

The user then gets bored of the first game and uninstalls it, thereby breaking all the other games that rely on the Content Provider that it contains.  As URIs are set at install time, none of the other games will work until the user reinstalls an existing game or downloads a new one - This is a terrible user experience.

Edit 20090109 (#2)
>>Peli - Indeed, for an advertising server, it makes more sense to include that in every application separately, for the reasons you mentioned. I could suggest the following…and all applications can access that one content provider. Would this sound like a suitable solution?<<
I didn’t think of just doing the synchronisation using intents (as they support a one-to-many relationship between components).  I’ll do a proof of concept on Monday to see if this works.  It’ll be a bit of a hassle for the guy who has to incorporate this into their application, but it will do until Android is improved to support components. ;-)

Thank you kindly!!

>>Mark Murphy - Since the content in question is going on /sdcard (right? right?!?), solve the problem by managing the space, not managing the components. Since you already require each application to have your own code anyway, just use a regular Java class to access the /sdcard data store and dump the ContentProvider interface.<<
>>Peli - Ad images and banners should be placed on the SD card, but private data for accounting (number of times an ad had been shown, click- through-rate, last ad shown, etc.) could be stored in a content provider, and it makes sense to share this content provider among several applications installed (e.g. so that the end user is not presented the same ad in every application they launch).<<
While Mark Murphy’s solution could be made to work, communicating outside of the OS would be quite ugly in terms of the security and the hardware assumptions which would need to be made.  I also expect the security regime and file permissions to morph somewhat over the next couple of Android releases, potentially breaking my OS bypass hack.  I’ll put this idea down as a plan B, thanks anyway!!

I think I have enough ideas to get this to work now, and will post my results to the thread and blog early next week.

Edit 20090115 - Solution
The simplest solution (not using intents) is to instruct each user of my component to define a new content provider:

content://myComponentNamespace.theirApplicaitonNamespace

Android lets me search through all available content providers, which can be string matched to my own component namespace.

context.getPackageManager().queryContentProviders(null, 0, 0);

If I find more than one valid Content Provider I can then pass around Synchronisation information (validity, compatibility, version, status, etc) using any of the ContentProvider class methods (I used getType()).

The only problem with this approach is that the application developer who imports my component (as a JAR) will have to define their own custom Content Provider.  This is done by extending the MyComponentContentProvider class (from my JAR) and defining a CONTENT_URI variable.

package test;
import com.whitemice.MyComponentContentProvider;
public class TheirContentProvider extends MyComponentContentProvider {
public static final Uri CONTENT_URI =
Uri.parse( "content:// myComponentNamespace.theirApplicaitonNamespace“);
}

As well as adding the custom provider to the Android manifest.

--provider
android:name="test.TheirContentProvider"
android:authorities=" myComponentNamespace.theirApplicaitonNamespace"

As this is a work time project, I will have to check if I can release the synchronisation code as a working example.

Edit 20090116
>>Peli  - Probably you should not mis-use getType()…<<
I originally choose getType() for simplicity (URI in -> String out), but I will now use query() instead.  However, as my application is not compatible with any other software (i.e. my data exchange has no MIME type), I would be interested if anyone could provide a concrete example of where an inappropriate getType() response might cause problems.

Also, for simplicity I am not using intents.

>>Dianne Hackborn - …Along those same lines, looking for your own special text in the authority to identify content providers you are going to work with is also kind-of screwy.  Typically how we do this is attach meta-data to the component that whoever is interested in identifying specifically tagged components looks for.  Look at the way input method service components are discovered in Cupcake as an example. <<

Here is a small component discovery rewrite, now using meta-data to mark valid Content Providers:

####AndroidManifest.xml####

–provider–
android:name=”test.TheirContentProvider”
android:authorities=”myComponentNamespace.theirApplicaitonNamespace”

–meta-data android:name=”type” android:value=”myComponentNamespace”–
–/provider–

####Java Code####

List–ProviderInfo– pis = androidContext.getPackageManager().queryContentProviders(null, 0, PackageManager.GET_META_DATA);


for(ProviderInfo pi:pis) {
Bundle md = pi.metaData;
if (md != null &&
md.getString(”type”) != null &&
md.getString(”type”).equals(”myComponentNamespace”)) {

    //Congratulations you have now found a valid Content Provider
//Note: keep looking as you might find more

    }
}

The upside of this is that the application developer can now deploy my Content Provider using any URI namespace they choose.  However, I will still recommend the previous naming scheme to prevent damaging naming conflicts.

>>Dianne Hackborn - …Also, have you thought about security at all?  What kind of information is stored on the content provider?  Who can access it?<<
As I understand it, any cross application Content Provider on Android needs to implement its own (i.e. roll-your-own) security solution when handling incoming requests.

My current application (an advertising server) treats this as an open/free to use API, with risk scenarios being managed mainly on the server side.

My next application (component for peer-to-peer data sharing) will require a custom Android Permission for sending data.  This is similar to the “android.permission.INTERNET” permission whereby the user still gets a say as to whether the application can send data off the phone.

I am not yet confident enough in the security capabilities of Android and/or my knowledge of them, to implement an application that handles confidential data.


Geo Visitors Map