[Android] Youtube -Bài 3: Chương trình đọc playlist từ youtube, load dữ liệu vào ListView
Bài 3: Viết chương trình đọc playlist từ youtube, load dữ liệu vào
ListView, khi chọn 1 mục trong ListView sẽ chạy Video tương ứng.
1. Tạo
project đặt tên vd:“youtubeplaylist1”.
2. Vào
“mainifest.xml” cấp quyền truy cập Internet.
<uses-permission android:name="android.permission.INTERNET"/>
3. Vào
file “main.xml” kéo vào 1 ListView. Qua file java chính khai báo và ánh xạ vào.
4. Tạo
ra một file xml mới có tên vd:
“listviewlayout.xml“ để làm layout cho từng mục con của ListView.
Mã lệnh như sau. Chú ý cách đặt tên, có 1 imageview tên
image1, 1textview tên title, 1 textview tên length:
<?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"
>
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TableRow
android:id="@+id/tableRow1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<TableRow
android:id="@+id/tableRow5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<ImageView
android:id="@+id/image1"
android:layout_width="100dp"
android:layout_height="80dp"
android:src="@drawable/ic_launcher"
/>
</TableRow>
<TableRow
android:id="@+id/tableRow6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:textSize="15dp"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/length"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:textSize="10dp"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
</TableRow>
</TableRow>
</TableLayout>
</LinearLayout>
5. Qua
file java chính khai báo thêm 1 ArrayList bên trong lại là HashMap để chứa dữ
liệu parser từ JSON. Và một ArrayList chứa Bitmap.
ListView lv;
//phai lay hinh trong doinbackground, neu
cu lay duong dan va
//den getView moi lay thi lai bi loi truy
xuat network trong mainthread
ArrayList<Bitmap> manghinh=new
ArrayList<Bitmap>();
ArrayList<HashMap<String,String>>
menuitems=new
ArrayList<HashMap<String,String>>();
6. Trong
file java chính, xây một class nội tên ParseVideoYoutube extends từ AsyncTask.
Class này giúp tách phần truy vấn nextwork ra thành luồng riêng và có thể cập
nhật được giao diện từ luồng (trên version mới phải làm như thế). Trong class
này ta override lên 2 hàm doInBackground và onPostExecute.
private class ParseVideoYoutube extends AsyncTask<Void,
Void, Void> {
@Override
protected Void
doInBackground(Void... params) {
return null;
}
@Override
protected void onPostExecute(Void
result) {
// TODO Auto-generated
method stub
super.onPostExecute(result);
}
}
7. Trong
hàm doInBackground ta đọc dữ liệu từ jon và phân tích nó ra bỏ vào ArrayList.
Chú ý phần hình ảnh ta cũng phải lấy về và bỏ vào ArrayList luôn chứ không lưu
địa chỉ và đợi khi gán vào ListView mới lấy nó ra vì khi trong hàm getView của
listview mà lấy hình xuống thì lại đụng đến vấn đề các thao tác network không
được bỏ trong thread chính.
URL jsonURL;
URLConnection jc;
try {
jsonURL = new URL("http://gdata.youtube.com/feeds/api/playlists/" +
"PLM5NQydODud7vIkTjPtEUa8nDZHR4rvUJ" +
"?v=2&alt=jsonc");
jc
= jsonURL.openConnection();
InputStream is = jc.getInputStream();
//doc du lieu
BufferedReader reader=
new BufferedReader(new
InputStreamReader(is,"UTF-8"),8);//iso-8859-1
StringBuilder sb=new StringBuilder();
String line=null;
while((line=reader.readLine())!=null)
{
sb.append(line+"\n");
}
is.close();
String jsonTxt=sb.toString(); //doc StringBuilder
vao chuoi
/////////////////////
JSONObject jj = new JSONObject(jsonTxt);
JSONObject jdata = jj.getJSONObject("data");
JSONArray aitems = jdata.getJSONArray("items");
for (int
i=0;i<aitems.length();i++)
{
JSONObject item = aitems.getJSONObject(i);
JSONObject video = item.getJSONObject("video");
String title = video.getString("title");
JSONObject player = video.getJSONObject("player");
String link = player.getString("default");
String length = video.getString("duration");
JSONObject thumbnail = video.getJSONObject("thumbnail");
String thumbnailUrl = thumbnail.getString("hqDefault");
HashMap<String,String> hashmap=new
HashMap<String,String>();
hashmap.put("title",title);
hashmap.put("thumbnailUrl", thumbnailUrl);
hashmap.put("length",length);
hashmap.put("link",link);
menuitems.add(hashmap);
//lay
hinh bo vao mang hinh truoc, khong doi den getView duoc
URL url = new URL(thumbnailUrl);
HttpURLConnection connection =
(HttpURLConnection) url.openConnection();
InputStream ishinh = connection.getInputStream();
Bitmap img = BitmapFactory.decodeStream(ishinh);
manghinh.add(img);
Log.d("dulieu", title);
Log.d("duongdan",link);
Log.d("hinh",thumbnailUrl);
}
} catch (Exception e) {
e.printStackTrace();
Log.d("loi", e.toString());
}
return null;
8. Đến
đây ta có thể chạy để test trên logcat bằng cách trong file java chính trong
hàm onCreate viết như sau:
new ParseVideoYoutube().execute();
9. Tiếp theo ta sẽ load nó lên ListView. Xây dựng
một class mới (tách thành file khác cho đỡ rối) đặt tên vd: “myadapter” kế thừa
ArrayAdapter và có mã như sau (chú ý: ở đây ta cần truyền vào context, layout,
arraylist của json và arraylist chứa hình bitmap:
class myadapter extends ArrayAdapter{
ArrayList<HashMap<String,String>>
menuitems;
ArrayList<Bitmap> manghinh;
Context
context;
public myadapter(Context context, int textViewResourceId,
ArrayList<HashMap<String,String>>
menuitems, ArrayList<Bitmap> manghinh) {
super(context,
textViewResourceId, menuitems);
// TODO Auto-generated
constructor stub
this.context=context;
this.menuitems=menuitems;
this.manghinh=manghinh;
}
@Override
public View getView(int position, View
convertView, ViewGroup parent) {
LayoutInflater
inf=(LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View
rowview=inf.inflate(R.layout.listviewlayout,parent, false);
TextView
textviewtitle=(TextView)rowview.findViewById(R.id.title);
TextView
textviewlength=(TextView)rowview.findViewById(R.id.length);
ImageView
imageview=(ImageView)rowview.findViewById(R.id.image1);
textviewtitle.setText(menuitems.get(position).get("title").toString());
textviewlength.setText(menuitems.get(position).get("length").toString());
//lay hinh trong mang hinh da chuan
bi san
imageview.setImageBitmap(manghinh.get(position));
return rowview;
}
}
10. Trong
file java chính trong hàm onPostExecute
ta sẽ tạo và gán adapter cho listview như sau:
@Override
protected void onPostExecute(Void
result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
lv.setAdapter(new
myadapter(getApplicationContext(),R.layout.listviewlayout,menuitems,manghinh));
}
11. Đến
đây là xong phần khó khăn giờ ta bắt sự kiện để khi click vào 1 mục trong
listview sẽ đến youtube và load file video đó. Trong onCreate bắt sự kiện cho
listview và kích hoạt Intent để xem địa chỉ video đó.
lv.setOnItemClickListener(new
OnItemClickListener() {
public void
onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated
method stub
String link=menuitems.get(arg2).get("link").toString();
Intent i=new Intent(Intent.ACTION_VIEW,Uri.parse(link));
startActivity(i);
}
});
12. Chạy
chương trình để thấy kết quả.
[Android] Youtube Bài 1: Hướng Dẫn Tạo Api Key Cho Android Youtube Player
No comments: