nexxPLAY for Android

nexxPLAY for android is a native Player, that is intended to work in native android Apps

In this Section, you will find all necessary basic Steps to integrate the nexxPLAY SDK to your native android App.

Please notice - 3Q also provides a sample App, that you can find here:

General Integration

First add the 3Q Repository to the Apps allprojects Gradle Definition.

...
maven { url "https://www.myget.org/F/3qnexx/maven" }
...

Add the Dependency for nexxPLAY in the Apps build.gradle:

dependencies { 
    ...
    implementation 'tv.nexx.android:play:6.+'
    ...
}

Make sure, that every Activity, that uses nexxPLAY handles configChanges:

<application>
    ...
    <activity
        ...
        android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|screenLayout" />
  
</application>

nexxPLAY needs a root anchor view which should be a FrameLayout. Please add something likes this to your layout, depending on your needs:

    <FrameLayout
        android:id="@+id/root"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

Adding a Player Instance

nexxPLAY needs a single view. The root view is the view group where the media player control layout (the player skin) is shown. Also the player needs the Acitivity's window

import tv.nexx.android.play.NexxPLAY;
import tv.nexx.android.play.NexxPLAYConfiguration;
import tv.nexx.android.play.NexxPLAYEnvironment;

public class PlayerActivity{

    private NexxPLAY player;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
    ...
      ViewGroup root = (ViewGroup) findViewById(R.id.root);

      //define the Player object
      NexxPLAY player = new NexxPLAY(this, root, getWindow());

      //define an Environment and specify at least the DomainID
      NexxPLAYEnvironment env = new NexxPLAYEnvironment(new HashMap<String, Object>() {{
         put(domain, ":domainid");
         ...
      }});
      player.setEnvironment(env);
      
      //define a Configuration and specify all Overrides, that shall be applied
      NexxPLAYConfiguration config = new NexxPLAYConfiguration(new HashMap<String, Object>() {{
         ...
      }});
      
      //start Playback of a given Media (here, by Streamtype and ID)
      player.startPlay(":streamtype", ":mediaid", config);
    }
    
    @Override
    public void onResume() {
        super.onResume();
        player.onActivityResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        player.onActivityPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        player.onActivityDestroyed();
    }
}

You can also use the NexxPlayProvider Singleton, if you prefer a synchronized Singleton Approach:

@Override
public void onCreate(Bundle savedInstanceState) {
    ...
    NexxPLAY player = NexxPlayProvider.init(getContext(), root, getActivity().getWindow());
    ...
}

Player Environment

The NexxPLAYEnvironment object contains global settings for the player object. Except for the domain all the settings are optional and have a predefined value. The settings are:

On TV, the Player will always start in Fullscreen (unless its Audio and respectViewSizeForAudio is set to 1). Therefore, "alwaysInFullscreen" and "showCloseButtonOnFullscreen" have no Effect.

Player Configuration

Just like the Javascript Player, the Player can be configured by a Configuration Object. This Object will be used in one of the various play() Methods of the SDK.

All Options are identical to the general SDK Override Options, you will find here:

Please notice, that some Options only make sense in the Web and are therefore not supported.

In case of "starting the Player muted", please notice the special Overrides for native Players on the same link.

If you are looking for the TCF Consent String Management, this is documented here:

Public Methods

Preparing and Configuring the Player

//Sets the environment object for the player. This method must be called before any start method is called
setEnvironment(NexxPLAYEnvironment nexxPLAYEnvironment)
//update a previously defined Environment Value
//domain, language, sessionID and alwaysInFullscreen cannot be updated
updateEnvironment(String key, String value)
//start the Player with the given Media
startPlay(String streamtype, String mediaID, NexxPLAYConfiguration configuration)
//start the Player with a given GlobalID
startPlayWithGlobalID(String globalID, NexxPLAYConfiguration configuration)
//start the Player with a Remote Media Reference
startPlayWithRemoteMedia(String streamtype, String reference, String provider, NexxPLAYConfiguration configuration)
//update a previously defined Configuration. 
//supported are currently only the ad*URL Configuration Settings (and webURLRepresentation).
updateConfiguration(String key, String value) 
//will clear all currently cached Data
clearCache()

Playback Control

//restart a paused Player
play()
//pauses a playing Player
pause()
//pauses/restarts a Player, depending on its current State
toggle()
//mutes the Player
mute()
//unmutes the Player
unmute()
//seeks to the given Time, if the Media supports that
seekTo(Float time)
//seeks relatively by a certain amount of Seconds, if the Media supports that
seekBy(Float seconds)
//swap to the next Item in a Container Element
next()
//swap to the previous Item in a Container Element
previous()
//swap to a new Item in a Container Element
swapToPosition(int position)
//swap to a completely new Media Item
swapToMediaItem(String mediaID, String streamtype:String, int startPosition = 0, Double delay = 0, String reason = "", Boolean showReturnButton = false)
//swap to a completely new Media Item, referenced by a GlobalID
swapToGlobalID(String globalID, int startPosition = 0, Double delay = 0, String reason = "", Boolean showReturnButton = false)
//swap to a completely new Media Item, referenced by a Remote Reference
swapToRemoteMedia(String reference, String streamtype, String provider, Double delay = 0, String reason:String = "", Boolean showReturnButton = false)

