如何通过 TV Input Manager 访问整个 TV Provider 数据库?
How to access the entire TV Provider database by TV Input Manager?
根据 Android docs
TV Inputs provided and signed by the device manufacturer (signature
apps) or other apps installed in the system partition will have access
to the entire TV Provider database. This access can be used to
construct apps to browse and search across all available TV channels
and programs.
假设我注册为设备制造商或在系统分区中安装了应用程序,我如何访问 TvProvider 及其频道信息?
编辑:
val tifSupport: Boolean = packageManager.hasSystemFeature(PackageManager.FEATURE_LIVE_TV)
Log.d("XXX", "TIF Support ? $tifSupport")
这句话说的是真的。然后我 运行 这些行:
val tvInputManager = applicationContext.getSystemService(TV_INPUT_SERVICE) as TvInputManager?
Log.d("XXX", "TvInputManager $tvInputManager")
val il = tvInputManager?.tvInputList
Log.d("XXX", "TvInputList size --> ${il?.size}")
tvInputManager?.tvInputList?.forEach { info ->
Log.d("XXX", "TvInputListInfo ${info.id} ${info.serviceInfo} # ${info.extras.size()}")
}
第一个日志打印
TvInputManager android.media.tv.TvInputManager@95728c2
因此 tvInputManager 看起来有效。第二个显示 0 作为 TvInputList 大小,因此第三个日志(在 forEach() 中)根本 not 打印。
您必须从 Android 的背景开始。文档中的提供者是指 ContentProvider
,它将在 Android 内的进程之间共享信息。现在开始:
- 如果我们的系统支持电视供应商。
- 如果为应用程序设置了所有清单权限
- 如果应用程序安装在系统应用程序下(并且有正确的 SE 策略)
然后您就可以使用ContentProvider
获取您需要的各种信息。要查看对 TVContent Provider 的完整支持,您可以参考 this file(确保它与您的 Android OS 版本一致)和其他 AOSP 信息。例如
/**
* Returns the current list of channels your app provides.
*
* @param resolver Application's ContentResolver.
* @return List of channels.
*/
public static List<Channel> getChannels(ContentResolver resolver) {
List<Channel> channels = new ArrayList<>();
// TvProvider returns programs in chronological order by default.
Cursor cursor = null;
try {
cursor = resolver.query(Channels.CONTENT_URI, Channel.PROJECTION, null, null, null);
if (cursor == null || cursor.getCount() == 0) {
return channels;
}
while (cursor.moveToNext()) {
channels.add(Channel.fromCursor(cursor));
}
} catch (Exception e) {
Log.w(TAG, "Unable to get channels", e);
} finally {
if (cursor != null) {
cursor.close();
}
}
return channels;
}
另一个例子
TvInputManager tv = (TvInputManager)getApplicationContext().getSystemService(Context.TV_INPUT_SERVICE);
List<TvInputInfo> list = tv.getTvInputList();
String[] projection = {
TvContract.Channels._ID,
TvContract.Channels.COLUMN_DISPLAY_NUMBER
};
ContentResolver cr = getContentResolver();
Iterator<TvInputInfo> it = list.iterator();
while(it.hasNext()) {
TvInputInfo aux = it.next();
Uri uri = TvContract.buildChannelsUriForInput(aux.getId());
Log.d("TAG", uri.toString());
Log.d("TAG", aux.toString());
Cursor cur = cr.query(uri, projection, null, null ,null);
Log.d("TAG", cur.toString());
if(cur.moveToFirst()) {
Log.d("TAG", "not empty cursors");
}
}
更新:
你应该拥有的基本权限(另见official documentation):
<uses-permission android:name="com.android.providers.tv.permission.READ_EPG_DATA" />
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
<uses-permission android:name="com.android.providers.tv.permission.ACCESS_ALL_EPG_DATA"/>
根据 Android docs
TV Inputs provided and signed by the device manufacturer (signature apps) or other apps installed in the system partition will have access to the entire TV Provider database. This access can be used to construct apps to browse and search across all available TV channels and programs.
假设我注册为设备制造商或在系统分区中安装了应用程序,我如何访问 TvProvider 及其频道信息?
编辑:
val tifSupport: Boolean = packageManager.hasSystemFeature(PackageManager.FEATURE_LIVE_TV)
Log.d("XXX", "TIF Support ? $tifSupport")
这句话说的是真的。然后我 运行 这些行:
val tvInputManager = applicationContext.getSystemService(TV_INPUT_SERVICE) as TvInputManager?
Log.d("XXX", "TvInputManager $tvInputManager")
val il = tvInputManager?.tvInputList
Log.d("XXX", "TvInputList size --> ${il?.size}")
tvInputManager?.tvInputList?.forEach { info ->
Log.d("XXX", "TvInputListInfo ${info.id} ${info.serviceInfo} # ${info.extras.size()}")
}
第一个日志打印
TvInputManager android.media.tv.TvInputManager@95728c2
因此 tvInputManager 看起来有效。第二个显示 0 作为 TvInputList 大小,因此第三个日志(在 forEach() 中)根本 not 打印。
您必须从 Android 的背景开始。文档中的提供者是指 ContentProvider
,它将在 Android 内的进程之间共享信息。现在开始:
- 如果我们的系统支持电视供应商。
- 如果为应用程序设置了所有清单权限
- 如果应用程序安装在系统应用程序下(并且有正确的 SE 策略)
然后您就可以使用ContentProvider
获取您需要的各种信息。要查看对 TVContent Provider 的完整支持,您可以参考 this file(确保它与您的 Android OS 版本一致)和其他 AOSP 信息。例如
/**
* Returns the current list of channels your app provides.
*
* @param resolver Application's ContentResolver.
* @return List of channels.
*/
public static List<Channel> getChannels(ContentResolver resolver) {
List<Channel> channels = new ArrayList<>();
// TvProvider returns programs in chronological order by default.
Cursor cursor = null;
try {
cursor = resolver.query(Channels.CONTENT_URI, Channel.PROJECTION, null, null, null);
if (cursor == null || cursor.getCount() == 0) {
return channels;
}
while (cursor.moveToNext()) {
channels.add(Channel.fromCursor(cursor));
}
} catch (Exception e) {
Log.w(TAG, "Unable to get channels", e);
} finally {
if (cursor != null) {
cursor.close();
}
}
return channels;
}
另一个例子
TvInputManager tv = (TvInputManager)getApplicationContext().getSystemService(Context.TV_INPUT_SERVICE);
List<TvInputInfo> list = tv.getTvInputList();
String[] projection = {
TvContract.Channels._ID,
TvContract.Channels.COLUMN_DISPLAY_NUMBER
};
ContentResolver cr = getContentResolver();
Iterator<TvInputInfo> it = list.iterator();
while(it.hasNext()) {
TvInputInfo aux = it.next();
Uri uri = TvContract.buildChannelsUriForInput(aux.getId());
Log.d("TAG", uri.toString());
Log.d("TAG", aux.toString());
Cursor cur = cr.query(uri, projection, null, null ,null);
Log.d("TAG", cur.toString());
if(cur.moveToFirst()) {
Log.d("TAG", "not empty cursors");
}
}
更新:
你应该拥有的基本权限(另见official documentation):
<uses-permission android:name="com.android.providers.tv.permission.READ_EPG_DATA" />
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
<uses-permission android:name="com.android.providers.tv.permission.ACCESS_ALL_EPG_DATA"/>