当前位置: 首页 > 工具软件 > tv > 使用案例 >

Android TV系列 TV APP分析(二)

郭兴平
2023-12-01

在ATV SDK中,TV APP也是一个比较重要的apk,他负责显示各种输入源,比如HDMI IN输入,AV IN输入,因为要显示不同的源,具体硬件平台又步一样,所以一定会涉及到相关定义。每一个不同的芯片,其TV APK都需要定制。本系列文章基于amlogic ATV SDK,分析amlogic  平台上是如何实现显示切换的。

Android TV系列 TV APP分析(一)

一、概述

代码位置:packages\apps\TV

参考Android TV系列 TV APP分析(一),显示输入源一般需要一个TvInputManager 类,一个
TvView 类负责显示,下面看看TV APP 中一些文件的具体作用

tv\MainActivity.java --主Activity

tv\util\TvInputManagerHelper.java--TvInputManager管理类

ui\AppLayerTvView.java-TvView的子类

ui\TunableTvView.java-AppLayerTvView的子类

TV的layout主要的控件就是TunableTvView,下面是activity_tv.xml的布局

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:foreground="@android:color/transparent"
    android:keepScreenOn="true">

    <com.android.tv.ui.TunableTvView android:id="@+id/main_tunable_tv_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start|center_vertical" />

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

    <include layout="@layout/menu" />
    <include layout="@layout/option_container" />
    <include layout="@layout/program_guide" />
    <FrameLayout android:id="@+id/fragment_container"
        android:layout_height="match_parent"
        android:layout_width="match_parent"/>
</FrameLayout>

因为是基于Amlogic 平台分析,amlogic 还增加的部分平台部分内容,这部分的核心类

QuickKeyInfo.java。

二、TV app 启动

TV app 在 AndroidManifest.xml定义一个隐式的action,android.media.tv.action.SETUP_INPUTS

 <activity
            android:name="com.android.tv.MainActivity"
            android:configChanges="keyboard|keyboardHidden|screenSize|smallestScreenSize|screenLayout|orientation"
            android:launchMode="singleTask"
            android:resizeableActivity="true"
            android:screenOrientation="landscape"
            android:supportsPictureInPicture="true"
            android:theme="@style/Theme.TV.MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="vnd.android.cursor.item/channel" />
                <data android:mimeType="vnd.android.cursor.dir/channel" />
                <data android:mimeType="vnd.android.cursor.item/program" />
                <data android:mimeType="vnd.android.cursor.dir/program" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.media.tv.action.SETUP_INPUTS" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.SEARCH" />
            </intent-filter>

TV APP的启动通发送上述隐式的action启动,这个隐式的action为:TvInputManager.ACTION_SETUP_INPUTS:(ction,android.media.tv.action.SETUP_INPUTS)

例如希望TV显示HDMI IN1 源信号,需要如下启动

Intent mIntent = new Intent(TvInputManager.ACTION_SETUP_INPUTS);
//下面的都是amlogic自定义的
//amlogic会根据下面实现tune
mIntent.putExtra("from_tv_source", true);
mIntent.putExtra(TvInputInfo.EXTRA_INPUT_ID, "com.droidlogic.tvinput/.services.Hdmi1InputService/HW5");
mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(mIntent);

上述代码最终会调用TV的MainActivity.java,并进入OnCreate。OnCreate的关键作用就是要调用TvView的tune函数,实现显示源的切换。

三、OnCreate

OnCreate关键是创建了TvInputManagerHelper,TvView,amlogic 定制类QuickKeyInfo

  @Override
    protected void onCreate(Bundle savedInstanceState) {
       
        //TvInputManager管理类
        mTvInputManagerHelper = tvApplication.getTvInputManagerHelper();
        //TvView显示类
        mTvView = (TunableTvView) findViewById(R.id.main_tunable_tv_view);
        mTvView.initialize(mProgramDataManager, mTvInputManagerHelper);
        
        
        //amlogic的定制类
        mQuickKeyInfo = new QuickKeyInfo(MainActivity.this, mTvInputManagerHelper, mChannelTuner);
        mQuickKeyInfo.registerCommandReceiver();
       
        mTvViewUiManager.restoreDisplayMode(false);
        //进一步处理Intent内容
        if (!handleIntent(getIntent())) {
            finish();
            return;
        }

handleIntent处理启动时传递的信息,这个信息主要时tune信息,handleIntent是原生函数,再该函数内,amlogic进行了拦截处理

// It should be called before onResume.
    private boolean handleIntent(Intent intent) {
        // Reset the closed caption settings when the activity is 1)created or 2) restarted.
        // And do not reset while TvView is playing.
        if (!mTvView.isPlaying()) {
            mCaptionSettings = new CaptionSettings(this);
        }
        mShouldTuneToTunerChannel = intent.getBooleanExtra(Utils.EXTRA_KEY_FROM_LAUNCHER, false);
        mInitChannelUri = null;

        String extraAction = intent.getStringExtra(Utils.EXTRA_KEY_ACTION);
        if (!TextUtils.isEmpty(extraAction)) {
            if (DEBUG) Log.d(TAG, "Got an extra action: " + extraAction);
            if (Utils.EXTRA_ACTION_SHOW_TV_INPUT.equals(extraAction)) {
                String lastWatchedChannelUri = Utils.getLastWatchedChannelUri(this);
                if (lastWatchedChannelUri != null) {
                    mInitChannelUri = Uri.parse(lastWatchedChannelUri);
                }
                mShowSelectInputView = true;
            }
        }
        
        if (TvInputManager.ACTION_SETUP_INPUTS.equals(intent.getAction())) {
            //当action为ACTION_SETUP_INPUTS时,由mQuickKeyInfo来处理
            if (mQuickKeyInfo.handleUiCommand(intent)) {
                return true;
            }

 类似资料: