下载视频到本地播放,是任何软件必不可少的部分。在YoukuPlayerOpenSDK的DownloadManager中对于下载缓存等以及有一部分处理了,在这里我暂时不修改该部分。先用DownloadManager类让我们能够下载下视频。
在这之前我有讲到过应用主界面下方的Tab是用FragmentManager完成的,没有使用到ViewPage。我们先在Fragment中嵌套使用ViewPage,完成下载界面的编写。
嵌套ViewPage的Fragment,DownFragment.java:
package com.jgh.watchdota;
import java.util.ArrayList;
import com.jgh.util.MyFragmentPagerAdapter;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.app.Activity;
import android.content.res.Resources;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.TextView;
public class DownFragment extends Fragment {
Resources resources;
private ViewPager mPager;
private ArrayList<Fragment> fragmentsList;
private ImageView ivBottomLine;
private TextView tvTabNew, tvTabHot;
private int currIndex = 0;
private int bottomLineWidth;
private int offset = 0;
private int position_one;
public final static int num = 2;
Fragment home1;
Fragment home2;
private Activity mActivity;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
Log.i("jiangguohu","DownFragment create");
View view = inflater
.inflate(R.layout.layout_download, container, false);
mActivity = getActivity();
resources = getResources();
InitWidth(view);
InitTextView(view);
InitViewPager(view);
Log.i("jiangguohu","onCreateView position_one = "+position_one+",,,,offset = "+offset);
TranslateAnimation animation = new TranslateAnimation(position_one,
offset, 0, 0);
// tvTabHot.setTextColor(resources.getColor(R.color.lightwhite));
animation.setFillAfter(true);
animation.setDuration(300);
ivBottomLine.startAnimation(animation);
return view;
}
private void InitTextView(View parentView) {
tvTabNew = (TextView) parentView.findViewById(R.id.tv_tab_1);
tvTabHot = (TextView) parentView.findViewById(R.id.tv_tab_2);
tvTabNew.setOnClickListener(new MyOnClickListener(0));
tvTabHot.setOnClickListener(new MyOnClickListener(1));
}
private void InitViewPager(View parentView) {
mPager = (ViewPager) parentView.findViewById(R.id.vPager);
fragmentsList = new ArrayList<Fragment>();
home1 = new DownCachedFragment(mActivity);
home2 = new DownCachingFragment(mActivity);
fragmentsList.add(home1);
fragmentsList.add(home2);
mPager.setAdapter(new MyFragmentPagerAdapter(getChildFragmentManager(),
fragmentsList));
mPager.setOnPageChangeListener(new MyOnPageChangeListener());
mPager.setCurrentItem(0);
}
private void InitWidth(View parentView) {
ivBottomLine = (ImageView) parentView.findViewById(R.id.iv_bottom_line);
bottomLineWidth = ivBottomLine.getLayoutParams().width;
DisplayMetrics dm = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
int screenW = dm.widthPixels;
offset = (int) ((screenW / num - bottomLineWidth) / 2);
int avg = (int) (screenW / num);
position_one = avg + offset;
}
public class MyOnClickListener implements View.OnClickListener {
private int index = 0;
public MyOnClickListener(int i) {
index = i;
}
@Override
public void onClick(View v) {
mPager.setCurrentItem(index);
}
};
public class MyOnPageChangeListener implements OnPageChangeListener {
@Override
public void onPageSelected(int arg0) {
Animation animation = null;
switch (arg0) {
case 0:
if (currIndex == 1) {
Log.i("jiangguohu","currIndex == 1 position_one = "+position_one+",,,,offset = "+offset);
animation = new TranslateAnimation(position_one, offset, 0,
0);
// tvTabHot.setTextColor(resources.getColor(R.color.lightwhite));
}
// tvTabNew.setTextColor(resources.getColor(R.color.white));
break;
case 1:
if (currIndex == 0) {
Log.i("jiangguohu","currIndex == 0 position_one = "+position_one+",,,,offset = "+offset);
animation = new TranslateAnimation(offset, position_one, 0,
0);
// tvTabNew.setTextColor(resources.getColor(R.color.lightwhite));
}
// tvTabHot.setTextColor(resources.getColor(R.color.white));
break;
}
currIndex = arg0;
animation.setFillAfter(true);
animation.setDuration(300);
ivBottomLine.startAnimation(animation);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
}
}
在上面中嵌套了两个Fragment,DownCachedFragment、DownCachingFragment。分别表示已经下载完成、正在下载的视频文件。需要注意的是,在这里所有的Fragment引用的都是support.v4下面的Fragment类,而不是android.app下面的。
再看看其中ViewPage的Adapter类:
package com.jgh.util;
import java.util.ArrayList;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> fragmentsList;
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
public MyFragmentPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragments) {
super(fm);
this.fragmentsList = fragments;
}
@Override
public int getCount() {
return fragmentsList.size();
}
@Override
public Fragment getItem(int arg0) {
return fragmentsList.get(arg0);
}
@Override
public int getItemPosition(Object object) {
return super.getItemPosition(object);
}
}
上一个布局文件吧,layout_download.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="5dip"
android:paddingTop="10dip" >
<TextView
android:id="@+id/tv_tab_1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1.0"
android:gravity="center"
android:text="已经下载"
android:textSize="18sp" />
<TextView
android:id="@+id/tv_tab_2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1.0"
android:gravity="center"
android:text="正在下载"
android:textSize="18sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="vertical"
android:paddingBottom="3dip" >
<ImageView
android:id="@+id/iv_bottom_line"
android:layout_width="40dip"
android:layout_height="2dip"
android:scaleType="matrix"
android:src="#000" />
</LinearLayout>
</LinearLayout>
<android.support.v4.view.ViewPager
android:id="@+id/vPager"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_gravity="center"
android:layout_weight="1.0"
android:background="#F0F3F6"
android:flipInterval="30"
android:persistentDrawingCache="animation" />
</LinearLayout>
就这样,我们就将两个Fragment嵌套进入一个Fragment里面了,而且这两个Fragment还能够左右滑动切换。接下来我们只需要在这两个Fragment中实现自己的下载方法就行了。
再来说说运用优酷API,如何下载视频吧。其实在优酷给的demo中的PlayerActivity.java里面点击下载按钮是会运行到:
/**
* 简单展示下载接口的使用方法,用户可以根据自己的 通过DownloadManager下载视频
*/
private void doDownload() {
// 通过DownloadManager类实现视频下载
DownloadManager d = DownloadManager.getInstance();
d.setCanUse3GDownload(true);// 设置是否允许2G、3G、4G模式下下载视频
d.setDownloadFormat(7);// 设置下载视频的格式,7为高清
/**
* 第一个参数为需要下载的视频id 第二个参数为该视频的标题title 第三个对下载视频结束的监听,可以为空null
*/
d.createDownload(itemDate.getId(), itemDate.getTitle(),
new OnCreateDownloadListener() {
@Override
public void onfinish(boolean isNeedRefresh) {
// TODO Auto-generated method stub
}
});
}
当createDownload之后优酷API里的DownloadService就会进行下载了。同时,你需要在AndroidManifest中进行如下注册:
<!-- 以下两个为下载时需要的添加的Service -->
<service
android:name="com.youku.service.download.DownloadService"
android:label="Youku Download Service"
android:process=":download" >
<intent-filter android:priority="1000" >
</intent-filter>
</service>
<service
android:name="com.youku.service.acc.AcceleraterService"
android:process=":accelerater" >
<intent-filter android:priority="1000" >
</intent-filter>
</service>
按上述处理之后,我们就已经开始下载视频了。接下来我们就要将其下载信息在我们的Fragment中显示出来。
正在下载DownCachingFragment.xml:
package com.jgh.watchdota;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map.Entry;
import com.youku.service.download.DownloadInfo;
import com.youku.service.download.DownloadManager;
import com.youku.service.download.OnChangeListener;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
public class DownCachingFragment extends Fragment {
// 展示视频信息的ListView
private ListView cachingList;
// 通过DownloadManager获取下载视频列表
private DownloadManager downloadManager;
// 记录当前下载中的视频列表
private ArrayList<DownloadInfo> downloadingList_show = new ArrayList<DownloadInfo>();
// 数据Adapter
private CachingVideoAdapter adapter;
private static final int MSG_STATE_CHANGE = 0;
private Activity mActivity;
private Handler handler = new Handler() {//点击下载选项下的按钮,更新下载信息列表
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
if (msg.what == MSG_STATE_CHANGE) {
initData();
// 更改界面现实状态
adapter.notifyDataSetChanged();
}
}
};
public DownCachingFragment(Activity mActivity) {
// TODO Auto-generated constructor stub
this.mActivity = mActivity;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
Log.i("jiangguohu", "DoenCachingFragment create");
View view = inflater.inflate(R.layout.layout_down_caching, null);
cachingList = (ListView) view.findViewById(R.id.cachingList);
adapter = new CachingVideoAdapter(mActivity, handler);
cachingList.setAdapter(adapter);
return view;
}
@Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
initData();
adapter.notifyDataSetChanged();
}
/**
* 获取当前正在下载的视频信息
*/
private void initData() {
downloadingList_show.clear();
// 通过DownloadManager类的getDownloadingData()接口函数获取已经下载的视频信息
downloadManager = DownloadManager.getInstance();
downloadManager.setOnChangeListener(new OnChangeListener() {
@Override
public void onFinish() {
// TODO Auto-generated method stub
Log.i("jiangguohu", "onFinish111111111111+++++++++++++++++++++");
handler.sendEmptyMessageDelayed(MSG_STATE_CHANGE, 200);
Intent mIntent = new Intent(
DownCachedFragment.ACTION_UPDATE_CACHED);
mIntent.putExtra("update", true);
// 发送广播
mActivity.sendBroadcast(mIntent);//下载完成发送广播,通知DownCachedFragment更新界面
}
@Override
public void onChanged(DownloadInfo info) {
// TODO Auto-generated method stub
Log.i("jiangguohu", "onChanged111111111111111 info.title = "
+ info.title+",,,,info.format = "+info.format);
}
});
Iterator iter = downloadManager.getDownloadingData().entrySet()
.iterator();
while (iter.hasNext()) {// 查询正在下载的视频信息
Entry entry = (Entry) iter.next();
// 视频信息实体类用DownloadInfo表示
DownloadInfo info = (DownloadInfo) entry.getValue();
downloadingList_show.add(info);
}
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
/**
* 简单示例:用户展示视频信息的Adapter 第三方需要自己完善
*
*/
class CachingVideoAdapter extends BaseAdapter {
private LayoutInflater inflater;
private Handler h;
public CachingVideoAdapter(Context context, Handler handler) {
inflater = LayoutInflater.from(context);
h = handler;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return downloadingList_show.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@SuppressLint("ViewHolder")
@Override
public View getView(final int position, View convertView,
ViewGroup parent) {
// TODO Auto-generated method stub
final DownloadInfo info = downloadingList_show.get(position);
View view = inflater.inflate(R.layout.downloading_item, null);
TextView tv_title = (TextView) view.findViewById(R.id.title); // 视频标题
final Button btn_pause_continue = (Button) view
.findViewById(R.id.pause); // 暂停/继续 按钮
Button btn_cancel = (Button) view.findViewById(R.id.cancel); // 须消当前下载任务按钮
// 展示视频标题
tv_title.setText(info.title);
if (info.state == DownloadInfo.STATE_DOWNLOADING) { // 当前视频的下载状态:正在下载
btn_pause_continue.setText("正在下载");
} else if (info.state == DownloadInfo.STATE_PAUSE) { // 当前视频的下载状态:暂停中
btn_pause_continue.setText("暂停中");
} else if (info.state == DownloadInfo.STATE_INIT // 当前视频的下载状态:等待中
|| info.state == DownloadInfo.STATE_EXCEPTION
|| info.state == DownloadInfo.STATE_WAITING) {
btn_pause_continue.setText("等待中");
}
// 单击暂停/继续按钮改变当前下载任务的状态
btn_pause_continue.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (info.state == DownloadInfo.STATE_DOWNLOADING
|| info.state == DownloadInfo.STATE_WAITING
|| info.state == DownloadInfo.STATE_INIT
|| info.state == DownloadInfo.STATE_EXCEPTION) {
// 处于以上几种状态时单击进行暂停任务
downloadManager.pauseDownload(info.taskId);
} else if (info.state == DownloadInfo.STATE_PAUSE) {
// 处于暂停状态时单击进行继续任务
downloadManager.startDownload(info.taskId);
}
h.sendEmptyMessageDelayed(0, 200);
}
});
// 取消当前下载任务
btn_cancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new AsyncTask<Void, Void, Boolean>() {
@Override
protected Boolean doInBackground(Void... params) {
// TODO Auto-generated method stub
// 通过DonwloadManager类的deleteDownloading()接口函数删除所限泽的正在下载的任务
return downloadManager
.deleteDownloading(info.taskId);
}
}.execute();
// 通知更新
h.sendEmptyMessageDelayed(0, 100);
}
});
return view;
}
}
}
在看看其布局吧,大体上就是一个ListView:
layout_down_caching.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/cachingList"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
downloading_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:descendantFocusability="afterDescendants">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp" />
<LinearLayout
android:layout_marginTop="5dp"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:gravity="center_horizontal">
<Button
android:id="@+id/pause"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="暂停"/>
<Button
android:id="@+id/cancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="取消"/>
</LinearLayout>
</LinearLayout>
DownCachedFragment界面其实和上面差不多的。
package com.jgh.watchdota;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map.Entry;
import com.youku.service.download.DownloadInfo;
import com.youku.service.download.DownloadManager;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
public class DownCachedFragment extends Fragment {
private Activity mActivity;
// 展示视频信息的ListView
private ListView cachedList;
// 数据Adapter
private CachedVideoAdapter adapter;
// 通过DownloadManager获取下载视频列表
private DownloadManager downloadManager;
// 记录当前已经下载的视频列表
private ArrayList<DownloadInfo> downloadedList_show = new ArrayList<DownloadInfo>();
public static final String ACTION_UPDATE_CACHED = "action_update_cached";
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("jiangguohu","onReceive");
String action = intent.getAction();
if (action.equals(ACTION_UPDATE_CACHED)) {
Log.i("jiangguohu","action.equals(ACTION_UPDATE_CACHED)");
// 获取已经下载的视频数据
initData();
// 同志数据更新
adapter.notifyDataSetChanged();
}
}
};
public DownCachedFragment(Activity mActivity) {
this.mActivity = mActivity;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
Log.i("jiangguohu", "DownCachedFragment create");
View view = inflater.inflate(R.layout.layout_down_cached, null);
// ViewGroup p = (ViewGroup)view.getParent();
// if (p != null) {
// p.removeAllViews();
// }
// mActivity = getActivity();
cachedList = (ListView) view.findViewById(R.id.cachedList);
adapter = new CachedVideoAdapter(mActivity);
cachedList.setAdapter(adapter);
cachedList.setOnItemClickListener(listener);
cachedList.setOnItemLongClickListener(longListener);
// 注册广播
registerBoradcastReceiver();
return view;
}
private void registerBoradcastReceiver() {
// TODO Auto-generated method stub
IntentFilter myIntentFilter = new IntentFilter();
myIntentFilter.addAction(ACTION_UPDATE_CACHED);
// 注册广播
mActivity.registerReceiver(mBroadcastReceiver, myIntentFilter);
}
@Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
// 获取已经下载的视频数据
initData();
// 同志数据更新
adapter.notifyDataSetChanged();
}
/**
* 获取已下载视频信息
*/
private void initData() {
downloadedList_show.clear();
// 通过DownloadManager类的getDownloadedData()接口函数获取已经下载的视频信息
downloadManager = DownloadManager.getInstance();
Iterator iter = downloadManager.getDownloadedData().entrySet()
.iterator();
while (iter.hasNext()) {
Entry entry = (Entry) iter.next();
// 视频信息实体类用DownloadInfo表示
DownloadInfo info = (DownloadInfo) entry.getValue();
downloadedList_show.add(info);
}
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
downloadedList_show.clear();
mActivity.unregisterReceiver(mBroadcastReceiver);
super.onDestroy();
}
/**
* 简单示例:用户展示视频信息的Adapter 第三方需要自己完善
*
*/
class CachedVideoAdapter extends BaseAdapter {
LayoutInflater inflater;
public CachedVideoAdapter(Context context) {
inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return downloadedList_show.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return downloadedList_show.get(position).title;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@SuppressLint("ViewHolder")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.cached_item, null);
// 简单展示视频信息的名称
TextView tv_title = (TextView) view.findViewById(R.id.video_title);
// 视频信息实体类用DownloadInfo表示
DownloadInfo info = downloadedList_show.get(position);
tv_title.setText(info.title);
return view;
}
}
/**
* 通过单击已经下载过的视频进行播放
*/
private AdapterView.OnItemClickListener listener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
// 获取点击item表示视频信息
DownloadInfo info = downloadedList_show.get(position);
// 跳转到播放界面进行播放,用户可以修改为自己的播放界面
Intent intent = new Intent(mActivity, PlayerActivity.class);
// 点击缓存视频播放时需要传递给播放界面的两个参数
intent.putExtra("isFromLocal", true);
intent.putExtra("video_id", info.videoid);
startActivity(intent);
}
};
/**
* 长按删除该条下载信息
*/
private AdapterView.OnItemLongClickListener longListener = new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
final int position, long id) {
// TODO Auto-generated method stub
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity)
.setMessage("确定删除?").setTitle("提示:");
builder.setPositiveButton("删除",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
// 获取点击item表示视频信息
final DownloadInfo info = downloadedList_show
.get(position);
downloadedList_show.remove(position);
downloadManager.deleteDownloaded(info);
adapter.notifyDataSetChanged();
}
});
builder.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
}
});
builder.create().show();
return true;
}
};
}
上面就是整个下载了。最后看看下载界面吧。