B4A Library External Displays

Android has had official support for external displays since version 4.2.
Prior to version 4.2 some devices had hardware that was capable of outputting a display signal to an external display but control of this output was implemented by the device manufacturer.
Generally the external display would mirror the device's primary display and that was it.

There was no standard API to control external displays until android version 4.2.
Android version 4.2 introduced the Presentation class.
A Presentation is a container for displaying a user interface on an external display.

An external display could now be configured to display any custom user interface - as well as still being able to simply mirror the device's primary display.

An external display is a display that is temporarily connected to a device.
Examples are:
  • TV or projector connected to device using an HDMI cable or MHL adapter.
  • TV or projector connected to device using the Miracast wireless protocol.
    This includes a Samsung device using Samsung's AllShare Cast technology - AllShare Cast is Samsung's proprietary implementation of the Miracast protocol.
  • TV or projector connected to device using a SlimPort cable.

Whereas a primary display is a display that the device normally uses for output.
A TV or projector connected to an android TV stick or OUYA device is still a primary display and not an external display as it is the display that the device normally uses for output.

A Chromecast device is not presently classified as an external display.
A Chromecast device is a media streaming device that can be told to playback a media resource - it will retrieve and display that media resource.
The Chromecast can be told to display a media resource by various methods: an android or iOS application or the desktop Chrome browser can tell a Chromecast device what media resource to display.
But the Chromecast is not currently an external display - i say currently as there is the possibility that Google will update the Chromecast firmware so that it behaves as an external display - but that is just a possibility and may or (more likely) may not happen.

But in this thread i'll publish my attempts to wrap the parts of the android API that allow control over both external displays and Chromecast devices.

If you do not have a device which you can connect to an external display then you are not out of luck - as long as your device is running android 4.2 or later.
In your device's Developer Options under the Drawing category you should find an option to Simulate secondary displays.
Give that option a click and you'll be presented with a list of available emulated secondary displays.
Select an option from that list and a small window will be overlaid on the device display - that small window is a software emulated external display and can be used as an alternative to a real external display.
You can tap and drag the window around the screen so as to not obscure a part of the device's main screen that you need to interact with.

I'll keep this thread tidy by attaching all library files to this first post.

Martin.
 

Attachments

  • CWAC-Presentation_library_files_v0.30.zip
    28.5 KB · Views: 852
  • ExternalDisplays-20140422.zip
    148.4 KB · Views: 984

moster67

Expert
Licensed User
Longtime User
The b4a Chromecast library is progressing - today i've managed to connect to and disconnect from my Chomecast, and while connected start playback of an online video.
Still lots of work to be done on it but i suspect i'll be able to upload something for you all to experiment with within the next couple of days.

Martin.
You're my man, Martin!

I really look forward to testing it. Another donation (third one to you from me) will be forthcoming. You're an asset to B4A and this community. Thanks.
 

DSD

Member
Licensed User
Longtime User
I tried the sample app MediaRouterRemotePlaybackDemo.apk and it worked great on my Xperia Z with my Cromecast.
This is very exciting since all the functionality I would need is the same as in the sample app.
Just to be able to send a URL to the Cromecast and control playback through the app would be a great first step.
I'm eagerly awaiting more news... :)
 

warwound

Expert
Licensed User
Longtime User
Here then is a chance to see what i've been working on the past few days.
It's not intended to be a finished library ready for production use, neither is any of it's syntax and usage guaranteed to remain.

There's a lot of and features and possibilities to cover in this library and i want to keep a balance between endless wrapped classes (that in theory allow complete use of the android API) and simpler helper classes that encapsulate more limited use of the android API but make things so much simpler to use...

In the attchement there are folders:
  • 20140420 contains the b4a demo project.
  • cwac-mediarouter-res contains android resources needed by one of the android library that this b4a library uses.
  • library_files contains the ExternalDisplay library files and an HTML reference document.

Unzip all folders, add the ExternalDisplays library files (.jar and .xml) to your b4a additional libraries folder and open the b4a project.

First locate these lines in the Main Activity (lines 8 to 11):

B4X:
	#AdditionalRes: C:\Users\martin\Programming\adt-bundle-windows-x86_64-20131030\sdk\extras\android\support\v7\appcompat\res, android.support.v7.appcompat
	#AdditionalRes: C:\Users\martin\Programming\adt-bundle-windows-x86_64-20131030\sdk\extras\android\support\v7\mediarouter\res, android.support.v7.mediarouter
	#AdditionalRes: C:\Users\martin\Programming\adt-bundle-windows-x86_64-20131030\sdk\extras\google\google_play_services\libproject\google-play-services_lib\res, com.google.android.gms
	#AdditionalRes: C:\Users\martin\Programming\Basic4Android\ExternalDisplays\cwac-mediarouter-res, com.commonsware.cwac.mediarouter

The library depends on 3 external android library projects:
(cwac.mediarouter is compiled into the b4a library but still requires you to include it's resources).
  • Android Support V4 - android-support-v4
  • Android Support V7 AppCompat - android-support-v7-appcompat.jar
  • Android Support V7 MediaRouter - android-support-v7-mediarouter.jar
So probably a good idea to start up the android SDK manager and make sure that you have all three library projects installed and that the latest versions of the .jar files are in your b4a additional libraries folder.

Update the paths to the 'res' folders of each project in the Main Activity - that's the AdditionalRes lines above.

Now you can compile the b4a project, if all goes well you'll see an Activity with the 'Cast' Button top left with a Panel underneath.
The Panel contains an EditText and Buttons for Play, Pause and Stop.

Click the Cast button and if your android device can detect a Chromecast device you'll see a dialog allowing you to select your Chromecast.
Select your Chromecast and take a look at the log, you'll see info about a RouteSelected event being raised, info about whether your Chromecast supports remote playback and session management and then a SessionActionResult event is raised and the logs shows the session id.
The Play, Pause and Stop Buttons (previously disabled) should now be enabled.
Click the Play Button and you should see your Chromecast start to stream a video from the internet.
Try Pause - does it pause playback? And does it resume playback when clicked a second time?
Does Stop stop playback?

Click the Cast Button again and you should have options to adjust the Chromecast volume and also to disconnect.

Finally the ActionBar 'Debug' menu item will force the display of the dialog that appears when you click the Cast Button.
If your android device cannot detect any nearby Chromecast devices then the Cast Button will not activate itself, the Debug menu item forces the Cast Button 'click action' even if it's disabled.

That's about it.

Be sure to look through the HTML reference document - many objects exist as 'stubs' only and have no methods or properties except an 'IsInitialized' method.
I'm hoping that i can develop the ExternalDisplays library so that it supports 'proper' external displays (think HDMI and MHL connections) as well as Chromecast.
Let me have some feedback and we can decide what's the best way forward.
Do we want lots of classes wrapped into lots of b4a objects, and the b4a developer has to study the android APIs and learn how to use these wrapped classes?
Or do we want simpler b4a helper objects that make development much easier but at the same time limit full access to the android APIs?

Martin.
 

thedesolatesoul

Expert
Licensed User
Longtime User
Now you can compile the b4a project, if all goes well you'll see an Activity with the 'Cast' Button top left with a Panel underneath.
The Panel contains an EditText and Buttons for Play, Pause and Stop.
Quick test of the apk.
The cast button is disabled for me. Pressing the debug finds my CC. And connects. (The cast button then shows the volume control)
But the play/pause/stop buttons seem to be disabled.
 

NJDude

Expert
Licensed User
Longtime User
The sample (APK) works fine, however, when a device is not found (pressing the DEBUG button) it keeps searching forever, just wondering if there's a timeout setting somewhere.

On a side note, apparently Google just released enough code to connect to ChromeCast, this library doesn't work on GoogleTV, I tested other ChromeCast-compatible apps and I got the same result, however, Google apps (like YouTube for example) can cast to GoogleTV; another case of Google's shenanigans.

Awesome job Warwound.
 

DSD

Member
Licensed User
Longtime User
I'm not able to get the sample project to build, when doing so I get the following error:

Compiling generated Java code. Error
B4A line: 53
MediaRouter1.AddCallback(MediaRouteSelector1, MediaRouterCallback1, MediaRouter1.CALLBACK_FLAG_REQUEST_DISCOVERY)
javac 1.6.0_24
src\uk\co\martinpearman\b4a\externaldisplaysdemo\main.java:307: package android.support.v7.media does not exist
_mediarouter1.AddCallback((android.support.v7.media.MediaRouteSelector)(_mediarouteselector1.getObject()),(android.support.v7.media.MediaRouter.Callback)(_mediaroutercallback1.getObject()),_mediarouter1.CALLBACK_FLAG_REQUEST_DISCOVERY);

I've replaced all the paths in project attributes so they point to working folders.
I'm not able to find the path in the error message (see bold text above).

Any help is appreciated.

/Mattias
 

thedesolatesoul

Expert
Licensed User
Longtime User
I've replaced all the paths in project attributes so they point to working folders.
I'm not able to find the path in the error message (see bold text above).

Any help is appreciated.
Read the instructions from warwound in the post above, specifically this:
These files are in your \extras\android\support\v7\appcompat\libs and so on.
The library depends on 3 external android library projects:
(cwac.mediarouter is compiled into the b4a library but still requires you to include it's resources).
  • Android Support V4 - android-support-v4
  • Android Support V7 AppCompat - android-support-v7-appcompat.jar
  • Android Support V7 MediaRouter - android-support-v7-mediarouter.jar
So probably a good idea to start up the android SDK manager and make sure that you have all three library projects installed and that the latest versions of the .jar files are in your b4a additional libraries folder.
 

DSD

Member
Licensed User
Longtime User
Read the instructions from warwound in the post above, specifically this:
These files are in your \extras\android\support\v7\appcompat\libs and so on.

Thanks I needed to read those lines again and I found out what I missed. :)
I've now added all the jar-files and added the path to Additional Libraries.
The project now builds, but when run I get an error on line 50:

Dim MediaRouterCallback1 As MediaRouterCallback
The error I get is java.lang.nullpointerexception

I'm running the app on Android 4.3
 

DSD

Member
Licensed User
Longtime User
Can you post the full exception?
I'm sorry but I don't get any more information than:
An error occurred:
(Line: 50) Dim MediaRouterCallback1 as MediaRouterCallback
java.lang.NullpointerException

Are there anything else I can do to get more information?
 

thedesolatesoul

Expert
Licensed User
Longtime User
I'm sorry but I don't get any more information than:
An error occurred:
(Line: 50) Dim MediaRouterCallback1 as MediaRouterCallback
java.lang.NullpointerException

Are there anything else I can do to get more information?
Are you checking in the logs?

Also, do you get this error after the CC is connected or you feel that it is not really connected?
 

warwound

Expert
Licensed User
Longtime User
When i'm back on my pc in the morning i'll check which android API version i compled with - just to check that's not the problem.
 

DSD

Member
Licensed User
Longtime User
Are you checking in the logs?

Also, do you get this error after the CC is connected or you feel that it is not really connected?

Are there any other logs I can check for more information?
The only one that I know of is the one in the B4A application (see attached image).

Perhaps I've made a mistake and compiled it against wrong Android version...
 

Attachments

  • B4A_ExternalDisplayError.PNG
    B4A_ExternalDisplayError.PNG
    17.2 KB · Views: 255

DSD

Member
Licensed User
Longtime User
Thanks for being so helpful. :)

I've tried "Clean Project" and refreshed the Libs tab and also unchecked/checked the libraries again.
Also tried running in debug and release. When running in Release the app just Force Close.

Since I'm quite new to B4A there could be something that I've missed...
 
Last edited:
Top