智能电视TV开发---客户端和服务器通信里面我们实现了客户端和服务端的简单通信,接下来我们做一个简单的客户端界面,来实现手机端来操控智能电视的TV端。

一、存储视频的结构设计

我们在做客户端的时候,通常是需要存储视频的相关信息,结构如下:

package com.jwzhangjie.smarttv_client.model;

import android.os.Parcel;
import android.os.Parcelable; public class LiveModel implements Parcelable{ /**
* 数据库位置
*/
private int db_id;
/**
* 直播频道的id
*/
private int channel_id;
/**
* 直播频道的名称
*/
private String channel_name;
/**
* 直播频道的url
*/
private String icon_url;
/**
* 直播频道的省份
*/
private String province;
/**
* 直播频道清晰度
*/
private String mode;
/**
* 直播频道的链接
*/
private String url;
/**
* 直播频道的second_url
*/
private String second_url;
/**
* 直播频道所属的类型
*/
private String types; public LiveModel(){ }
private LiveModel(Parcel parcel){
readFromParcel(parcel);
}
@Override
public int describeContents() {
return 0;
} public void readFromParcel(Parcel parcel){
db_id = parcel.readInt();
channel_id = parcel.readInt();
channel_name = parcel.readString();
icon_url = parcel.readString();
province = parcel.readString();
mode = parcel.readString();
url = parcel.readString();
second_url = parcel.readString();
types = parcel.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(db_id);
dest.writeInt(channel_id);
dest.writeString(channel_name);
dest.writeString(icon_url);
dest.writeString(province);
dest.writeString(mode);
dest.writeString(url);
dest.writeString(second_url);
dest.writeString(types);
} public static Creator<LiveModel> CREATOR = new Creator<LiveModel>() { @Override
public LiveModel createFromParcel(Parcel source) {
return new LiveModel(source);
} @Override
public LiveModel[] newArray(int size) {
return new LiveModel[size];
}
}; public int getDb_id() {
return db_id;
}
public void setDb_id(int db_id) {
this.db_id = db_id;
}
public int getChannel_id() {
return channel_id;
}
public void setChannel_id(int channel_id) {
this.channel_id = channel_id;
}
public String getChannel_name() {
return channel_name;
}
public void setChannel_name(String channel_name) {
this.channel_name = channel_name;
}
public String getIcon_url() {
return icon_url;
}
public void setIcon_url(String icon_url) {
this.icon_url = icon_url;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getMode() {
return mode;
}
public void setMode(String mode) {
this.mode = mode;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getSecond_url() {
return second_url;
}
public void setSecond_url(String second_url) {
this.second_url = second_url;
}
public String getTypes() {
return types;
}
public void setTypes(String types) {
this.types = types;
} }

二、数据库设计

  接下来我们设计数据库表格,代码如下:

package com.jwzhangjie.smarttv_client.db;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Environment; public class DBHelper extends SQLiteOpenHelper{ private static final String NAME = "tv_jie.sqlite";
public static final String DB_PATH = Environment.getExternalStorageDirectory() + "/";
private static final int DB_VERSION = 1;
public static final String LIVE_VIDEO="CREATE TABLE live_video " +
"('db_id' INTEGER PRIMARY KEY AUTOINCREMENT, 'channel_id' INTEGER," +
" 'channel_name' VARCHAR, 'icon_url' VARCHAR, 'province' VARCHAR, 'mode' VARCHAR, " +
"'url' VARCHAR, 'second_url' VARCHAR, 'types' VARCHAR)"; public DBHelper(Context context) {
super(context, DB_PATH + NAME, null, DB_VERSION);
} public DBHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
} @Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(LIVE_VIDEO);
} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF live_video");
} }

三、调用数据库,首先数据的插入,或直播,获取直播的个数

