Resolution issue! Screen is cut off

Hello. The sentence may be strange because this article has been translated.

There was a problem with the resolution.
I received the following screenshot from my app user.

The screenshot below is when I run the app on my device.

When I look at the screen of my app user, the navigation bar is cut off exactly.
(The left side is the picture I got from the user, and the right side is the screenshot I took with the navigation bar.)
compare

I used the following code when setting the resolution.

auto devSize = director->getWinSize();
glview->setDesignResolutionSize(devSize.width, devSize.height, ResolutionPolicy::NO_BORDER);

My app user’s device is the Galaxy Note 10.
cocos2dx version is 3.17.2.

What’s wrong? I want to solve this problem.
Thanks for reading!!

Please post your AppDelegate.cpp

Thank you for your reply!

Unrelated parts have been commented out.
[AppDelegate.cpp]

// #include “AppDelegate.h”
// #include "MainScene.h"
// #include "EditScene.h"
// #include "CropScene.h"

// #include "Settings.h"
// #include "Language.h"

// // #define USE_AUDIO_ENGINE 1
// // #define USE_SIMPLE_AUDIO_ENGINE 1

// #if USE_AUDIO_ENGINE && USE_SIMPLE_AUDIO_ENGINE
// #error "Don't use AudioEngine and SimpleAudioEngine at the same time. Please just select one in your game!"
// #endif

// #if USE_AUDIO_ENGINE
// #include "audio/include/AudioEngine.h"
// using namespace cocos2d::experimental;
// #elif USE_SIMPLE_AUDIO_ENGINE
// #include "audio/include/SimpleAudioEngine.h"
// using namespace CocosDenshion;
// #endif

// USING_NS_CC;

// AppDelegate::AppDelegate()
// {
// }

// AppDelegate::~AppDelegate()
// {
// #if USE_AUDIO_ENGINE
	// AudioEngine::end();
// #elif USE_SIMPLE_AUDIO_ENGINE
	// SimpleAudioEngine::end();
// #endif
// }

// // if you want a different context, modify the value of glContextAttrs
// // it will affect all platforms
// void AppDelegate::initGLContextAttrs()
// {
	// // set OpenGL context attributes: red,green,blue,alpha,depth,stencil
	// GLContextAttrs glContextAttrs = { 8, 8, 8, 8, 24, 8 };

	// GLView::setGLContextAttrs(glContextAttrs);
// }

// // if you want to use the package manager to install more packages,
// // don't modify or remove this function
// static int register_all_packages()
// {
	// return 0; //flag for packages manager
// }

static Size designResolutionSize = Size(1080, 1920);
static Size testSize = Size(1080, 1920) * 0.5;

bool AppDelegate::applicationDidFinishLaunching() {
	// initialize director
	auto director = Director::getInstance();
	auto glview = director->getOpenGLView();
	if (!glview) {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
		glview = GLViewImpl::createWithRect("BGMaker", cocos2d::Rect(0, 0, testSize.width, testSize.height));
#else
		glview = GLViewImpl::create("BGMaker");
#endif
		director->setOpenGLView(glview);
	}

	// set FPS. the default value is 1.0/60 if you don't call this
	director->setAnimationInterval(1.0f / 60);

	// Set the design resolution
#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
	auto devSize = testSize;
#else
	auto devSize = director->getWinSize();
#endif

	if (designResolutionSize.width > devSize.width) {
		devSize = designResolutionSize;
	}

	glview->setDesignResolutionSize(devSize.width, devSize.height, ResolutionPolicy::NO_BORDER);
	sWin = devSize;

	// register_all_packages();

	// // User data
	// Settings::load();

	// // Language
	// initSentence();

	// // run
// //#define DEBUG______

// #ifdef DEBUG______
	// director->runWithScene(EditScene::createScene());
	// //director->setDisplayStats(true);
// #else
	// director->runWithScene(MainScene::createScene());
// #endif

	// return true;
}

// // This function will be called when the app is inactive. Note, when receiving a phone call it is invoked.
// void AppDelegate::applicationDidEnterBackground() {
	// Director::getInstance()->stopAnimation();

// #if USE_AUDIO_ENGINE
	// AudioEngine::pauseAll();
// #elif USE_SIMPLE_AUDIO_ENGINE
	// SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
	// SimpleAudioEngine::getInstance()->pauseAllEffects();
// #endif
// }

// // this function will be called when the app is active again
// void AppDelegate::applicationWillEnterForeground() {
	// Director::getInstance()->startAnimation();

// #if USE_AUDIO_ENGINE
	// AudioEngine::resumeAll();
// #elif USE_SIMPLE_AUDIO_ENGINE
	// SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
	// SimpleAudioEngine::getInstance()->resumeAllEffects();
// #endif
// }

And below are some of the possible causes of the problem that I have further identified.
Could it be the cause of the problem?

[AndroidManifest.xml]

<activity
            android:name="org.cocos2dx.cpp.AppActivity"
            android:screenOrientation="portrait"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:label="@string/app_name"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:launchMode="singleTask"
            android:taskAffinity=""  >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <meta-data android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version"/>
        <activity android:name="com.google.android.gms.ads.AdActivity"
            android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>

