PageRenderTime 26ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/development/samples/SampleSyncAdapter/src/com/example/android/samplesync/client/NetworkUtilities.java

https://gitlab.com/brian0218/rk3188_r-box_android4.2.2_sdk
Java | 271 lines | 172 code | 19 blank | 80 comment | 21 complexity | 3b8f2fcee1306b3f43245ff6b9d3e133 MD5 | raw file
  1. /*
  2. * Copyright (C) 2010 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.example.android.samplesync.client;
  17. import org.apache.http.HttpEntity;
  18. import org.apache.http.HttpResponse;
  19. import org.apache.http.HttpStatus;
  20. import org.apache.http.NameValuePair;
  21. import org.apache.http.ParseException;
  22. import org.apache.http.auth.AuthenticationException;
  23. import org.apache.http.client.HttpClient;
  24. import org.apache.http.client.entity.UrlEncodedFormEntity;
  25. import org.apache.http.client.methods.HttpPost;
  26. import org.apache.http.conn.params.ConnManagerParams;
  27. import org.apache.http.impl.client.DefaultHttpClient;
  28. import org.apache.http.message.BasicNameValuePair;
  29. import org.apache.http.params.HttpConnectionParams;
  30. import org.apache.http.params.HttpParams;
  31. import org.apache.http.util.EntityUtils;
  32. import org.json.JSONArray;
  33. import org.json.JSONException;
  34. import org.json.JSONObject;
  35. import android.accounts.Account;
  36. import android.graphics.Bitmap;
  37. import android.graphics.BitmapFactory;
  38. import android.text.TextUtils;
  39. import android.util.Log;
  40. import java.io.BufferedReader;
  41. import java.io.ByteArrayOutputStream;
  42. import java.io.IOException;
  43. import java.io.InputStream;
  44. import java.io.InputStreamReader;
  45. import java.io.UnsupportedEncodingException;
  46. import java.net.HttpURLConnection;
  47. import java.net.MalformedURLException;
  48. import java.net.URL;
  49. import java.util.ArrayList;
  50. import java.util.List;
  51. /**
  52. * Provides utility methods for communicating with the server.
  53. */
  54. final public class NetworkUtilities {
  55. /** The tag used to log to adb console. */
  56. private static final String TAG = "NetworkUtilities";
  57. /** POST parameter name for the user's account name */
  58. public static final String PARAM_USERNAME = "username";
  59. /** POST parameter name for the user's password */
  60. public static final String PARAM_PASSWORD = "password";
  61. /** POST parameter name for the user's authentication token */
  62. public static final String PARAM_AUTH_TOKEN = "authtoken";
  63. /** POST parameter name for the client's last-known sync state */
  64. public static final String PARAM_SYNC_STATE = "syncstate";
  65. /** POST parameter name for the sending client-edited contact info */
  66. public static final String PARAM_CONTACTS_DATA = "contacts";
  67. /** Timeout (in ms) we specify for each http request */
  68. public static final int HTTP_REQUEST_TIMEOUT_MS = 30 * 1000;
  69. /** Base URL for the v2 Sample Sync Service */
  70. public static final String BASE_URL = "https://samplesyncadapter2.appspot.com";
  71. /** URI for authentication service */
  72. public static final String AUTH_URI = BASE_URL + "/auth";
  73. /** URI for sync service */
  74. public static final String SYNC_CONTACTS_URI = BASE_URL + "/sync";
  75. private NetworkUtilities() {
  76. }
  77. /**
  78. * Configures the httpClient to connect to the URL provided.
  79. */
  80. public static HttpClient getHttpClient() {
  81. HttpClient httpClient = new DefaultHttpClient();
  82. final HttpParams params = httpClient.getParams();
  83. HttpConnectionParams.setConnectionTimeout(params, HTTP_REQUEST_TIMEOUT_MS);
  84. HttpConnectionParams.setSoTimeout(params, HTTP_REQUEST_TIMEOUT_MS);
  85. ConnManagerParams.setTimeout(params, HTTP_REQUEST_TIMEOUT_MS);
  86. return httpClient;
  87. }
  88. /**
  89. * Connects to the SampleSync test server, authenticates the provided
  90. * username and password.
  91. *
  92. * @param username The server account username
  93. * @param password The server account password
  94. * @return String The authentication token returned by the server (or null)
  95. */
  96. public static String authenticate(String username, String password) {
  97. final HttpResponse resp;
  98. final ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
  99. params.add(new BasicNameValuePair(PARAM_USERNAME, username));
  100. params.add(new BasicNameValuePair(PARAM_PASSWORD, password));
  101. final HttpEntity entity;
  102. try {
  103. entity = new UrlEncodedFormEntity(params);
  104. } catch (final UnsupportedEncodingException e) {
  105. // this should never happen.
  106. throw new IllegalStateException(e);
  107. }
  108. Log.i(TAG, "Authenticating to: " + AUTH_URI);
  109. final HttpPost post = new HttpPost(AUTH_URI);
  110. post.addHeader(entity.getContentType());
  111. post.setEntity(entity);
  112. try {
  113. resp = getHttpClient().execute(post);
  114. String authToken = null;
  115. if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
  116. InputStream istream = (resp.getEntity() != null) ? resp.getEntity().getContent()
  117. : null;
  118. if (istream != null) {
  119. BufferedReader ireader = new BufferedReader(new InputStreamReader(istream));
  120. authToken = ireader.readLine().trim();
  121. }
  122. }
  123. if ((authToken != null) && (authToken.length() > 0)) {
  124. Log.v(TAG, "Successful authentication");
  125. return authToken;
  126. } else {
  127. Log.e(TAG, "Error authenticating" + resp.getStatusLine());
  128. return null;
  129. }
  130. } catch (final IOException e) {
  131. Log.e(TAG, "IOException when getting authtoken", e);
  132. return null;
  133. } finally {
  134. Log.v(TAG, "getAuthtoken completing");
  135. }
  136. }
  137. /**
  138. * Perform 2-way sync with the server-side contacts. We send a request that
  139. * includes all the locally-dirty contacts so that the server can process
  140. * those changes, and we receive (and return) a list of contacts that were
  141. * updated on the server-side that need to be updated locally.
  142. *
  143. * @param account The account being synced
  144. * @param authtoken The authtoken stored in the AccountManager for this
  145. * account
  146. * @param serverSyncState A token returned from the server on the last sync
  147. * @param dirtyContacts A list of the contacts to send to the server
  148. * @return A list of contacts that we need to update locally
  149. */
  150. public static List<RawContact> syncContacts(
  151. Account account, String authtoken, long serverSyncState, List<RawContact> dirtyContacts)
  152. throws JSONException, ParseException, IOException, AuthenticationException {
  153. // Convert our list of User objects into a list of JSONObject
  154. List<JSONObject> jsonContacts = new ArrayList<JSONObject>();
  155. for (RawContact rawContact : dirtyContacts) {
  156. jsonContacts.add(rawContact.toJSONObject());
  157. }
  158. // Create a special JSONArray of our JSON contacts
  159. JSONArray buffer = new JSONArray(jsonContacts);
  160. // Create an array that will hold the server-side contacts
  161. // that have been changed (returned by the server).
  162. final ArrayList<RawContact> serverDirtyList = new ArrayList<RawContact>();
  163. // Prepare our POST data
  164. final ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
  165. params.add(new BasicNameValuePair(PARAM_USERNAME, account.name));
  166. params.add(new BasicNameValuePair(PARAM_AUTH_TOKEN, authtoken));
  167. params.add(new BasicNameValuePair(PARAM_CONTACTS_DATA, buffer.toString()));
  168. if (serverSyncState > 0) {
  169. params.add(new BasicNameValuePair(PARAM_SYNC_STATE, Long.toString(serverSyncState)));
  170. }
  171. Log.i(TAG, params.toString());
  172. HttpEntity entity = new UrlEncodedFormEntity(params);
  173. // Send the updated friends data to the server
  174. Log.i(TAG, "Syncing to: " + SYNC_CONTACTS_URI);
  175. final HttpPost post = new HttpPost(SYNC_CONTACTS_URI);
  176. post.addHeader(entity.getContentType());
  177. post.setEntity(entity);
  178. final HttpResponse resp = getHttpClient().execute(post);
  179. final String response = EntityUtils.toString(resp.getEntity());
  180. if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
  181. // Our request to the server was successful - so we assume
  182. // that they accepted all the changes we sent up, and
  183. // that the response includes the contacts that we need
  184. // to update on our side...
  185. final JSONArray serverContacts = new JSONArray(response);
  186. Log.d(TAG, response);
  187. for (int i = 0; i < serverContacts.length(); i++) {
  188. RawContact rawContact = RawContact.valueOf(serverContacts.getJSONObject(i));
  189. if (rawContact != null) {
  190. serverDirtyList.add(rawContact);
  191. }
  192. }
  193. } else {
  194. if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
  195. Log.e(TAG, "Authentication exception in sending dirty contacts");
  196. throw new AuthenticationException();
  197. } else {
  198. Log.e(TAG, "Server error in sending dirty contacts: " + resp.getStatusLine());
  199. throw new IOException();
  200. }
  201. }
  202. return serverDirtyList;
  203. }
  204. /**
  205. * Download the avatar image from the server.
  206. *
  207. * @param avatarUrl the URL pointing to the avatar image
  208. * @return a byte array with the raw JPEG avatar image
  209. */
  210. public static byte[] downloadAvatar(final String avatarUrl) {
  211. // If there is no avatar, we're done
  212. if (TextUtils.isEmpty(avatarUrl)) {
  213. return null;
  214. }
  215. try {
  216. Log.i(TAG, "Downloading avatar: " + avatarUrl);
  217. // Request the avatar image from the server, and create a bitmap
  218. // object from the stream we get back.
  219. URL url = new URL(avatarUrl);
  220. HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  221. connection.connect();
  222. try {
  223. final BitmapFactory.Options options = new BitmapFactory.Options();
  224. final Bitmap avatar = BitmapFactory.decodeStream(connection.getInputStream(),
  225. null, options);
  226. // Take the image we received from the server, whatever format it
  227. // happens to be in, and convert it to a JPEG image. Note: we're
  228. // not resizing the avatar - we assume that the image we get from
  229. // the server is a reasonable size...
  230. Log.i(TAG, "Converting avatar to JPEG");
  231. ByteArrayOutputStream convertStream = new ByteArrayOutputStream(
  232. avatar.getWidth() * avatar.getHeight() * 4);
  233. avatar.compress(Bitmap.CompressFormat.JPEG, 95, convertStream);
  234. convertStream.flush();
  235. convertStream.close();
  236. // On pre-Honeycomb systems, it's important to call recycle on bitmaps
  237. avatar.recycle();
  238. return convertStream.toByteArray();
  239. } finally {
  240. connection.disconnect();
  241. }
  242. } catch (MalformedURLException muex) {
  243. // A bad URL - nothing we can really do about it here...
  244. Log.e(TAG, "Malformed avatar URL: " + avatarUrl);
  245. } catch (IOException ioex) {
  246. // If we're unable to download the avatar, it's a bummer but not the
  247. // end of the world. We'll try to get it next time we sync.
  248. Log.e(TAG, "Failed to download user avatar: " + avatarUrl);
  249. }
  250. return null;
  251. }
  252. }