代码之家  ›  专栏  ›  技术社区  ›  Itay Ganor

将Unity Admob横幅放置在带有显示屏切口的设备底部

  •  2
  • Itay Ganor  · 技术社区  · 7 年前

    我试图将我的广告横幅(通过官方的Admob Unity软件包生成)放在屏幕的最底部,但它似乎不能很好地与带有凹口的设备配合使用。

    bv = new BannerView(adUnitId, adSize, AdPosition.Bottom);
    

    这一行代码将横幅完美地放置在无凹口设备(例如Pixel、Pixel XL、Pixel 2&2 XL)的最底部,但当设备顶部有凹口时,其外观如下所示:

    enter image description here

    (演示照片取自 this Github Issue 。忽略可见的导航栏。)

    横幅和屏幕底部之间的空间为 确切地 缺口的高度。我用多个缺口高度测试了它。

    为了将横幅放置在最底部,我认为最好的解决方案是获得槽口的高度,然后使用以下代码行:

    new BannerView(adUnitId, adSize, 0, (int)ConvertPixelsToDP(Screen.height - adHeight + notchHeight));
    

    但我找不到任何方法来获得剪切高度。我试着用 Screen 和 Display 类属性,但这些方法都没有帮助我获得屏幕的真正分辨率,包括凹口,所以我可以减去安全区域高度,得到凹口的确切高度。

    有没有办法获得真正的屏幕分辨率?或者有其他可能解决这个问题的方法吗?

    2 回复  |  直到 7 年前
        1
  •  2
  •   silencewebber    7 年前

    从…起 the main GitHub issue thread about this AdMob Unity插件开发人员表示,“将优先考虑下一版本的兼容性。”早在10月份,他们就已经意识到了这个漏洞,并在1月22日发布了帖子,称“这项工作被推迟了,但将进入下一个版本。还没有ETA,但应该很快就会发布。”所以谁知道这个问题什么时候会得到解决。

    但对于任何正在努力解决这个问题的人来说:我找到了一个解决办法。在我的例子中,这是一个让广告出现在屏幕底部的变通方法,但我也会提到如何让它正确地显示在屏幕顶部。我仍然希望能尽快发布一个版本来解决这个问题,但是对于那些不想等待的人来说,这里有一个选项。。。

    我发现了这个解决方法,因为我首先从显而易见的解决方案开始:通过显而易见的公式手动计算y位置: int yDP = DensityIndependentPixels(Mathf.RoundToInt(Screen.safeArea.y + Screen.safeArea.height) - ScreenPixels(adSize.Height)); 这是可行的,但从2018年3月5日起 safeArea 始终有0,0代表x和y,而宽度和高度可用于检测与之相比是否存在缺口 Display.main.systemHeight (虽然据我所知, Screen.height == safeArea.height 我也是 width 所以 安全区 现在完全没有用,因为它只传递你可以从中获得的信息 Screen.height 和 Screen.width ),你实际上无法检测出缺口在哪里。。。这意味着在这个解决方案中,我假设凹口位于屏幕顶部(这是一个安全的假设,但有些手机有两个凹口,一个在顶部,一个在底部,对于这些设备,我的解决方案将使广告部分被底部凹口覆盖…如果 安全区 一旦得到有用的价值,我的变通方法可以解释这一点。。。不管怎样,我离题了。。。

    根据这个假设,我们可以使用一个稍加修改的公式: int yDP = DensityIndependentPixels(Screen.height - ScreenPixels(adSize.Height));

    但令人沮丧的是,当我记录y位置的预期值时。。。它仍然出现在同一个奇怪的偏移位置!我开始从0开始手动递增y位置,并确认在某个y坐标下,即使增加该值,它出现的位置也将是相同的!然后我发现,如果你在y值上再加一点,它会莫名其妙地出现在屏幕顶部,你可以继续增加y位置,使其回到屏幕下方,但这次它没有卡在奇怪的偏移位置!经过多次实验,我发现这个令人费解的额外环绕y偏移的公式是: (DensityIndependentPixels(Display.main.systemHeight) + adSize.Height) 当添加到 intendedDensityIndependentPixelPosition ... 现在,横幅位于您期望的y位置!

    一旦你简化了数学,手动y位置是一个功能性的解决方案,用于将横幅放置在凹口设备的底部,它非常简单:

    int yDP = DensityIndependentPixels(Screen.height + Display.main.systemHeight);
    

    我已经用Android 9中的所有模拟凹口对此进行了测试,它是有效的(需要注意的是,双凹口仍然部分覆盖了广告,但这比覆盖应用程序UI的广告要好),但请注意,我还没有在实际的凹口设备上测试过这一点!

    请注意,您只需要在以下情况下执行此操作: Screen.height != Display.main.systemHeight ... 否则,您使用的是无notchless设备,应该使用 AdPosition.BOTTOM .

    对于那些希望你的横幅出现在顶部的人来说,手动计算y位置就更简单了。在相同的假设下,槽口始终位于顶部,ad的y位置应设置为 DensityIndependentPixels(Display.main.systemHeight - Screen.height) 没有什么奇怪的、莫名其妙的缠绕。请注意,我还没有测试在顶部显示横幅,因为我的应用程序中的横幅总是显示在底部。

    确保广告居中的x位置手动公式完全符合您的预期: int xDP = Mathf.RoundToInt(DensityIndependentPixels(Display.main.systemWidth - ScreenPixels(adSize.Width)) / 2f); 没什么特别奇怪的。

    最后一个注意事项是,在我开始手动指定广告位置后,我无法拨打电话 Show() 打完电话 Hide() 上 BannerView ... 它会进入一种奇怪的状态,在那里它是看不见的,但却可以点击;简单地解决这个问题 Destroy() 创造一个新的 AdRequest 而不是打电话 Show() ... 我在谷歌支持论坛上看到过一些声明,说这是更好的做法。

    我希望我在这个奇怪的问题上失败的那一天,找到这个解决办法能帮助这里的人。

        2
  •  0
  •   nokola    7 年前

    不幸的是,这是一个问题,是由于admob没有正确地考虑Android上的顶级应用。注意:在iOS上,ads代码似乎承认了缺口的存在,并在其下方添加了额外的10个填充单元,这很奇怪。

    我只是花了一天左右的时间试图找出与横幅非常相似的问题。

    有几种方法可以解决这个问题:

    选项1。创建新的java插件并添加下面的代码或C#调用此代码的等效代码:

    public int getDisplayRealHeightPixels() {
        Point realSize = new Point();
        Display display = getWindowManager().getDefaultDisplay();
        if (Build.VERSION.SDK_INT >= 17) {
            display.getRealSize(realSize);
        }
        else {
            display.getSize(realSize);
        }
        return realSize.y;
    }
    

    然后使用 getDisplayRealHeightPixels() 来定位旗帜。我现在就是这么做的。

    选择2。在切割区域启用喷漆: 在onCreate add中创建一个新的java插件:

    protected void onCreate(Bundle savedInstanceState) {
        ...
        // uncomment to allow painting in notch area;
        WindowManager.LayoutParams attributes = getWindow().getAttributes();
        attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
        getWindow().setAttributes(attributes);
        ...
    

    一旦我调整我的应用程序以正确支持剪切,我就会使用这个选项。

    选项3:等待Unity 2018.3正确支持槽口

    根据 https://unity3d.com/unity/beta/2018.3 :

    “安卓:增加了对安卓的支持。”


    哥查斯:

    1. 上述修复都不是完美的(可能是选项3?但我还没有尝试过。)确保在iOS(iPhone X)上测试,因为那里的广告行为与Android不同。
    2. 在Android广告中,y==0是屏幕的顶部,而在iPhone X上,y==0则在缺口下方10个单位处呈现横幅。 对于iOS,我只需将“凹口大小”硬编码为30,然后在凹口区域绘制我的应用程序。
    3. Android split screen是一个难题——我还没有在那里完全测试过,在这种情况下,我的横幅会在屏幕上四处飘扬。我只是决定以后再修。