Java tutorial
/** * VimeoDroid - Unofficial Vimeo app for Android * Copyright (C) 2012 Makoto Schoppert * This program is free software; * you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; * either version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this program; * if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ package com.makotosan.vimeodroid.vimeo; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.HashMap; import java.util.zip.GZIPInputStream; import oauth.signpost.exception.OAuthCommunicationException; import oauth.signpost.exception.OAuthExpectationFailedException; import oauth.signpost.exception.OAuthMessageSignerException; import org.apache.commons.io.IOUtils; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.HttpResponseException; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.AbortableHttpRequest; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.MultipartEntity; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.entity.mime.content.StringBody; import org.apache.http.impl.client.BasicResponseHandler; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserFactory; import android.app.Activity; import android.app.Application; import android.content.Context; import android.content.SharedPreferences; import android.net.http.AndroidHttpClient; import android.os.Environment; import android.util.Log; import android.view.Display; import android.view.WindowManager; import android.widget.Toast; import com.makotosan.vimeodroid.ApplicationEx; import com.makotosan.vimeodroid.Authentication; import com.makotosan.vimeodroid.ConsumerInfo; import com.makotosan.vimeodroid.R; import com.makotosan.vimeodroid.common.CountingRequestEntity; import com.makotosan.vimeodroid.common.MoogalXml; import com.makotosan.vimeodroid.common.VimeoUrls; import com.makotosan.vimeodroid.common.CountingRequestEntity.ProgressListener; public class Methods { public static interface OnTransferringHandler { public void onTransferring(AbortableHttpRequest request); } private static final String MY_PREFS = "VIMEO_DROID_PREFS"; private static final String TAG = "Methods"; public static boolean isExternalStorageWritable() { boolean mExternalStorageAvailable = false; boolean mExternalStorageWriteable = false; String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { mExternalStorageAvailable = mExternalStorageWriteable = true; } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { mExternalStorageAvailable = true; mExternalStorageWriteable = false; } else { mExternalStorageAvailable = mExternalStorageWriteable = false; } return mExternalStorageAvailable && mExternalStorageWriteable; } private ApplicationEx app; private Context context; public Methods(Context context, Application app) { this.context = context; this.app = (ApplicationEx) app; } public CollectionItem<Video> albums_getWatchLater() { final HashMap<String, String> params = new HashMap<String, String>(); params.put("full_response", "1"); return parseVideosXml(makeRequest("albums.getWatchLater", params)); } public CollectionItem<Contact> contacts_getAll() { final CollectionItem<Contact> contacts = new CollectionItem<Contact>(Contact.class, "contacts"); try { final XmlPullParser xpp = makeRequest("contacts.getAll", null); contacts.initialize(xpp); } catch (Exception e) { Log.e(TAG, "Unable to get contacts", e); Toast.makeText(context, "Unable to get contacts", Toast.LENGTH_SHORT).show(); } return contacts; } public void downloadFile(String uri, String fileName, ProgressListener listener, OnTransferringHandler handler) throws ClientProtocolException, IOException { final HttpGet request = new HttpGet(uri); final HttpResponse response = this.getHttpResponse(request, uri, false); handler.onTransferring(request); HttpEntity entity = new CountingRequestEntity(response.getEntity(), listener); // long fileSize = entity.getContentLength(); // entity.getContent(); this.saveVideo(entity, uri, fileName); } private ConsumerInfo getConsumerInfo() { final SharedPreferences prefs = context.getSharedPreferences(MY_PREFS, Context.MODE_PRIVATE); final ConsumerInfo info = new ConsumerInfo(); final String consumerToken = prefs.getString(Authentication.CONSUMER_TOKEN_PREF, null); final String consumerTokenSecret = prefs.getString(Authentication.CONSUMER_TOKEN_SECRET_PREF, null); info.setConsumerToken(consumerToken); info.setConsumerTokenSecret(consumerTokenSecret); return info; } public String getContentType(String uri) throws ClientProtocolException, IOException { final HttpResponse response = this.getHttpResponse(uri); return response.getFirstHeader("Content-Type").getValue(); } public long getFileSize(String uri) throws ClientProtocolException, IOException { final HttpResponse response = this.getHttpResponse(uri); return response.getEntity().getContentLength(); } public HttpResponse getHttpResponse(HttpGet request, String uri, Boolean closeConnection) throws ClientProtocolException, IOException { boolean useAltHttpClient = this.getUseAltHttpClient(); final HttpClient client = useAltHttpClient ? app.getHttpClient() : AndroidHttpClient.newInstance("Vimeo Droid"); HttpResponse response; try { response = client.execute(request); } finally { if (client != null && client instanceof AndroidHttpClient) { if (closeConnection) { ((AndroidHttpClient) client).close(); } } } return response; } public HttpResponse getHttpResponse(String uri) throws ClientProtocolException, IOException { final HttpGet request = new HttpGet(uri); return this.getHttpResponse(request, uri, true); } public MoogalXml getMoogalXml(String clipId, String userId, VideoQuality quality) { MoogalXml moogal = new MoogalXml(); Display display = ((WindowManager) this.context.getSystemService(Context.WINDOW_SERVICE)) .getDefaultDisplay(); String baseUrl = "http://vimeo.com/moogaloop/load/clip:" + clipId + "/local/?moog_width=" + display.getWidth() + "&moog_height=" + display.getHeight() + "&embed_location=¶m_server=vimeo.com¶m_force_embed=0¶m_multimoog=¶m_autoplay=1¶m_fullscreen=1¶m_md5=0¶m_force_info=undefined¶m_show_portrait=0¶m_show_title=0¶m_ver=39487¶m_show_byline=0¶m_context=user:" + userId + "¶m_clip_id=" + clipId + "¶m_color=00ADEF¶m_context_id=&context=user:" + userId; // Call it, and then we'll get XML final HttpGet request = new HttpGet(baseUrl); final HttpClient client = app.getHttpClient(); final ResponseHandler<String> handler = new BasicResponseHandler(); String finalUrl = ""; try { final String response = client.execute(request, handler); String requestSignature = ""; String requestSignatureExpires = ""; String embedCode = ""; final XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); final XmlPullParser xpp = factory.newPullParser(); xpp.setInput(new StringReader(response)); int eventType = xpp.getEventType(); String tagName = ""; while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { case XmlPullParser.START_TAG: tagName = xpp.getName(); break; case XmlPullParser.END_TAG: tagName = ""; break; case XmlPullParser.TEXT: if ("request_signature".equals(tagName)) { requestSignature = xpp.getText(); break; } if ("request_signature_expires".equals(tagName)) { requestSignatureExpires = xpp.getText(); break; } if ("embed_code".equals(tagName)) { embedCode = xpp.getText(); } break; } eventType = xpp.next(); } finalUrl = String.format( "http://vimeo.com/moogaloop/play/clip:%s/%s/%s/?q=%s&type=local&embed_location=", clipId, requestSignature, requestSignatureExpires, quality); moogal.setUrl(finalUrl); moogal.setEmbedCode(embedCode); moogal.setRequestSignature(requestSignature); moogal.setRequestSignatureExpires(requestSignatureExpires); // Log.d("GetMp4Url", "Playing video at " + finalUrl); } catch (Exception e) { e.printStackTrace(); } return moogal; // return finalUrl; } public String getRedirectedUri(String uri) throws ClientProtocolException, IOException { boolean useAltHttpClient = this.getUseAltHttpClient(); final HttpClient client = useAltHttpClient ? app.getHttpClient() : AndroidHttpClient.newInstance("Vimeo Droid"); final HttpGet request = new HttpGet(uri); try { final HttpResponse response = client.execute(request); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == 302) { // Redirect // Need to get the redirected URL value and do another request uri = response.getHeaders("Location")[0].getValue(); } } finally { if (client != null && client instanceof AndroidHttpClient) { ((AndroidHttpClient) client).close(); } } return uri; } public boolean getSettingUseBuiltinPlayer() { SharedPreferences prefs = this.context.getSharedPreferences("com.makotosan.vimeodroid_preferences", 0); String settingKey = this.context.getResources().getString(R.string.SETTING_USE_BUILTIN_PLAYER); boolean useBuiltinPlayer = prefs.getBoolean(settingKey, true); return useBuiltinPlayer; } public String getSettingVideoQuality() { SharedPreferences prefs = this.context.getSharedPreferences("com.makotosan.vimeodroid_preferences", 0); String settingKey = this.context.getResources().getString(R.string.SETTING_VIDEO_QUALITY); String quality = prefs.getString(settingKey, "sd"); return quality; } private boolean getUseAltHttpClient() { SharedPreferences prefs = this.context.getSharedPreferences("com.makotosan.vimeodroid_preferences", 0); String settingKey = this.context.getResources().getString(R.string.SETTING_HTTP_CLIENT_PREF); boolean useAltHttpClient = prefs.getBoolean(settingKey, false); return useAltHttpClient; } private XmlPullParser makeRequest(String method, HashMap<String, String> parameters) { final StringBuilder urlStringBuilder = new StringBuilder(); try { urlStringBuilder.append(VimeoUrls.STANDARD_API + "?method=vimeo." + method); final ConsumerInfo info = getConsumerInfo(); if (parameters != null && !parameters.isEmpty()) { for (String key : parameters.keySet()) { urlStringBuilder.append("&" + key + "=" + parameters.get(key)); } if (!parameters.containsKey("user_id")) { urlStringBuilder.append("&user_id=" + info.getConsumerToken()); } } final HttpGet request = new HttpGet(urlStringBuilder.toString()); request.addHeader("Accept-Encoding", "gzip"); final HttpClient client = this.app.getHttpClient(); Authentication.signRequest(info, request); final org.apache.http.HttpResponse response = client.execute(request); final int statusCode = response.getStatusLine().getStatusCode(); // Log.d("HTTP method : " + method, "return statusCode : " + // statusCode); if (statusCode != 200) { throw new HttpResponseException(statusCode, "HTTP Error"); } final HttpEntity entity = response.getEntity(); if (entity != null) { InputStream inputStream = null; try { inputStream = entity.getContent(); final Header contentEncoding = response.getFirstHeader("Content-Encoding"); if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) { inputStream = new GZIPInputStream(inputStream); } final XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); final XmlPullParser xpp = factory.newPullParser(); final String rawXml = IOUtils.toString(inputStream); xpp.setInput(new StringReader(rawXml)); int eventType = xpp.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { case XmlPullParser.START_TAG: if ("rsp".equals(xpp.getName())) { String status = xpp.getAttributeValue(XmlPullParser.NO_NAMESPACE, "stat"); if ("fail".equals(status)) { ErrorInfo error = VimeoXmlParser.parse(ErrorInfo.class, xpp); Log.e(TAG, error.getExplanation()); Toast.makeText(context, error.getExplanation(), Toast.LENGTH_LONG).show(); return null; // throw new // Exception(error.getExplanation()); } return xpp; } break; } eventType = xpp.next(); } return xpp; } finally { if (inputStream != null) { inputStream.close(); } entity.consumeContent(); } } } catch (Exception e) { Log.e(TAG, e.getMessage(), e); // Toast.makeText(context, e.getMessage(), // Toast.LENGTH_SHORT).show(); } return null; } public OauthInfo oauth_checkAccessToken() { // Log.d(TAG, "oauth_checkAccessToken()"); final ConsumerInfo consumerInfo = getConsumerInfo(); final HashMap<String, String> params = new HashMap<String, String>(); params.put("oauth_token", consumerInfo.getConsumerToken()); try { final OauthInfo oauth = VimeoXmlParser.parse(OauthInfo.class, makeRequest("oauth.checkAccessToken", params)); return oauth; } catch (Exception e) { Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show(); } return null; } private CollectionItem<Video> parseVideosXml(XmlPullParser xpp) { final CollectionItem<Video> videos = new CollectionItem<Video>(Video.class, "videos"); try { videos.initialize(xpp); } catch (Exception e) { Log.e(TAG, "Unable to parse videos xml", e); // Toast.makeText(context, e.getMessage(), // Toast.LENGTH_SHORT).show(); } return videos; } private void saveVideo(HttpEntity entity, String url, String fileName) { if (isExternalStorageWritable()) { String path = Environment.getExternalStorageDirectory().getAbsolutePath(); path += "/Videos/"; OutputStream out = null; byte[] buffer = new byte[8 * 1024]; try { InputStream input = entity.getContent(); File file = new File(path); file.mkdirs(); file = new File(path + fileName); out = new FileOutputStream(file); int bytesRead; while ((bytesRead = input.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); } } catch (Exception e) { // What to do here? } finally { try { entity.consumeContent(); if (out != null) { out.close(); } } catch (IOException e) { // Swallow exception } } } } public void uploadFile(String endpoint, String ticketId, File file, String filename, ProgressListener listener, OnTransferringHandler handler) throws OAuthMessageSignerException, OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException, IOException { // final int chunkSize = 512 * 1024; // 512 kB // final long pieces = file.length() / chunkSize; int chunkId = 0; final HttpPost request = new HttpPost(endpoint); // BufferedInputStream stream = new BufferedInputStream(new // FileInputStream(file)); // for (chunkId = 0; chunkId < pieces; chunkId++) { // byte[] buffer = new byte[chunkSize]; // stream.skip(chunkId * chunkSize); // stream.read(buffer); final MultipartEntity entity = new MultipartEntity(); entity.addPart("chunk_id", new StringBody(String.valueOf(chunkId))); entity.addPart("ticket_id", new StringBody(ticketId)); request.setEntity(new CountingRequestEntity(entity, listener)); // , // chunkId // * // chunkSize)); // ByteArrayInputStream arrayStream = new ByteArrayInputStream(buffer); Authentication.signRequest(getConsumerInfo(), request); entity.addPart("file_data", new FileBody(file)); // entity.addPart("file_data", new InputStreamBody(arrayStream, // filename)); final HttpClient client = app.getHttpClient(); handler.onTransferring(request); final HttpResponse response = client.execute(request); final HttpEntity responseEntity = response.getEntity(); if (responseEntity != null) { responseEntity.consumeContent(); } // } } public Boolean videos_comments_addComment(String commentText, String videoId, String replyToCommentId) { final HashMap<String, String> params = new HashMap<String, String>(); final ConsumerInfo info = this.getConsumerInfo(); params.put("oauth_token", info.getConsumerToken()); try { params.put("comment_text", URLEncoder.encode(commentText, "UTF-8")); } catch (UnsupportedEncodingException e) { Log.e(TAG, "Unable to URL Encode comment", e); Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show(); return false; } params.put("video_id", videoId); if (replyToCommentId != null && replyToCommentId.length() > 0) { params.put("reply_to_comment_id", replyToCommentId); } return makeRequest("videos.comments.addComment", params) != null; } public CollectionItem<Comment> videos_comments_getList(String videoId) { final HashMap<String, String> params = new HashMap<String, String>(); final CollectionItem<Comment> comments = new CollectionItem<Comment>(Comment.class, "comments"); params.put("video_id", videoId); try { final XmlPullParser xpp = makeRequest("videos.comments.getList", params); comments.initialize(xpp); // comments = VimeoXmlParser.parse(Comments.class, xpp); } catch (Exception e) { Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show(); } return comments; } public void videos_delete(String videoId) { final HashMap<String, String> params = new HashMap<String, String>(); final ConsumerInfo info = this.getConsumerInfo(); params.put("oauth_token", info.getConsumerToken()); params.put("video_id", videoId); makeRequest("videos.delete", params); } public Person people_getInfo(String userId) { final HashMap<String, String> params = new HashMap<String, String>(); params.put("user_id", userId); final Person person = new Person(); final XmlPullParser xpp = makeRequest("people.getInfo", params); try { person.initialize(xpp); } catch (Exception e) { Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show(); } return person; } public Video videos_getInfo(String videoId) { final HashMap<String, String> params = new HashMap<String, String>(); params.put("video_id", videoId); final Video video = new Video(); final XmlPullParser xpp = makeRequest("videos.getInfo", params); try { video.initialize(xpp); } catch (Exception e) { Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show(); } return video; } public CollectionItem<Video> videos_getAll(String sortBy, String userId) { final HashMap<String, String> params = new HashMap<String, String>(); params.put("full_response", "1"); if (userId != null && userId.length() > 0) { params.put("user_id", userId); } if (sortBy != null && sortBy.length() > 0) { params.put("sort", sortBy); } return parseVideosXml(makeRequest("videos.getAll", params)); } public CollectionItem<Video> videos_getSubscriptions(String sortBy) { final HashMap<String, String> params = new HashMap<String, String>(); params.put("full_response", "1"); if (sortBy != null) { params.put("sort", sortBy); } return parseVideosXml(makeRequest("videos.getSubscriptions", params)); } public CollectionItem<Video> videos_search(String query, String sortBy) { final HashMap<String, String> params = new HashMap<String, String>(); params.put("full_response", "1"); try { params.put("query", URLEncoder.encode(query, "UTF-8")); } catch (UnsupportedEncodingException e) { return null; } if (sortBy != null) { params.put("sort", sortBy); } return parseVideosXml(makeRequest("videos.search", params)); } public Boolean videos_setDescription(String description, String videoId) { final HashMap<String, String> params = new HashMap<String, String>(); final ConsumerInfo info = this.getConsumerInfo(); params.put("oauth_token", info.getConsumerToken()); try { params.put("description", URLEncoder.encode(description, "UTF-8")); } catch (UnsupportedEncodingException e) { return false; } params.put("video_id", videoId); return makeRequest("videos.setDescription", params) != null; } public Boolean videos_setLike(boolean like, String videoId) { final HashMap<String, String> params = new HashMap<String, String>(); final ConsumerInfo info = this.getConsumerInfo(); params.put("oauth_token", info.getConsumerToken()); params.put("like", String.valueOf(like)); params.put("video_id", videoId); return makeRequest("videos.setLike", params) != null; } public Boolean videos_setTitle(String title, String videoId) { final HashMap<String, String> params = new HashMap<String, String>(); final ConsumerInfo info = this.getConsumerInfo(); params.put("oauth_token", info.getConsumerToken()); try { params.put("title", URLEncoder.encode(title, "UTF-8")); } catch (UnsupportedEncodingException e) { return false; } params.put("video_id", videoId); return makeRequest("videos.setTitle", params) != null; } public void videos_upload_complete(String ticketId, String fileName) { final HashMap<String, String> params = new HashMap<String, String>(); final ConsumerInfo info = this.getConsumerInfo(); params.put("oauth_token", info.getConsumerToken()); params.put("ticket_id", ticketId); params.put("filename", fileName); makeRequest("videos.upload.complete", params); } public Quota videos_upload_getQuota() { final HashMap<String, String> params = new HashMap<String, String>(); final ConsumerInfo info = this.getConsumerInfo(); params.put("oauth_token", info.getConsumerToken()); Quota quota = null; try { final XmlPullParser xpp = makeRequest("videos.upload.getQuota", params); quota = VimeoXmlParser.parse(Quota.class, xpp); } catch (Exception e) { Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show(); } return quota; } public UploadTicket videos_upload_getTicket() { final HashMap<String, String> params = new HashMap<String, String>(); final ConsumerInfo info = this.getConsumerInfo(); params.put("oauth_token", info.getConsumerToken()); UploadTicket ticket = null; try { ticket = VimeoXmlParser.parse(UploadTicket.class, makeRequest("videos.upload.getTicket", params)); } catch (Exception e) { Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show(); } return ticket; } public CollectionItem<Video> videos_getLikes(String sortBy) { final HashMap<String, String> params = new HashMap<String, String>(); params.put("full_response", "1"); if (sortBy != null && sortBy.length() > 0) { params.put("sort", sortBy); } return parseVideosXml(makeRequest("videos.getLikes", params)); } }