我的应用程序完全可以使用 DPad 在 AndroidTV 上使用和导航。嗯,它肯定在我的 AndroidTV 和 AVD 上。
但是,谷歌一直拒绝我将其标记为支持 AndroidTV 的请求。
除了
之外没有任何反馈缺少 DPad 功能 您的应用程序需要用户交互 菜单或应用程序导航。请确保所有菜单和应用程序 使用 DPad 即可实现完整的导航功能。请参阅我们的 DPAD 控制和硬件声明文档。
您知道他们是否真正测试了这些应用程序,还是只是寻找某些代码模式?他们发来的信息看起来是自动发送的,而且我还没有和任何人说过话。
如果我记录我的应用程序的使用情况并向他们发送演示链接会有帮助吗?
就我而言,有 3 个问题。
采取所有这些措施后 - 12 小时后 - 我获得了批准。现在,我已经删除了吐司,我的应用程序仍然被接受。
更新 - 2024 年 4 月 11 日:
联系支持人员没有帮助。 需要重写 onKeydown,这是 pad 按钮所需要的 - 并在各处实现 toast。特别是音量按钮
int currentVolume = 50;
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
try {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_UP:
if (remotevideoTrack != null && audioTrack != null ) {
currentVolume = Math.min(currentVolume + 5, 100);
audioTrack.setVolume(currentVolume);
ToastMeVeryShort("volume:" + currentVolume);
}
else
ToastMeVeryShort("no connection");
return true;
case KeyEvent.KEYCODE_MEDIA_PLAY:
if (remotevideoTrack != null && audioTrack != null ) {
ToastMeVeryShort("running already");
}
else
ToastMeVeryShort("no connection");
return true;
case KeyEvent.KEYCODE_MEDIA_PAUSE:
if (remotevideoTrack != null && audioTrack != null ) {
ToastMeVeryShort("running already");
}
else
ToastMeVeryShort("no connection");
return true;
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
if (remotevideoTrack != null && audioTrack != null ) {
ToastMeVeryShort("running already");
}
else
ToastMeVeryShort("no connection");
return true;
case KeyEvent.KEYCODE_DPAD_DOWN:
if (remotevideoTrack != null && audioTrack != null ) {
if (audioTrack != null) {
currentVolume = Math.max(currentVolume - 5, 0);
audioTrack.setVolume(currentVolume);
ToastMeVeryShort("volume:" + currentVolume);
}
}
else
ToastMeVeryShort("no connection");
return true;
case KeyEvent.KEYCODE_DPAD_RIGHT:
return super.onKeyDown(keyCode, event);
case KeyEvent.KEYCODE_DPAD_LEFT:
return super.onKeyDown(keyCode, event);
case KeyEvent.KEYCODE_BACK: {
if (remotevideoTrack != null && audioTrack != null ) {
ToastMeVeryShort("bye");
}
try {
SayByeAndClose();
} catch (Exception ex) {
Log.e(TAG, ex.toString());
}
try{
finish();
System.exit(0);
} catch (Exception ex) {
Log.e(TAG, ex.toString());
}
return true;
}
}
}
catch (Exception ex)
{
Log.e(TAG, ex.toString());
}
return false;
}
AndroidTV 应用程序支持并期望 Leanback 活动。此外,方向键需要最少的遥控器支持,如上、下、左、右、选择、后退和主页按钮。
方向键最小控制 电视设备的默认控制器是方向键。一般来说,您的应用程序应该可以通过只有上、下、左、右、选择、后退和主页按钮的遥控器进行操作。如果您的应用程序是一款通常需要带有附加控件的游戏控制器的游戏,则您的应用程序应尝试允许使用这些方向键控件进行游戏。在这种情况下,您的应用程序还应该警告用户需要控制器,并允许他们使用方向键控制器优雅地退出游戏。有关使用电视设备的方向键控制器处理导航的更多信息,请参阅创建电视导航。
将以下行添加到 AndroidManifest.xml 中的主要 Activity 可能有助于 Dpad 支持。
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
如果它不起作用并且这些行已在清单中,请分享您的清单文件。
我面临着同样的问题..我在fire tv和电视模拟器中进行了测试,我认为dpad功能很好..
这是我的清单文件
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hsvision.hsvplay.android.tv">
<!--
io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here.
-->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-feature android:name="android.hardware.touchscreen"
android:required="false"/>
<uses-feature android:name="android.hardware.faketouch"
android:required="false"/>
<uses-feature android:name="android.hardware.telephony"
android:required="false"/>
<uses-feature android:name="android.hardware.camera"
android:required="false"/>
<uses-feature android:name="android.hardware.nfc"
android:required="false"/>
<uses-feature android:name="android.hardware.location.gps"
android:required="false"/>
<uses-feature android:name="android.hardware.microphone"
android:required="false"/>
<uses-feature android:name="android.hardware.sensor"
android:required="false"/>
<uses-feature android:name="android.software.leanback"
android:required="true" />
<uses-feature android:name="android.hardware.wifi"
android:required="false"/>
<application
android:usesCleartextTraffic="true"
android:banner="@drawable/banner"
android:icon="@drawable/banner"
android:label="HSV PLAY TV"
android:theme="@style/Theme.Leanback">
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
<activity android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="@string/app_name" />
<activity
android:name="com.facebook.CustomTabActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="@string/fb_login_protocol_scheme" />
</intent-filter>
</activity>
<activity
android:exported="true"
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:windowSoftInputMode="adjustResize" >
<!--
Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI.
-->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" />
<!--
Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame.
-->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--
请勿删除下面的元数据。 Flutter工具使用它来生成GeneratePluginRegistrant.java -->