Requesting Player Status and Details

//returns Information about the currently played Media Item
getCurrentMedia(): tv.nexx.play.android.MediaData
//returns Information about the Container Element of the currently played Media Item
getCurrentMediaParent(): tv.nexx.play.android.MediaParentData
//returns Information about the current Playback State of the Player
getCurrentPlaybackState(): tv.nexx.play.android.PlaybackState
//returns the Captions of the current Media Item (or only the ones matching the given Language)
getTextTracks(): tv.nexx.play.android.TextTrack[]
//returns all available Audio Tracks of the current Media
getAudioTracks(): tv.nexx.play.android.AudioTrack[]
//returns the current playback time of the Player
getCurrentTime(): Float
//returns the Files, connected to the current Media
getConnectedFiles(): tv.nexx.play.android.ConnectedFile[]
//returns true, if the Player is currently playing
isPlaying(): Boolean
//returns true, if the Player is currently playing an Ad
isPlayingAd(): Boolean
//returns true, if the Player is currently muted
isMuted(): Boolean
//returns true, if the Player is currently in PictureToPicture Mode
isInPiP(): Boolean
//returns true, if the Player is currently casting
isCasting(): Boolean

LocalMedia and Offline Playback

nexxPLAY for android also supports Playback of previously downloaded Media Items and therefore offers some SDK Methods to manage localMedia.

//start a Download of a given Media Item (internal ID or Remote Reference)
startDownloadLocalMedia(String mediaID, String streamtype, @Nullable String provider)
//returns a List of currently available localMedia Items
listLocalMedia(@Nullable String streamtype)
//returns true, if the referenced Media Item is already available locally
hasDownloadOfLocalMedia(String mediaID, String streamtype, @Nullable String provider): Boolean
//remove a previously downloaded Media Item
removeLocalMedia(String mediaID:String, String streamtype, @Nullable String provider:String)
//remove all previously downloaded Media Items
clearLocalMedia(@Nullable String streamtype)
//returns the currently used Storage by downloaded Media Items
diskSpaceUsedForLocalMedia():long

This Feature must be enabled within nexxOMNA. Furthermore, various Settings to finetune the Details of the localMedia Behaviour can be setup there. Contact 3Q for more Information.

Player Notifications

Just like the Javascript Player, the Player emits all Events to a Listener Function, that can be configured as outlined below. The Player Class has to implement the NexxPLAYNotification.Listener Interface in this case.

import tv.nexx.android.play.NexxPLAYConfiguration;
import tv.nexx.android.play.NexxPLAYEnvironment;
import tv.nexx.android.play.NexxPLAYNotification;
import tv.nexx.android.play.INexxPLAY;
import tv.nexx.android.play.player.IPlayer;

public class PlayerActivity implements NexxPLAYNotification.Listener {

    private INexxPLAY player;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
    ...    
    }
    
    @Override
    public void onResume() {
        super.onResume();
        player.addPlaystateListener(this);
        player.onActivityResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        player.removePlaystateListener(this);
        player.onActivityPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        player.onActivityDestroyed();
    }
}
    @Override
    public void onPlayerEvent(NexxPLAYNotification.IPlayerEvent playerEvent) {
        //do something with the Event
    }
    
    @Override
    public void onPlayerStateChanged(IPlayer.State state) {
        //do something 
    }

    @Override
    public void onPlayerError(String reason, String details) {
        //do something 
    }

    @Override
    public void onFullScreen(boolean fullScreen) {
        //do something 
    }
    
}

Ad Support

nexxPLAY supports Video Ads on all Platforms. This is handled internally with the Google IMA Framework. To minimize the Google Footprint in the Android Manifests, nexxPLAY seperates the Ad Functionality from the main SDK since Version 6.3.00.

To support Ads, just add a Reference to the latest AdManager SDK and add a Reference to the Player Environment like the following:

dependencies { 
    ...
    implementation 'tv.nexx.android:admanager:1.+'
    ...
}
import tv.nexx.android.play.NexxPLAY;
import tv.nexx.android.play.NexxPLAYEnvironment;

public class PlayerActivity{
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
    ...

      //define the Player object
      NexxPLAY player = new NexxPLAY(this, root, getWindow());

      //define an Environment and specify at least the DomainID
      NexxPLAYEnvironment env = new NexxPLAYEnvironment(new HashMap<String, Object>() {{
         put(domain, ":domainid");
         put(adManager, new NexxPLAYAdManager(PlayerActivity.this))
         ...
      }});
      player.setEnvironment(env);
      ...
    }

TV Support

Remote Control

nexxPLAY for android works identical on mobile Devices as on Phones - unless the Platform demands different Behaviour. Most significantly, you must support Remote Control Input and forward it to the Player:

import tv.nexx.android.play.NexxPLAYConfiguration;
import tv.nexx.android.play.NexxPLAYEnvironment;
import tv.nexx.android.play.NexxPLAYNotification;
import tv.nexx.android.play.NexxPLAY;

public class PlayerActivity implements NexxPLAYNotification.Listener {
    
    ...
 
    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        NexxPLAY player = NexxPlayProvider.getInstance();
        if (player != null && player.dispatchKeyEvent(event)) {
            return true;
        }
        return super.dispatchKeyEvent(event);
    }
}

Fullscreen

As it is common on TV to show the Player in Fullscreen, the Overrides "alwaysInFullscreen" and "showCloseButtonOnFullscreen" are ignored on this Platform.

In case the Player will use Audio Contents on TV, it might make sense to not use it Fullscreen. Use the Configuration Option "respectViewSizeForAudio" in this Case.

Homescreen Rows

nexxPLAY for Android TV also support the "WatchNext" System, if possible (GoogleTV needs a manual Review for this Feature).

In order to make this work, a valid contentURITemplate and contentIDTemplate must be set. This can be done either within nexxOMNIA or via the Environment Settings.

Please notice, that nexxOMNIA can also manage the Channel Rows on androidTV. For this, you must also add the "Channel Widget" to your Project (see below).

Picture-in-Picture

To enable Picture-in-Picture (on mobile, Tablet and/or TV) add the following code:

import tv.nexx.android.play.NexxPLAYConfiguration;
import tv.nexx.android.play.NexxPLAYEnvironment;
import tv.nexx.android.play.NexxPLAYNotification;
import tv.nexx.android.play.NexxPLAY;

public class PlayerActivity implements NexxPLAYNotification.Listener {

    ...
 
    @Override
    public void onUserLeaveHint() {
        NexxPLAY player = NexxPlayProvider.getInstance();
        if (player != null) {
            player.onUserLeaveHint();
        }
    }

    @Override
    public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig) {
        NexxPLAY player = NexxPlayProvider.getInstance();
        if (player != null) {
            player.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);
        }
    }
}

Picture-in-Picture must also be declared in the App Manifest, at least like this:

android:supportsPictureInPicture="true"

Picture-in-Picture also requires to be enabled in nexxOMNIA Player Settings and/or Configuration with Overrides.

Additionally, it may not be available on all Devices, depending on Hardware Capabilities.

Chromecast

nexxPLAY for android supports Chromecast and Casting on mobile and Tablet Devices.

Chromecast can only be used, if 3Q adds this Module to the target Domain. If Chromecast Module is enabled, follow these Implementation Steps to enable Chromecast also in the android App.

First, add the Chromecast Receiver Application ID (from 3Q) to your "res/values/strings.xml":

...
<string name="chromecast_receiver_app" translatable="false">RECEIVER_APP</string>
...

Add the latest Cast Framework to the build.gradle of the App:

implementation 'com.google.android.gms:play-services-cast-framework:21.4.0'

Add the nexxPLAY CastOptionsProvider Class as MetaData to the Manifest:

<application>
    ...

  <receiver
    android:name="androidx.mediarouter.media.MediaTransferReceiver"
    android:exported="true"></receiver>

  <meta-data
    android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
    android:value="tv.nexx.android.play.cast.CastOptionsProvider"/>

</application>

Within the main Application, as early as possible and in the "onCreate" Method, initiate the CastContext, provided by Google Play Services and save it. This CastContext should be used then every time, nexxPLAY is initiated.

public class MainActivity{
    ...
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        CastContext.getSharedInstance(this, Executors.newSingleThreadExecutor())
            .addOnSuccessListener(castContext -> {
                mCastContext=castContext;
            }).addOnFailureListener(exception -> {
                //some Devices (especially TVs etc) may not support Casting
            });
    }
    ...
}

Every time, the Application starts a new nexxPLAY Instance, set NexxPLAYEnvironment.castContext to the captured CastContext (mCastContext in this Example). The rest will be handled by nexxPLAY internally.

Global MediaSession

normally, there is no need to handle MediaSession and TransportControl app-wise, as nexxPLAY will handle this automatically and initiate/terminate the necessary Objects and States corresponding to Config and System Capabilities.

If your App needs a consistent MediaSession though (for example for Assistant Commands), you can use the Environment Options mediaSession and send your Global MediaSession to the Player, whenever it is initiated. In this case, the Player will NOT terminate the Session, even if it will be destroyed. Nevertheless, as the Player changes the Callbacks of the MediaSession, your App might have to set the App-related Callbacks later.

In case nexxPLAY received an app-related Command via MediaSession while active, the App will be informed about that via the nexxPLAY Event System.

Notch and Display CutOut

nexxPLAY will automatically respect the App Notch Settings and expand under it, if defined. If this is desired, configure the App Theme like:

<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>

Flutter

nexxPLAY for android is also supported in Flutter.

Widgets

The android Platform also supports native Widgets by nexxPLAY.

Last updated