Optimizing your app

Modifying apps for Samsung DeX

This section provides an overview of how to optimize apps for Samsung DeX.

There are very few special implementation requirements needed to get an app ready for Samsung DeX. Generally, if an app adheres to the best practices of Android programming, it will successfully operate in Samsung DeX without any additional coding. Apps should follow the best practices for the following topics:

  • Enabling Multi-Window support

  • Enabling keyboard and mouse support

  • Handling runtime configuration changes

  • Implementing a responsive UI

The following section provides references to the most relevant Android coding practices for Samsung DeX.

Enabling Multi-Window support

To run in Samsung DeX, apps should support Android Multi-Window – this enables minimizing, maximizing and resizing. If Multi-Window is not supported, the app opens in a fixed-size window. Follow Androids guide on Multi-Window support for complete information on how to configure apps.

To enable Multi-Window for Samsung DeX, paste this code into the Manifest file:

<activity>
    android:resizeableActivity="true"
</activity>

The image below shows the different window resize options available when apps have Multi-Window enabled

Figure 5: Target SDK >= 24, android:resizeableActivity="true"

Enabling Mouse and keyboard

Do not declare the touchscreen support as it may disable the mouse and the keyboard interactions. This explicit declaration is shown in the code below.

<uses-configuration android:reqTouchScreen="finger">
<uses-feature android:name="android.hardware.touchscreen">
<android:required="true">

If you explicitly declare touchscreen support, the app won't launch in Desktop mode and will display the message below.

Figure 6: Touchscreen disabled error

Handle runtime configuration changes

The switch between mobile and Samsung DeX mode causes runtime configuration changes – similar to an orientation change from portrait to landscape display. This may result in the application being forced to restart when switching between modes. To ensure that this does not happen, follow Android's guide for handling configuration changes; as well as Android's best practices for more information on building a responsive design.

Samsung DeX 7 runtime changes to support:
  • Density change between xxxhdpi and mdpi.

  • Resolution change between WQHD and FHD (or one among FHD, HD+ and WQHD at Samsung DeX with SEP v9.0).

  • Orientation change between portrait and landscape.

  • Screen layout change.

  • Screen size change.

  • Smallest screen size change.

  • UI mode change between mobile and desktop.

You can use the following qualifiers to provide alternative Android resources in Samsung DeX mode:

  • UI mode : desk

  • Screen layout : xlarge

  • Density : mdpi

  • Resolution : FHD (can also support HD+ or WQHD when using Samsung DeX with SEP v9.0)

For example, this image below shows an example of using different resources for different screen densities.

Figure 7: Android resource folder

This image demonstrates the correct dpi handling for fonts on different screen sizes – when the Samsung DeX app is resized, the size and scale of font remains appropriate to the screen size.

Figure 8: Runtime configuration changes in Samsung DeX

If you choose to handle configuration changes yourself (not recommended), you need to provide the following declaration in the Manifest file. It will prevent the application from restarting when the screen density changes between mobile and Samsung DeX modes:

How to detect Samsung DeX mode

If you want to check the current mode of your app, Samsung DeX or mobile mode, use the following code snippet.


import android.content.res.Configuration;
import java.lang.reflect.Field;
import java.lang.Class;

Configuration config=getResources().getConfiguration();
		try{
         Class configClass=config.getClass();
		if(configClass.getField("SEM_DESKTOP_MODE_ENABLED").getInt(configClass)
		==configClass.getField("semDesktopModeEnabled").getInt(config)){

		// Samsung DeX mode enabled
		}
		}catch(NoSuchFieldException e){
		}catch(IllegalAccessException e){
		}catch(IllegalArgumentException e){
}

To switch your application between mobile and Samsung DeX, add the following code snippet. This will allow your app to detect Samsung DeX once it is connected.

1. Declare “keepalive” and set the android:configChanges attribute in the Android manifest.


<application
   …
android:resizeableActivity="true">
   <activity android:name=".MainActivity"
     android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation">
       <intent-filter>
           <action android:name="android.intent.action.MAIN" />
           <category android:name="android.intent.category.LAUNCHER" />
       </intent-filter>
   </activity>
   <meta-data android:name="com.samsung.android.keepalive.density" android:value="true"/>
</application> 
Note

Declares keepalive in the android manifest file, to avoid the process being killed when switching between mobile and Samsung DeX. In addition, set the android:configChanges to avoid restarting the app during the switching process.

2. See the code below to initialize your Samsung DeX app as well as how to implement the onConfigurationChanged() API method.


import android.content.res.Configuration; 
import java.lang.refelction.Field; 
import java.lang.Class; 

boolean desktopModeEnabled=false; 
boolean currentDesktopMode = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);     
    setContentView(R.layout.activity_main);
// initialize the status for Samsung DeX mode enabled
    desktopModeEnabled = checkDeXEnabled();
}
 
@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    currentDesktopMode = checkDeXEnabled();
    if (desktopModeEnabled != currentDesktopMode) {
        desktopModeEnabled = currentDesktopMode;
        // Here, implement the working codes when switch the mode between mobile and Samsung DeX
    }
} 
 
boolean checkDeXEnabled(){
    boolean enabled;
    Configuration config = getResources().getConfiguration();
    try {
        Class configClass = config.getClass();
        if (configClass.getField("SEM_DESKTOP_MODE_ENABLED").getInt(configClass)
                == configClass.getField("semDesktopModeEnabled").getInt(config)) {
            enabled = true;
        } else {
            enabled = false;
        }
        return enabled;
    } catch (NoSuchFieldException e) {
    } catch (IllegalAccessException e) {
    } catch (IllegalArgumentException e) {
    }
    return false;
}