안드로이드 개발 질문/답변
(글 수 45,052)
제가 YouTube 어플처럼 실행하면 리스트뷰로 동영상들을 띄워주고
리스트뷰를 누르면 해당 YouTube 동영상 재생해주고 또 검색 가능한 어플을 구현하려고 하는데
여기저기 정보를 검색하던중 네이버 개발카페에서 어떤분이 gdata말고 데이터를 파싱해서 구현하신 소스가 있더라구요
소스를 실행해서 좀 참고좀 하려고 하는데 실행이 안되네요 왜 안될까요??
얘기치 않게 중단되었다고 뜨는데요 기본소스와 XML 첨부합니다
Source package com.google.YouTube;
import android.app.Activity; import android.app.ListActivity; import android.net.Uri; import android.os.Bundle;
import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.List;
import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException;
import android.util.Xml; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup;
import android.content.Context; import android.content.Intent; import android.webkit.WebView; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView;
public class YouTube extends ListActivity // 이부분은 ListActivity
{
/** Called when the activity is first created. */
private HttpClient mClient;
private HttpGet mGetMethod;
List<String> title = new ArrayList<String>(); // 리스트를 만들기 위한 준비
List<String> thumbnailUrl = new ArrayList<String>(); // 썸네일 URL 들을 순서대로 저장하기 위한 객체
List<String> userId = new ArrayList<String>(); // 동영상을 올린이의 ID 를 순서대로 저장
List<String> videoUrl = new ArrayList<String>(); // 재생을 위한 동영상 URL 을 순서대로 저장
List<String> description = new ArrayList<String>(); // 올린이가 동영상에 대한 설명글을 저장
List<String> Duration = new ArrayList<String>(); // 재생 시간을 순서대로 저장
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
GetYoutubeData();
CMyArrayAdapter aa = new CMyArrayAdapter(this, title); // 리스트에 들어갈 각 row 를 꾸미기 위한 adapter 객체
setListAdapter(aa); // 리스트에 adapter 객체를 적용한다.
}
private void GetYoutubeData()
{
String keyword = "검색할 내용";
String encodeKeyword = "";
// EditText01
try {
encodeKeyword = URLEncoder.encode(keyword, "UTF-8"); // 위의 keyword 를 유튜브로 보내기 위해 utf-8 로 인코딩
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// YouTube
String uri = "http://gdata.youtube.com/feeds/api/videos?vq=" + encodeKeyword; // 인코딩한 검색어 결합
mClient = new DefaultHttpClient();
mGetMethod = new HttpGet();
HttpResponse resp = null;
try
{
// Request
mGetMethod.setURI(new URI(uri)); // 유튜브에 검색을 요청하기 위한 URI 준비
}
catch (URISyntaxException e)
{
// TODO
e.printStackTrace();
}
try
{
// METHOD GET Request
resp = mClient.execute(mGetMethod); // 유튜브로 검색을 요청(request)
}
catch (ClientProtocolException e)
{
// TODO catch
e.printStackTrace();
}
catch (IOException e)
{
// TODO
e.printStackTrace();
}
// Request
if (resp.getStatusLine().getStatusCode() == 200)
{
try
{
InputStream is = resp.getEntity().getContent(); // 검색결과를 받아옴
try {
GetYouTubeEntries(is); // 받아온 결과 파싱 (기능 밑에서 설명)
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
is.close();
}
catch (IllegalStateException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
private void GetYouTubeEntries(InputStream is) throws XmlPullParserException, IOException
{
String nameSpace = null;
String parserName = null; // XML 문서에서 각 부분들의 이름
String value; // XML 문서에서 각 부분들의 값
Integer depth = 0;
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new InputStreamReader(is));
// boolean bThumbnail = false;
String szTempTitle = null;
String szOrigTitle = null;
for (int e = parser.getEventType(); e != parser.END_DOCUMENT; e = parser.next())
{
depth = parser.getDepth(); // xml 문서에서 뎁스 가져옴
switch(e)
{
case XmlPullParser.START_TAG: // START_TAG 부분일 경우
parserName = parser.getName();
if (depth == 4)
{
if (parserName == "thumbnail") // 썸네일이 나왔네요. 이 썸네일은 동영상 한개당 3~4장 정도 있습니다. 때문
// 에 썸네일을 최초 1장만 저장하고 나머지는 무시하는것이 필요합니다.
{
if(szTempTitle != szOrigTitle) // 최초의 썸네일만 저장하고, 동영상의 타이틀이 바뀌지 않으면 즉 같은 동영상
// 이라면 썸네일을 저장하지 않고 넘어갑니다.
{
szTempTitle = szOrigTitle; // 이 안에 들어왔다면 최초의 썸네일이란 뜻이므로 이 두 변수를 같게합니다.
String url = parser.getAttributeValue(nameSpace, "url"); // 썸네일 주소를 받아서
thumbnailUrl.add(url); // 썸네일 List 에 저장합니다.
}
}
else if (parserName == "player")
{
String url = parser.getAttributeValue(nameSpace, "url"); // 동영상주소
videoUrl.add(url);
}
else if (parserName == "duration")
{
String duration = parser.getAttributeValue(nameSpace, "seconds"); // 동영상시간
Duration.add(duration);
}
}
break;
case XmlPullParser.TEXT: // XML 에서 동영상 정보 가 아닌 텍스트 부분들
value = null;
value = parser.getText();
if (depth == 3)
{
// if (parserName == "published") // 잘 모르겠네요;;
// {
// int a = 0;
// }
// else if (parserName == "updated") // 올라간 날짜
// {
// int a = 0;
// }
if (parserName == "title") // 동영상 제목
{
szOrigTitle = value;
title.add(value);
}
// else if (parserName == "content") // 컨텐츠의 종류 예: 영화, 드라마 등
// {
// //entry.setContent(value);
// int a = 0;
// }
// else if (parserName == "recorded") // 누가 녹화 했는가 뭐 그런것 이었던듯
// {
// int a = 0;
// //entry.setRecorded(value);
// }
}
else if (depth == 4)
{
if (parserName == "name") // 게시자 ID
{
userId.add(value);
}
else if (parserName == "uri") // 유져에 대한 정보를 보여주는 uri 별 필요 없습니다
{
int a = 0;
}
// else if (parserName == "category") // 카테고리 분류
// {
// int a = 0;
// //mediaCategory.setValue(value);
// }
else if (parserName == "description") // 글 내용
{
description.add(value);
}
// else if (parserName == "keywords") // 동영상의 키워드
// {
// int a = 0;
// //media.setKeywords(value);
// }
}
break;
case XmlPullParser.END_TAG:
parserName = parser.getName();
if (parserName.equals("entry"))
{
//retEntries.add(entry);
}
break;
}
}
}
private class CMyArrayAdapter extends ArrayAdapter<Object>
{
Context context;
CMyArrayAdapter(Context context, List titles) // 클래스의 생성자
{
super(context, R.layout.row, titles); // 어뎁터를 row.xml 레이아웃으로 지정하고, titles 의 리스트가 끝날때
// 까지 리스트를 구성하게 됩니다.
this.context = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) // 리스트를 한개한개 만들때마다 자동으로 호
{ // 출되는 getView 입니다. 각 row의 안을
// 채운다고 생각하시면 됩니다. LayoutInflater inflater = ((Activity)context).getLayoutInflater(); View row = (View)inflater.inflate(R.layout.row, null); TextView titleView = (TextView)row.findViewById(R.id.title); // 타이틀 textview 객체 TextView durationView = (TextView)row.findViewById(R.id.duration); // 시간 textview 객체 WebView thumbnailView = (WebView)row.findViewById(R.id.thumbnail); // 섬네일 webview 객체 thumbnailView.setFocusable(false); // 주의!! 안드로이드의 버그로, ListView 안에 클릭 가능한 객체 (예:버튼, 웹뷰)
// 가 있으면 ListView 를 클릭했을때 호출되는 onListItemClick 이 호출되지 않습니다. 그래서 webView 의 focusable 을
// false 로 만들어 주어야 합니다. 웃기는건 레이아웃 에서 설정해도 소용이 없고, 반드시 코드상에서 위처럼 해야 합니다.
// 참고하세요.
String szThumbnailUrl = (String)thumbnailUrl.get(position); // position 에 리스트의 인덱스가 있습니다.
String szTitle = (String)title.get(position);
String szDuration = (String)Duration.get(position);
int nDuration = Integer.parseInt(szDuration);
if(nDuration > 60) // duration 이 초단위 만 있으므로 분과 초로 나눠줍니다.
{
int nMinute = nDuration/60;
int nSecond = nDuration%60;
szDuration = nMinute+"분 "+nSecond+"초";
}
else
{
szDuration = nDuration+"초";
}
titleView.setText(szTitle); // 이제 타이틀뷰에 타이틀 을 넣고
durationView.setText(szDuration); // 시간을 넣고
thumbnailView.loadUrl("szThumbnailUrl); // 웹뷰 썸네일을 넣으면 끝~~
return row;
}
}
}
main XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<ListView
android:id="@id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<TextView
android:id="@id/android:empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="No Item" />
</LinearLayout>
row XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="80px"
android:orientation="horizontal">
<WebView
android:id="@+id/thumbnail"
android:layout_width="120px"
android:layout_height="90px"
android:layout_gravity="center_vertical" android:scrollbars="none"
android:clickable="false"
android:focusable="false">
</WebView>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="55px"
android:textSize="14px"
android:layout_marginLeft="10px"
android:layout_marginTop="10px"
android:clickable="false"
android:focusable="false">
</TextView>
<TextView
android:id="@+id/duration"
android:layout_width="fill_parent"
android:layout_height="15px"
android:textSize="10px"
android:gravity="right"
android:layout_marginRight="20px"
android:clickable="false"
android:focusable="false">
</TextView>
</LinearLayout>
</LinearLayout>



