智能电视TV开发---直播视频客户端结构设计和实现

来源:互联网 发布:高达w 知乎 编辑:程序博客网 时间:2024/04/27 20:12

在智能电视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);}@Overridepublic 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();}@Overridepublic 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>() {@Overridepublic LiveModel createFromParcel(Parcel source) {return new LiveModel(source);}@Overridepublic 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);}@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(LIVE_VIDEO);}@Overridepublic 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 {@Overridepublic 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();}@Overridepublic int getCount() {return listDatas == null ?0:listDatas.size();}@Overridepublic Object getItem(int position) {return listDatas.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic 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;@Overrideprotected 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>{@Overrideprotected Void doInBackground(Void... params) {listDatas = dbUtils.getLiveVideoModels();return null;}@Overrideprotected void onPostExecute(Void result) {adapter.updateListDatas(listDatas);super.onPostExecute(result);}}@Overridepublic 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.显示效果




4 0
原创粉丝点击