制作一个android tv launcher应用程序需要什么?



我找不到任何关于如何为android电视制作启动应用程序的教程。所以我选择了一个视频,展示了如何制作一个手机启动器应用程序,这是视频。

然而,我并没有完全复制视频中的代码,因为我知道android电视应用程序所需的依赖关系和库。主要问题是我的电视模拟器没有显示更改启动器的选项。在视频中,它显示在20:19模拟器打开后,按下home键询问使用哪个启动器,但我没有得到任何这样的对话框后按下home键,我也没有得到任何错误,所以我几乎被困在这里。

App默认不启动任何activity

代码如下:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tvapp.myapplication">
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<uses-feature
android:name="android.software.leanback"
android:required="true" />
<application
android:allowBackup="true"
android:banner="@drawable/banner"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication">
<activity
android:name=".AppListActivity"
android:exported="true">
<intent-filter>
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTask"
android:stateNotNeeded="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>

themes.xml

<resources>
<style name="Theme.MyApplication" parent="@style/Theme.Leanback.Browse" />
</resources>

MainActivity

public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = findViewById(R.id.button);
btn.setOnClickListener(view -> {
Intent intent = new Intent(getApplicationContext(), AppListActivity.class);
startActivity(intent);
});
}
@Override
public void onBackPressed() {
// do nothing
}
}

AppListActivity

public class AppListActivity extends FragmentActivity {
private PackageManager manager;
private List<Item> apps;
private ListView list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_app_list);
loadApps();
loadListView();
addClickListener();
}
private void loadApps() {
manager = getPackageManager();
apps = new ArrayList<>();
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LEANBACK_LAUNCHER);
List<ResolveInfo> availableActivities = manager.queryIntentActivities(intent, 0);
for(ResolveInfo ri : availableActivities) {
Item app = new Item();
app.label = ri.activityInfo.packageName;
app.name = ri.loadLabel(manager);
app.icon = ri.loadIcon(manager);
apps.add(app);
}
}
private void loadListView() {
list = findViewById(R.id.list);
ArrayAdapter<Item> adapter = new ArrayAdapter<Item>(this, R.layout.item, apps) {
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent)
{
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.item, null);
}
ImageView appIcon = convertView.findViewById(R.id.icon);
appIcon.setImageDrawable(apps.get(position).icon);
TextView appName = convertView.findViewById(R.id.name);
appName.setText(apps.get(position).name);
return convertView;
}
};
list.setAdapter(adapter);
}
private void addClickListener() {
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = manager.getLaunchIntentForPackage(apps.get(position).label.toString());
startActivity(intent);
}
});
}
}

Item.java

public class Item {
CharSequence label;
CharSequence name;
Drawable icon;
}

主活动布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="APPS" />
</RelativeLayout>

AppListActivity布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".AppListActivity">

<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/list"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:background="#ffffff">
</ListView>
</LinearLayout>

项目布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:padding="10dp">

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/icon"
android:scaleType="centerInside" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/name"
android:layout_marginTop="10dp"
android:textSize="18sp" />
</LinearLayout>

android.intent.category.HOME.DEFAULT类别应该在AppListActivity意图过滤器(有LEANBACK_LAUNCHER)中,以指示您的应用程序是TV的启动器设备。

最新更新