Java tutorial
// Guidebook is an Android application that reads audioguides using Text-to-Speech services. // Copyright (C) 2013 Adrin Romero Corchado // // 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 3 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, see <http://www.gnu.org/licenses/>. package com.adrguides.model; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; import com.adrguides.utils.HTTPUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.net.URL; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.UUID; /** * Created by adrian on 20/08/13. */ public class Guide implements Parcelable { private static final int THUMBNAIL_WIDTH = 96; private static final int THUMBNAIL_HEIGHT = 96; private String address; private String title; private String description; private String author; private String keywords; private String language; private String country; private String variant; private boolean stored; private List<Place> places = new ArrayList<Place>(); public Guide() { address = null; title = "* * *"; description = ""; author = ""; keywords = ""; language = Locale.getDefault().getLanguage(); country = Locale.getDefault().getCountry(); variant = Locale.getDefault().getVariant(); stored = false; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getKeywords() { return keywords; } public void setKeywords(String keywords) { this.keywords = keywords; } public String getLanguage() { return language; } public void setLanguage(String language) { this.language = language; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public String getVariant() { return variant; } public void setVariant(String variant) { this.variant = variant; } public Locale getLocale() { return new Locale(language, country, variant); } public List<Place> getPlaces() { return places; } public void setPlaces(List<Place> places) { this.places = places; } public void setStored(boolean stored) { this.stored = stored; } public boolean isStored() { return stored; } public void saveToDisk(Context context) throws IOException, JSONException { File dir = new File(context.getFilesDir(), "saved-" + sha256(getTitle() + "_" + getLanguage() + "_" + getCountry() + "_" + getVariant())); dir.mkdir(); File[] children = dir.listFiles(); for (File c : children) { c.delete(); } Map<String, String> processedimages = new HashMap<String, String>(); JSONObject jsonguide = new JSONObject(); jsonguide.put("address", getAddress()); jsonguide.put("title", getTitle()); jsonguide.put("description", getDescription()); jsonguide.put("author", getAuthor()); jsonguide.put("keywords", getKeywords()); jsonguide.put("language", getLanguage()); jsonguide.put("country", getCountry()); jsonguide.put("variant", getVariant()); JSONArray chapters = new JSONArray(); jsonguide.put("chapters", chapters); for (Place p : getPlaces()) { JSONObject chapter = new JSONObject(); chapters.put(chapter); chapter.put("id", p.getId()); chapter.put("title", p.getTitle()); JSONArray paragraphs = new JSONArray(); chapter.put("paragraphs", paragraphs); for (Section s : p.getSections()) { JSONObject section = new JSONObject(); paragraphs.put(section); section.put("text", s.getText()); section.put("read", s.getRead()); section.put("image", saveImage(context, processedimages, dir, s.getImageURL())); } } saveTextToFile(new File(dir, "guidebook.json"), jsonguide.toString()); saveTextToFile(new File(dir, "guidebook.title.txt"), getTitle()); saveTextToFile(new File(dir, "guidebook.description.txt"), getDescription()); saveTextToFile(new File(dir, "guidebook.author.txt"), getAuthor()); saveTextToFile(new File(dir, "guidebook.keywords.txt"), getKeywords()); saveTextToFile(new File(dir, "guidebook.locale.txt"), getLocale().getDisplayName()); if (getPlaces().size() > 0 && getPlaces().get(0).getSections().size() > 0 && getPlaces().get(0).getSections().get(0).getImageURL() != null) { saveBitmapToFile(context, new File(dir, "guidebook.image.png"), new URL(getPlaces().get(0).getSections().get(0).getImageURL())); } // setStored(true); } private void saveTextToFile(File f, String text) throws IOException { Writer filewriter = null; try { filewriter = new OutputStreamWriter(new FileOutputStream(f), "UTF-8"); filewriter.append(text); } finally { if (filewriter != null) { try { filewriter.close(); } catch (IOException e) { } } } } private void saveBitmapToFile(Context context, File f, URL imageURL) throws IOException { InputStream in = null; OutputStream out = null; try { Bitmap newbmp; // read bitmap from source. in = HTTPUtils.openAddress(context, imageURL); Bitmap bmp = BitmapFactory.decodeStream(in); int w = bmp.getWidth(); int h = bmp.getHeight(); if (w > h) { newbmp = Bitmap.createBitmap(bmp, (w - h) / 2, 0, h, h); } else { newbmp = Bitmap.createBitmap(bmp, 0, (h - w) / 2, w, w); } if (newbmp != bmp) { bmp.recycle(); bmp = newbmp; } float density = context.getResources().getDisplayMetrics().density; newbmp = Bitmap.createScaledBitmap(bmp, (int) (THUMBNAIL_WIDTH * density), (int) (THUMBNAIL_HEIGHT * density), true); if (newbmp != bmp) { bmp.recycle(); bmp = newbmp; } // store in local filesystem. out = new FileOutputStream(f); bmp.compress(Bitmap.CompressFormat.PNG, 100, out); bmp.recycle(); } finally { if (out != null) { out.close(); } if (in != null) { in.close(); } } } private String saveImage(Context context, Map<String, String> processedimages, File dir, String address) throws IOException { String outImage = processedimages.get(address); if (outImage == null) { InputStream inimage; try { inimage = HTTPUtils.openAddress(context, new URL(address)); } catch (IOException e) { return null; } OutputStream outimage = null; try { File outfile = new File(dir, "img-" + UUID.randomUUID().toString() + ".png"); outimage = new FileOutputStream(outfile); byte[] buffer = new byte[1024]; int len; while ((len = inimage.read(buffer)) != -1) { outimage.write(buffer, 0, len); } outImage = outfile.toURI().toURL().toString(); processedimages.put(address, outImage); } finally { if (inimage != null) { try { inimage.close(); } catch (IOException e) { } } if (outimage != null) { try { outimage.close(); } catch (IOException e) { } } } } return outImage; } private static String sha256(String base) { try { MessageDigest digest = MessageDigest.getInstance("SHA-256"); return bytesToHex(digest.digest(base.getBytes("UTF-8"))); } catch (NoSuchAlgorithmException ex) { throw new RuntimeException(ex); } catch (UnsupportedEncodingException ex) { throw new RuntimeException(ex); } } // private final static char[] hexArray = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; private final static char[] hexArray = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p' }; private static String bytesToHex(byte[] bytes) { char[] chars = new char[bytes.length * 2]; int v; int index = 0; for (byte b : bytes) { v = b & 0xFF; chars[index++] = hexArray[v >>> 4]; chars[index++] = hexArray[v & 0x0F]; } return new String(chars); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int i) { parcel.writeString(getAddress()); parcel.writeString(getTitle()); parcel.writeString(getDescription()); parcel.writeString(getAuthor()); parcel.writeString(getKeywords()); parcel.writeString(getLanguage()); parcel.writeString(getCountry()); parcel.writeString(getVariant()); parcel.writeTypedList(getPlaces()); parcel.writeInt(isStored() ? 1 : 0); } public static final Parcelable.Creator<Guide> CREATOR = new Parcelable.Creator<Guide>() { public Guide createFromParcel(Parcel in) { Guide guide = new Guide(); guide.setAddress(in.readString()); guide.setTitle(in.readString()); guide.setDescription(in.readString()); guide.setAuthor(in.readString()); guide.setKeywords(in.readString()); guide.setLanguage(in.readString()); guide.setCountry(in.readString()); guide.setVariant(in.readString()); guide.setPlaces(in.createTypedArrayList(Place.CREATOR)); guide.setStored(in.readInt() == 1); return guide; } public Guide[] newArray(int size) { return new Guide[size]; } }; }