package com.jwzhangjie.smarttv_client.utils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List; import com.jwzhangjie.smarttv_client.db.DBHelper;
import com.jwzhangjie.smarttv_client.model.LiveVideoModel; import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; public class DBUtils implements Serializable{ private static final long serialVersionUID = 1L; private static DBHelper mDBHelper; public DBUtils(Context paramContext) {
mDBHelper = new DBHelper(paramContext);
} public void close() {
if (mDBHelper != null) {
mDBHelper.close();
}
} public void insertLiveVideo(LiveVideoModel liveModel){
SQLiteDatabase db = null;
try {
db = mDBHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("channel_id", liveModel.getChannel_id());
contentValues.put("channel_name", liveModel.getChannel_name());
contentValues.put("icon_url", liveModel.getIcon_url());
contentValues.put("province", liveModel.getProvince());
contentValues.put("mode", liveModel.getMode());
contentValues.put("url", liveModel.getUrl());
contentValues.put("second_url", liveModel.getSecond_url());
contentValues.put("types", liveModel.getTypes());
db.insertOrThrow("live_video", null, contentValues);
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 获取所有的直播视频的个数
* @return
*/
public int getMovieCount() {
SQLiteDatabase db = mDBHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT count(*) FROM live_video", null);
cursor.moveToNext();
int coutn = cursor.getInt(0);
cursor.close();
db.close();
return coutn;
} public List<LiveVideoModel> getLiveVideoModels(){
List<LiveVideoModel> listData = new ArrayList<LiveVideoModel>();
try {
SQLiteDatabase db = mDBHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM live_video", null);
while (cursor.moveToNext()) {
LiveVideoModel mVideoModel = new LiveVideoModel();
mVideoModel.setDb_id(cursor.getInt(0));
mVideoModel.setChannel_id(cursor.getInt(1));
mVideoModel.setChannel_name(cursor.getString(2));
mVideoModel.setIcon_url(cursor.getString(3));
mVideoModel.setProvince(cursor.getString(4));
mVideoModel.setMode(cursor.getString(5));
mVideoModel.setUrl(cursor.getString(6));
mVideoModel.setSecond_url(cursor.getString(7));
mVideoModel.setTypes(cursor.getString(8));
listData.add(mVideoModel);
}
} catch (Exception e) {
e.printStackTrace();
}
return listData;
} }

具体的数据自己去填充,这里我就不提供了,各大视频论坛都分享

四、客户端视频数据的显示

  这里已经假设数据库已经有数据了,界面很简单就是一个listView来显示,自定义一个adapter

4.1ListView中Item的设计

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ImageView
android:id="@+id/item_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="center"
android:layout_centerVertical="true"
android:src="@drawable/widget_progress_medium_rotation_image"
android:contentDescription="@string/app_name"
/>
<ImageView
android:id="@+id/arrow_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/arrow_right"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dip"
android:contentDescription="@string/app_name"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/item_icon"
android:layout_toLeftOf="@id/arrow_right"
android:orientation="vertical"
android:gravity="center_vertical"
android:layout_centerVertical="true"
android:layout_marginLeft="10dip"
>
<TextView
android:id="@+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="title"
/>
<TextView
android:id="@+id/item_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="subtitle"
/>
</LinearLayout>
</RelativeLayout>

4.2网络图片加载方式

这里涉及的直播频道的图标都是网络图片,所以要实现加载网络图片的功能,这里我使用的是网络一个开源的库com.nostra13.universalimageloader,在网上一搜就能看见,所以要使用它我们要配置一些内容。

首先编写一个类继承Application,然后再AndroidManifest.xml里面设置Application的name属性,代码如下:

package com.jwzhangjie.smarttv_client.utils;

import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType; import android.app.Application;
import android.content.Context; public class SmartTV_App extends Application { @Override
public void onCreate() {
super.onCreate();
initImageLoader(getApplicationContext());
} public static void initImageLoader(Context context) {
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
context).threadPriority(Thread.NORM_PRIORITY - 2)
.denyCacheImageMultipleSizesInMemory()
.discCacheFileNameGenerator(new Md5FileNameGenerator())
.tasksProcessingOrder(QueueProcessingType.LIFO)
.writeDebugLogs() // Remove for release app
.build();
ImageLoader.getInstance().init(config);
}
}

4.3ListView的adapter设计

package com.jwzhangjie.smarttv_client.adapter;

import java.util.List;

import com.jwzhangjie.smarttv_client.R;
import com.jwzhangjie.smarttv_client.model.LiveVideoModel;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader; import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView; public class LiveVideoAdapter extends BaseAdapter{ private LayoutInflater mInflater;
private List<LiveVideoModel> listDatas;
private ImageLoader imageLoader = ImageLoader.getInstance();
private DisplayImageOptions options;
public LiveVideoAdapter(Context context){
mInflater = LayoutInflater.from(context);
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.img_loading_bg)
.showImageForEmptyUri(R.drawable.img_loading_empty)
.showImageOnFail(R.drawable.img_loading_error)
.cacheInMemory(true)
.cacheOnDisc(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
} public void updateListDatas(List<LiveVideoModel> listDatas){
this.listDatas = listDatas;
notifyDataSetChanged();
}
@Override
public int getCount() {
return listDatas == null ?0:listDatas.size();
} @Override
public Object getItem(int position) {
return listDatas.get(position);
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = mInflater.inflate(R.layout.item_live, null);
viewHolder.item_icon = (ImageView)convertView.findViewById(R.id.item_icon);
viewHolder.item_arrow = (ImageView)convertView.findViewById(R.id.arrow_right);
viewHolder.item_title = (TextView)convertView.findViewById(R.id.item_title);
viewHolder.item_subtitle = (TextView)convertView.findViewById(R.id.item_subtitle);
convertView.setTag(viewHolder);
}else {
viewHolder = (ViewHolder)convertView.getTag();
}
LiveVideoModel videoModel = listDatas.get(position);
viewHolder.item_title.setText(videoModel.getChannel_name());
viewHolder.item_subtitle.setText("省份:"+videoModel.getProvince());
imageLoader.displayImage(videoModel.getIcon_url(), viewHolder.item_icon, options);
return convertView;
} class ViewHolder{
private ImageView item_icon;
private ImageView item_arrow;
private TextView item_title;
private TextView item_subtitle;
} }

4.4主界面布局设计

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Smart_TV_Client" > <RelativeLayout
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="60dip"
android:background="#d0d0d0"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="直播界面测试"
android:layout_centerInParent="true"
android:textSize="16sp"
android:textStyle="bold"
/>
</RelativeLayout>
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/title"
android:cacheColorHint="#00000000"
android:divider="@drawable/cbox_uc_divider"
android:fadeScrollbars="false"
android:fastScrollEnabled="false"
android:focusable="true"
android:focusableInTouchMode="true"
android:scrollbars="none"
android:scrollingCache="false"
></ListView>
</RelativeLayout>

4.5 主界面代码编写

这里就是这章最后的一步,调用数据库数据,然后传值给adapter,显示在listview上面
package com.jwzhangjie.smarttv_client;

import java.util.List;

import com.jwzhangjie.smarttv_client.adapter.LiveVideoAdapter;
import com.jwzhangjie.smarttv_client.model.LiveVideoModel;
import com.jwzhangjie.smarttv_client.utils.DBUtils; import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.Window;
import android.widget.ListView; public class Smart_TV_Client extends Activity { private ListView listView;
private LiveVideoAdapter adapter;
private DBUtils dbUtils;
private List<LiveVideoModel> listDatas;
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_smart__tv__client);
dbUtils = new DBUtils(this);
initView();
loadData();
} public void initView(){
adapter = new LiveVideoAdapter(this);
listView = (ListView)findViewById(R.id.listview);
listView.setAdapter(adapter);
} public void loadData(){
new loadData().execute();
} private class loadData extends AsyncTask<Void, Void, Void>{
@Override
protected Void doInBackground(Void... params) {
listDatas = dbUtils.getLiveVideoModels();
return null;
} @Override
protected void onPostExecute(Void result) {
adapter.updateListDatas(listDatas);
super.onPostExecute(result);
} }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.smart__tv__client, menu);
return true;
} }

5.显示效果





智能电视TV开发---直播视频客户端结构设计和实现的更多相关文章

  1. 智能电视TV开发---客户端和服务器通信

    在做智能电视应用的时候,最头疼的就是焦点问题,特别是对于个人开发者,没有设备这是最最头疼的事情了,在没有设备的情况下,怎么实现智能电视应用呢,接下来我是用TV程序来做演示的,所以接下来的所有操作是在有 ...

  2. 智能电视TV开发---如何实现程序省电

    对于很多使用智能手机的用户来,很多抱怨手机耗电太快,很多人买手机的时候卖家都是推荐买两块电池,还有如果用户留心的话,在买手机的网页上,卖家会显示播放视频多长时间,听音乐多长时间,待机多长时间,不过看的 ...

  3. H5活动全屏滚动页面在安卓智能电视TV调试

    前段时间公司做一个线上活动,在电视上商品促销.产品的要求是每个商品介绍刚好满一屏,按下遥控器向下键可以整屏切换.这种功能如果实在PC端,实现起来非常容易,引用jQuery插件就能实现.但是在安卓智能电 ...

  4. 安卓TV开发(十) 智能电视开发之在线视频直播

    转载注明出处:http://blog.csdn.net/sk719887916/article/details/46582987 从<安卓TV开发(八) 移动智能终端多媒体之在线加载网页视频源& ...

  5. 安卓Tv开发(一)移动智能电视之焦点控制(触控事件)

    前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家居,以及可穿戴设备的大量使用,但是这些设备上的开发并不是和传统手机开发一样,特别是焦点控制和用户操作体验风格上有很大的区别,本系列博 ...

  6. 安卓Tv开发(二)移动智能电视之焦点控制(按键事件)

    原文:http://blog.csdn.net/sk719887916/article/details/44781475 skay 前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家 ...

  7. 安卓TV开发(概述) 智能电视之视觉设计和体验分析

         转载说明出处 :http://blog.csdn.net/sk719887916, 作者:skay 前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家居,以及可穿戴设备的大 ...

  8. 安卓TV开发(四) 实现主流智能TV视频播放器UI

    前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家居,以及可穿戴设备的大量使用,但是这些设备上的开发并不是和传统手机开发一样,特别是焦点控制和用户操作体验上有很大的区别,本系列博文主 ...

  9. 联发科发布全球首款搭载Android TV的智能电视系统芯片MT5595

    联发科发布全球首款搭载Android TV的智能电视系统芯片MT5595 admin 资讯 01-07 1 1月7日消息,联发科宣布与Google共同开发出全世界第一个搭载Android TV操作系统 ...

随机推荐

  1. 关于cocos2dx 3.0升级崩溃报错(unable to load native library) 和(Fatal signal 11 (SIGSEGV) at 0x00000000)

    近期一直在Windows平台开发cocos-2dx游戏,期间做了一次引擎升级,升级到了3.0正式版本号.Windows平台上表现非常正常,没有出现什么问题. 上周五准备公布一个安卓包,编译非常轻松的就 ...

  2. Swfit中视图跳转

    .跳转到任一UIViewController var sb = UIStoryboard(name: "Main", bundle:nil) var vc = sb.instant ...

  3. .NET程序员生活开始

    不知不觉,开始踏入程序员生活了!加油吧.有关Session的好文章: 最近这两天被一个Web Farm环境下的Session处理问题虐得很痛苦,网上到处找解决方案,在无意中翻看到这篇文章,感觉很不错, ...

  4. 关于Resharper的使用经验

    发现Resharper这东西真的有点累赘,重构也是,一开始用会有很多莫名其妙的提示.现在的项目用了Resharper,js是很方便,有定位功能,但连TypeScript的js都有了.

  5. uri 和 url 的区别

    uri 统一资源标识符,值是唯一标识资源的任意字符,比如guid url 统一资源定位符,值是标识资源的字符串,但是包含定位信息,比如http://localhost/index.html

  6. android webview点击返回键返回上一级activity

    android webview点击返回键返回上一个activity @Override public boolean onKeyDown(int keyCode, KeyEvent event) { ...

  7. 关于智能指针auto_ptr

    智能指针auto_ptr和shared_ptr也是面试中经常被问到的一个 感觉看auto_ptr的源码反而更加容易理解一些,因为源码的代码量并不大,而且比较容易理解. 本篇主要介绍auto_ptr 其 ...

  8. Windows中的对象

    来源  http://www.0xaa55.com/forum.php?mod=viewthread&tid=1401&extra=page%3D1  windows里常用句柄操作资源 ...

  9. error C4996 The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name

    error C4996: 'strupr': The POSIX name for this item is deprecated. Instead, use the ISO C and C++ co ...

  10. iOS移动支付——支付宝支付

    这篇博客总结得很好,我只对在iOS上集成支付宝做简洁的步骤总结. http://www.it165.net/pro/html/201402/9376.html iOS集成支付宝支付的步骤: 准备工作的 ...