Java tutorial
/* * Copyright 2015 Tapcentive, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.tapcentive.sdk.icons; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.json.JSONObject; import org.json.JSONArray; import com.android.volley.AuthFailureError; import com.android.volley.NetworkResponse; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.Response.ErrorListener; import com.android.volley.VolleyError; import com.android.volley.Request.Method; import com.android.volley.toolbox.HttpHeaderParser; import com.android.volley.toolbox.Volley; import com.tapcentive.sdk.TapcentiveLibrary; import com.tapcentive.sdk.service.util.CustomJsonObjectRequest; import com.tapcentive.sdk.touchpoint.nfc.PrefsProfileStorage; import android.annotation.SuppressLint; import android.app.IntentService; import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.util.Log; import android.webkit.MimeTypeMap; public class IconRetrievalService extends IntentService { public final String TAG = "ICON_RETRIEVAL_SERVICE"; public static String ICONDIR = "icondir"; private static RequestQueue requestQueue = null; public IconRetrievalService() { super("IconRetrievalService"); } synchronized RequestQueue getRequestQueue() { if (requestQueue == null) { requestQueue = Volley.newRequestQueue(getApplicationContext()); } return requestQueue; } class IconReference { public long id; public String url; public IconReference(long id, String url) { this.id = id; this.url = url; } } class CustomIconRequest extends Request<File> { IconReference icon; Map<String, String> headers; CustomIconRequest(IconReference icon, ErrorListener listener, Map<String, String> headers) { super(Request.Method.GET, icon.url, listener); this.icon = icon; this.headers = headers; } @Override public Map<String, String> getHeaders() throws AuthFailureError { return headers; } @SuppressLint("DefaultLocale") @Override protected Response<File> parseNetworkResponse(NetworkResponse response) { Log.d(TAG, "Got a response reading response to icon: " + icon.toString()); String contentType = ""; for (String key : response.headers.keySet()) { if (key.toLowerCase().equals("content-type")) { contentType = response.headers.get(key); break; } } MimeTypeMap mimeMap = MimeTypeMap.getSingleton(); String extension = mimeMap.getExtensionFromMimeType(contentType); if (extension.equals("jpeg")) { extension = "jpg"; } response.headers.get("content-type"); File newIconFile = new File(getApplicationContext().getFilesDir() + "/" + ICONDIR + "/" + Long.toString(icon.id) + "." + extension); try { BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newIconFile)); bos.write(response.data, 0, response.data.length); bos.close(); Log.d(TAG, "Successfully retrieved icon: " + icon.toString()); return Response.success(newIconFile, HttpHeaderParser.parseCacheHeaders(response)); } catch (FileNotFoundException e) { Log.d(TAG, "File Not Found Exception: " + e.toString()); return Response.error(new VolleyError(e)); } catch (IOException e) { Log.d(TAG, "IO Exception: " + e.toString()); return Response.error(new VolleyError(e)); } } @Override protected void deliverResponse(File response) { // Do nothing for now } } protected void retrieveIcon(IconReference icon) { // Check to see if we have this icon // If we don't have this icon Log.d(TAG, "Attempting to fetch custom icon: " + icon.toString()); Map<String, String> headers = new HashMap<String, String>(); try { final RequestQueue queue = this.getRequestQueue(); CustomIconRequest iconRequest = new CustomIconRequest(icon, new ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.d(TAG, error.toString()); } }, headers); iconRequest.getHeaders().put("User-Agent", "consumer"); // Add the request to the queue and execute queue.add(iconRequest); } catch (Exception e) { e.printStackTrace(); Log.d(TAG, "Exception" + e.toString()); } } protected void syncIcons(List<IconReference> icon_list) { Log.d(TAG, "Calling syncIcons with icon_list: " + icon_list.toString()); // Get the current list of stored icons and delete ones that aren't in the icon_list File dir = new File(getApplicationContext().getFilesDir() + "/" + ICONDIR); dir.mkdirs(); // Just make sure it exists always LinkedList<Long> localFileIds = new LinkedList<Long>(); if (dir.isDirectory()) { for (final File iconFile : dir.listFiles()) { //String iconFileId = iconFile.getName().substring(0, iconFile.getName().length()-4); // Remove .png, .gif, etc String iconFileId = iconFile.getName().substring(0, iconFile.getName().lastIndexOf(".")); // Remove extension localFileIds.add(Long.parseLong(iconFileId)); boolean found = false; for (IconReference ref : icon_list) { if (Long.toString(ref.id).equals(iconFileId)) { found = true; break; } } if (!found) { iconFile.delete(); } } Log.d(TAG, "Would start to sync icons here: " + icon_list.toString()); for (IconReference icon : icon_list) { if (!localFileIds.contains(icon.id)) { retrieveIcon(icon); } } } } @Override protected void onHandleIntent(Intent intent) { Log.d(TAG, "Called IconRetrievalService::onHandleIntent"); // Get client profile token // XXX: Is it really safe to assume we have a valid client token? getList(new ListCallback() { public void gotList(JSONObject result) { LinkedList<IconReference> icon_list = new LinkedList<IconReference>(); try { Log.d(TAG, result.toString()); JSONArray icons = result.getJSONArray("icon_list"); for (int i = 0; i < icons.length(); i++) { JSONObject icon = icons.getJSONObject(i); icon_list.add(new IconReference(icon.getLong("id"), icon.getString("url"))); } syncIcons(icon_list); } catch (Exception e) { // XXX: What to do? Log.d(TAG, "Problem getting icons list: " + e.toString()); } }; public void gotError() { Log.d(TAG, "Got an error in IRS list retrieval"); }; }); } interface ListCallback { public void gotList(JSONObject result); public void gotError(); } private void getList(final ListCallback callback) { PrefsProfileStorage prefStorage = new PrefsProfileStorage(getApplicationContext()); String consumerTemplate = prefStorage.getProfile(); Log.d(TAG, "Last profile fetch attempt: " + prefStorage.getLastAccessTime()); if (consumerTemplate == null) { Log.d(TAG, "No consumer template, skipping icon list retrieval"); // Haven't registered consumer template? return; } Map<String, String> headers = new HashMap<String, String>(); JSONObject jsonTemplate = new JSONObject(); try { headers.put("User-Agent", "consumer"); SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); String msiURLString = sharedPref.getString("pref_key_msi_url", ""); if ((msiURLString != null) && (!msiURLString.equals(""))) { String url = msiURLString + "/icon/list"; jsonTemplate.put("template", consumerTemplate); final RequestQueue queue = this.getRequestQueue(); CustomJsonObjectRequest jsonRequest = new CustomJsonObjectRequest(Method.POST, url, jsonTemplate, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { callback.gotList(response); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.d(TAG, "Error" + error.toString()); if (error == null || error.networkResponse == null) { callback.gotError(); return; } if (error.networkResponse.statusCode == 400 || error.networkResponse.statusCode == 204 || error.networkResponse.statusCode == 403) { callback.gotError(); return; } } }, headers); // Add the request to the queue and execute queue.add(jsonRequest); } } catch (Exception e) { e.printStackTrace(); Log.d(TAG, "Exception" + e.toString()); callback.gotError(); } } }