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=newArrayList<Bitmap>();
ArrayList<HashMap<String,String>> menuitems=newArrayList<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(newInputStreamReader(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 (inti=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=newHashMap<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(newmyadapter(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(newOnItemClickListener() {
public voidonItemClick(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
Mình lam bi loi.không run được,lỗi thoát chương trình luôn
ReplyDelete