Android Tutorial Android Daydream / DreamService tutorial

Erel

Administrator
Staff member
Licensed User
Android 4.2 includes a new powerful screen saver feature named Daydream.

A "dream" starts when the device is docked or charged and the screen timeouts. By default dreams are non-interactive, which means that once the user touches the screen the dream is dismissed. However dreams can also be interactive and include standard views (controls).

It is worth reading Google's blog about this feature: Android Developers Blog: Daydream: Interactive Screen Savers

The Daydream library allows you to create your own dreams.
The dream is handled by a service. The service name must be DreamService.

The dreams are set under Settings - Display - Daydreams.

Steps required to create a dream
- Add a service named DreamService.
- Add the following code to the manifest editor:
B4X:
AddApplicationText(<service
            android:name="anywheresoftware.b4a.objects.DreamServiceWrapper"
            android:exported="true"
            android:label="Dream Service Example">
            <intent-filter>
                <action android:name="android.service.dreams.DreamService" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
           </service>)
You can modify the label value. This value will appear in the dreams list (use this list during development to start the dream):



You can change the icon by changing the application icon.

- Set minSdkVersion and targetSdkVersion in the manifest editor to 17 (17 is Android 4.2).
- Reference android.jar from platform 17 or above (Tools - Configure Paths). You will probably need to first download it with Android SDK Manager.

Simple dream that draws random circles on the screen:
B4X:
Sub Process_Globals
   Private dd As Daydream
   Private timer1 As Timer
End Sub
Sub Service_Create
   
End Sub

Sub Service_Start (StartingIntent As Intent)
   dd.Initialize("dd")
   timer1.Initialize("timer1", 800)
End Sub

Sub dd_SizeChanged
   dd.Canvas.Initialize(dd.Panel)
End Sub

Sub dd_DreamStarted
   dd.Interactive = False
   timer1.Enabled = True
End Sub

Sub Timer1_Tick
   dd.Canvas.DrawCircle(Rnd(0, dd.Panel.Width), _
      Rnd(0, dd.Panel.Height), _
      Rnd(10dip, 100dip), _
      Rnd(0x80000001, 0), _
      True, 0)
   dd.Panel.Invalidate
End Sub
Sub dd_DreamStopped
   timer1.Enabled = False
End Sub

Sub Service_Destroy

End Sub
Important subs:
- Daydream should be initialized in Service_Start.
- SizeChanged event is raised when the main panel is first ready or after the user rotates the screen. In this sub you should build the layout (by adding views to the panel or by initializing the canvas and drawing on the panel).
- DreamStarted event is raised when the dream starts.
- DreamStopped event is raised when the dream stops.

Daydream.Canvas is a placeholder for a canvas. You should initialize it before using it (as done in the above example).

Dreams limitations
Services usually do not interact with UI elements. There are some limitations which you should be aware of:
- Views (and other activity objects) cannot be declared in Sub Process_Globals. You should instead fetch the views from the main panel as done in the WebView example.
- Layout files cannot be loaded.
- Percentage units cannot be used (100%x, 100%y).

Examples
Two examples are attached. The circles example is a dream that randomly draws circles on the screen. The webview example is an interactive dream that loads the URL that the user enters with WebView. The URL is saved in a file.

 

Attachments

barx

Well-Known Member
Licensed User
Looks like a nice feature for future use.

Didn't even know such feature existed.

Well done Erel.
 

RiverRaid

Active Member
Licensed User
Thank you for this!!

Is it also possible to include DayDream in an APP that should run onolder Versions of Android?

I mean, the app itself should run on Android 2.2 + and only on Devices 4.2+ Daydream is available? (Im asking because of the setting of minSdkVersion and targetSdkVersion)

Regards,
Andi
 

NeoTechni

Well-Known Member
Licensed User
How do we get touch events from DD.panel?

I tried DD.Panel.Initialize("DDpanel") but it just crashes

Do I have to add a panel to the panel? Cause that sounds like a pain/waste.
 

Erel

Administrator
Staff member
Licensed User
You will need to add another panel. It will not have any impact on the performance. Also make sure to set Interactive to True.
 

NeoTechni

Well-Known Member
Licensed User
I need drawing and touch though.

Putting a panel on the DD, I can't get a canvas from it.
 

Erel

Administrator
Staff member
Licensed User
I see. Try to add a Touch listener with the reflection library (to the main panel).
 

NeoTechni

Well-Known Member
Licensed User
Thank you.

Might I suggest adding the touch event to the library? The interactive property requires it.
 

Erel

Administrator
Staff member
Licensed User
You can also add a transparent panel. Use it to handle the touch event and draw on the main panel.

Might I suggest adding the touch event to the library?
Suggestions are always welcome.
 

Inman

Well-Known Member
Licensed User
Can I use the animation library in Daydream? If no, how can I perform a translation animation on a view (say Imageview)? Should I change its layout manually using a timer?
 

Erel

Administrator
Staff member
Licensed User
You should be able to use Animation library in Daydream. You can save the Animation object in the view's tag (as you cannot save it as a process global object).
 

Inman

Well-Known Member
Licensed User
Thanks Erel. I was wondering how to declare the animation variable globally. This solves it.
 
Top