Tuesday, 20 November 2012

Creating an Android Jelly Bean Daydream from a WebView


One of the new nifty features on Android Jelly Bean 4.2 is the concept of daydreams (basically a screensaver but also displays when docked etc).  I wanted to create one that displayed an HTML page, which makes for prety easy development and this is how

First of all, this assumes you have API 17 (Android 4.2) installed, otherwise you won't have access to the relevant Android class

Android Daydream option


You need to create a new class that extends android.service.dreams.DreamService and override the onAttachedToWindow() method which is what is called when the service starts up.  In here all you really need to do is create a new WebView as normal and attach it.  Example code below

import android.annotation.TargetApi;
import android.service.dreams.DreamService;
import android.webkit.WebView;
@TargetApi(17)
public class MyDreamService extends DreamService {
    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        // Allow user touch
        setInteractive(true);
        // Hide system UI
        setFullscreen(true);
        // Set the dream layout
        WebView webView = new WebView(this);
        setContentView(webView);
        webView.loadUrl("file:///android_asset/www/test.html");
    }
}

The last line is loading my local HTML file but you could load any page here (remember to set the INTERNET permission for external pages though)

The service needs to be declared in the manifest, for example

<service
    android:name=".MyDreamService"
    android:exported="true"
    android:label="@string/short_app_name" >
    <intent-filter>
        <action android:name="android.service.dreams.DreamService" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</service>

That is pretty much all you need to do! Install your app and try it! The dream setting are under Settings > Display > Daydream

There are various options you can set (eg I set the fullscreen option above) that are documented in the API here: http://developer.android.com/reference/android/service/dreams/DreamService.html

Not a very exciting screenshot but this is my html page displayed as a daydream in the 4.2 emulator
And there you have it, easy! Hope this helps someone

4 comments:

  1. Hi Antony, I am simply an artist, but am very interested in the possibility of creating my own custom Daydream animations, and possibly release them on the market.

    Is this still a simple feature that can't bee changed? Or can developers create for this feature?

    ReplyDelete
  2. Hi
    I'm not quite sure what you're asking, but I'll attempt to answer and leave you to reply if I'm not answering what you asked

    The Daydream feature is something that would require you to develop and release an android app (albeit one containing only a Daydream if that's what you wanted). The same applies for live wallpapers, for example.

    A developer could certainly create custom daydreams, that's the idea. Ordinarily one would need to write the animation code and call the relevant view. What I'm attempting to do above is not code it in the Android API but code it in Javascript and display an HTML page which will run it (so far with limited success, but I'm working on it)

    Does that help at all?

    Antony

    ReplyDelete
  3. Have you tried loading a real web page through the web. I tried to open www.google.com and the day dream app throws an exception that startActivity() can't be called from outside an activity unless FLAG_ACTIVITY_NEW_TASK is used.

    I have no idea why a loadUrl on WebView would trigger a startActivity from a DaydreamService.

    ReplyDelete
  4. I haven't tried it, but that sounds familiar. I think Android tried to load URLs in a new view if they don't seem to be related to the current view. Have you tried using WebViewClient?

    ReplyDelete