[AppActivity.java]

public class AppActivity extends Cocos2dxActivity {
private static AppActivity _appActiviy;
private static AdView adView;
private static final String AD_UNIT_ID = “my ad unit id”;

    //////////////////////////////////////////
    // for ADMOB
    //////////////////////////////////////////

    // Helper get display screen to avoid deprecated function use
    private Point getDisplaySize(Display d)
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
        {
            return getDisplaySizeGE11(d);
        }
        return getDisplaySizeLT11(d);
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
    private Point getDisplaySizeGE11(Display d)
    {
        Point p = new Point(0, 0);
        d.getSize(p);
        return p;
    }

    private Point getDisplaySizeLT11(Display d)
    {
        try
        {
            Method getWidth = Display.class.getMethod("getWidth", new Class[] {});
            Method getHeight = Display.class.getMethod("getHeight", new Class[] {});
            return new Point(((Integer) getWidth.invoke(d, (Object[]) null)).intValue(), ((Integer) getHeight.invoke(d, (Object[]) null)).intValue());
        }
        catch (NoSuchMethodException e2) // None of these exceptions should ever occur.
        {
            return new Point(-1, -1);
        }
        catch (IllegalArgumentException e2)
        {
            return new Point(-2, -2);
        }
        catch (IllegalAccessException e2)
        {
            return new Point(-3, -3);
        }
        catch (InvocationTargetException e2)
        {
            return new Point(-4, -4);
        }
    }

    public static void hideAd()
    {
        _appActiviy.runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                if (_appActiviy.adView.isEnabled())
                    _appActiviy.adView.setEnabled(false);

                if (_appActiviy.adView.getVisibility() != View.INVISIBLE )
                    _appActiviy.adView.setVisibility(View.INVISIBLE);
            }
        });
    }

    public static void showAd()
    {
        _appActiviy.runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                if (!_appActiviy.adView.isEnabled())
                    _appActiviy.adView.setEnabled(true);

                if (_appActiviy.adView.getVisibility() == View.INVISIBLE )
                    _appActiviy.adView.setVisibility(View.VISIBLE);
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();

        if (adView != null) {
            adView.resume();
        }

        if (this.getCurrentFocus() != Cocos2dxGLSurfaceView.getInstance())
        {
            Cocos2dxGLSurfaceView.getInstance().requestFocus();
        }
    }

    @Override
    protected void onPause() {
        if (adView != null) {
            adView.pause();
        }

        super.onPause();
    }

    @Override
    protected void onDestroy() {
        if(adView != null){
            adView.destroy();
        }

        super.onDestroy();
    }

    //////////////////////////////////////////
    // onCreate
    //////////////////////////////////////////

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.setEnableVirtualButton(false);
        super.onCreate(savedInstanceState);
        // Workaround in https://stackoverflow.com/questions/16283079/re-launch-of-activity-on-home-button-but-only-the-first-time/16447508
        if (!isTaskRoot()) {
            // Android launched another instance of the root activity into an existing task
            //  so just quietly finish and go away, dropping the user back into the activity
            //  at the top of the stack (ie: the last state of this task)
            // Don't need to finish it again since it's finished in super.onCreate .
            return;
        }
        // Make sure we're running on Pie or higher to change cutout mode
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            // Enable rendering into the cutout area
            WindowManager.LayoutParams lp = getWindow().getAttributes();
            lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
            getWindow().setAttributes(lp);
        }
        // DO OTHER INITIALIZATION BELOW

        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

        _appActiviy = this;

        // ADMOB
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        int width = getDisplaySize(getWindowManager().getDefaultDisplay()).x;

        LinearLayout.LayoutParams adParams = new LinearLayout.LayoutParams(
                width,
                LinearLayout.LayoutParams.WRAP_CONTENT);


        adView = new AdView(this);
        adView.setAdSize(AdSize.BANNER);
        adView.setAdUnitId(AD_UNIT_ID);


        AdRequest adRequest = new AdRequest.Builder()
                .build();

        adView.loadAd(adRequest);
        adView.setBackgroundColor(Color.BLACK);
        adView.setBackgroundColor(0);
        addContentView(adView,adParams);

        //Hide ad as default
        hideAd();
    }
}

You should checkout how multi-resolution policy manage to work.

This is my case for 9:16 portrait device.

cocos2d::Size designResolutionSize = cocos2d::Size(720, 1280);
cocos2d::Size smallResolutionSize = cocos2d::Size(720, 1280);
cocos2d::Size mediumResolutionSize = cocos2d::Size(1080, 1920);
cocos2d::Size largeResolutionSize = cocos2d::Size(1440, 2560);

glview->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::FIXED_HEIGHT);

And then create a background image(720 1280) setting scale from CC_CONTENT_SCALE_FACTOR to cover up black border.

Thank you very much for your reply!! :smiley:

In my opinion, the cut seems to be covered by something. (E.g. navigation bar)
This is because only the navigation bar is cut off without an error of exactly 1 pixel.

The suggested method is not a workaround. :cold_face:
Thank you for taking the time to respond. :heart_eyes: