Java tutorial
/* This file is part of AbianReader. AbianReader 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. AbianReader 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 AbianReader. If not, see <http://www.gnu.org/licenses/>. */ package com.abiansoftware.lib.reader; /* import java.io.File; import java.io.FileOutputStream; */ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Vector; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import java.text.DateFormat; import org.json.JSONArray; import org.json.JSONObject; import com.loopj.android.http.*; import android.os.Looper; import android.text.format.Time; import android.util.Log; public class AbianReaderData { private static final String TAG = "AbianReaderData"; public static final int MAX_DATA_ITEMS = 100; //private static Object SYNC_OBJ = new Object(); static public class AbianReaderItem { private String m_itemTitle; private String m_itemLink; private String m_itemContent; private String m_itemDescription; private Date m_itemPubDate; private String m_itemCreator; private String m_itemCommentsLink; private int m_itemCommentCount; private String m_thumbnailLink; private Bitmap m_thumbnailBitmap; private String m_featuredImageLink; private Bitmap m_featuredImageBitmap; private boolean m_bIsFeatured; @SuppressWarnings("unused") private boolean m_bIsGettingThumbnail; @SuppressWarnings("unused") private boolean m_bIsGettingFeatureImage; @SuppressWarnings("unused") private boolean m_bIsGettingExtraJsonData; private boolean m_bHasBeenRead; public AbianReaderItem() { m_itemTitle = ""; m_itemLink = ""; m_itemContent = ""; m_itemDescription = ""; m_itemPubDate = new Date(); m_itemCreator = ""; m_itemCommentsLink = ""; m_itemCommentCount = 0; m_thumbnailLink = ""; m_thumbnailBitmap = null; m_featuredImageLink = ""; m_bIsFeatured = false; m_bHasBeenRead = false; m_bIsGettingThumbnail = false; m_bIsGettingFeatureImage = false; m_bIsGettingExtraJsonData = false; } public String getTitle() { return m_itemTitle; } public String getLink() { return m_itemLink; } public String getContent() { return m_itemContent; } public String getDescription() { return m_itemDescription; } public String getPubDate() { String dateStr = DateFormat.getDateInstance(DateFormat.LONG).format(m_itemPubDate); String timeStr = DateFormat.getTimeInstance(DateFormat.SHORT).format(m_itemPubDate); return dateStr + " at " + timeStr; } public String getPubDateOnly() { return DateFormat.getDateInstance(DateFormat.LONG).format(m_itemPubDate); } public String getPubDateLong() { SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z"); return sdf.format(m_itemPubDate); } public String getCreator() { return m_itemCreator; } public String getCommentsLink() { return m_itemCommentsLink; } public int getCommentsCount() { return m_itemCommentCount; } public void setTitle(String itemTitle) { if (itemTitle == null) { itemTitle = ""; } m_itemTitle = itemTitle; } public void setLink(String itemLink) { if (itemLink == null) { itemLink = ""; } m_itemLink = itemLink; } public void setContent(String itemContent) { if (itemContent == null) { itemContent = ""; } m_itemContent = itemContent; } public void setDescription(String itemDescription) { if (itemDescription == null) { itemDescription = ""; } m_itemDescription = itemDescription; } public void setPubDate(String itemPubDate) { SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z"); if (itemPubDate == null) { itemPubDate = ""; } try { m_itemPubDate = sdf.parse(itemPubDate); } catch (ParseException e) { Log.e(TAG, e.toString()); } } public void setJsonDate(String itemPubDate) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); if (itemPubDate == null) { itemPubDate = ""; } try { m_itemPubDate = sdf.parse(itemPubDate); } catch (ParseException e) { Log.e(TAG, e.toString()); } } public void setCreator(String itemCreator) { if (itemCreator == null) { itemCreator = ""; } m_itemCreator = itemCreator; } public void setCommentsLink(String itemCommentsLink) { if (itemCommentsLink == null) { itemCommentsLink = ""; } m_itemCommentsLink = itemCommentsLink; } public void setCommentCount(int itemCommentCount) { if (itemCommentCount < 0) { itemCommentCount = 0; } m_itemCommentCount = itemCommentCount; } public void setThumbnailLink(String thumbnailLink) { if (thumbnailLink == null) { thumbnailLink = ""; } m_thumbnailLink = thumbnailLink; AbianReaderApplication.getInstance().sendDataUpdatedMessage(); /* if(thumbnailLink.length() > 0) { // check to see if this image has been cached already File thumbnailFile = new File(getThumbnailImageCacheFilePath()); if(thumbnailFile.exists()) { loadThumbnailImageFromCache(); } else { String[] allowedContentTypes = new String[] { "image/png", "image/jpeg", "image/gif" }; m_bIsGettingThumbnail = true; AbianReaderApplication.DoHttpBinaryGet(thumbnailLink, new BinaryHttpResponseHandler(allowedContentTypes) { @Override public void onSuccess(byte[] fileData) { File thumbnailFile = new File(getThumbnailImageCacheFilePath()); try { FileOutputStream thumbnailFileOutputStream = new FileOutputStream(thumbnailFile); thumbnailFileOutputStream.write(fileData); thumbnailFileOutputStream.flush(); thumbnailFileOutputStream.close(); loadThumbnailImageFromCache(); } catch(Exception e) { Log.e(TAG, e.toString()); } m_bIsGettingThumbnail = false; } public void onFailure(Throwable e, byte[] imageData) { Log.e(TAG, "AsyncHttp failed thumb"); m_bIsGettingThumbnail = false; } }); } } */ } /* private String getThumbnailImageCacheFilePath() { File appCacheDirectory = AbianReaderApplication.getInstance().getCacheDir(); String thumbnailImageFileName = m_thumbnailLink.substring(m_thumbnailLink.lastIndexOf('/') + 1, m_thumbnailLink.length()); String thumbnailImageFilePath = appCacheDirectory.getAbsolutePath() + '/' + thumbnailImageFileName; return thumbnailImageFilePath; } private String getFeatureImageCacheFilePath() { File appCacheDirectory = AbianReaderApplication.getInstance().getCacheDir(); String featureImageFileName = m_featuredImageLink.substring(m_featuredImageLink.lastIndexOf('/') + 1, m_featuredImageLink.length()); String featureImageFilePath = appCacheDirectory.getAbsolutePath() + '/' + featureImageFileName; return featureImageFilePath; } private void loadThumbnailImageFromCache() { File thumbnailImageFile = new File(getThumbnailImageCacheFilePath()); if(thumbnailImageFile.exists() && thumbnailImageFile.isFile()) { synchronized(SYNC_OBJ) { int imgWid = AbianReaderApplication.s_width/4; int imgHei = AbianReaderApplication.s_height/4; m_thumbnailBitmap = AbianReaderData.decodeSampledBitmapFromFile(thumbnailImageFile.getAbsolutePath(), imgWid, imgHei); } if(m_thumbnailBitmap == null) { Log.e(TAG, "AsyncHttp thumb bitmap decode failed"); } AbianReaderApplication.getInstance().sendDataUpdatedMessage(); } } private void loadFeaturedImageFromCache() { File featuredImageFile = new File(getFeatureImageCacheFilePath()); if(featuredImageFile.exists() && featuredImageFile.isFile()) { synchronized(SYNC_OBJ) { int imgWid = AbianReaderApplication.s_width; int imgHei = AbianReaderApplication.s_height/4; m_featuredImageBitmap = AbianReaderData.decodeSampledBitmapFromFile(featuredImageFile.getAbsolutePath(), imgWid, imgHei); } if(m_featuredImageBitmap == null) { Log.e(TAG, "AsyncHttp featured bitmap decode failed, " + featuredImageFile.getAbsolutePath()); } AbianReaderApplication.getInstance().sendDataUpdatedMessage(); } } */ public String getThumbnailLink() { if (m_thumbnailLink == null) { m_thumbnailLink = ""; } return m_thumbnailLink; } public void setFeaturedImageLink(String featuredImageLink, boolean bIsFeatured) { if (featuredImageLink == null) { featuredImageLink = ""; } m_featuredImageLink = featuredImageLink; m_bIsFeatured = bIsFeatured; AbianReaderApplication.getInstance().sendDataUpdatedMessage(); /* if((featuredImageLink.length() > 0) && m_bIsFeatured) { // check to see if this image has been cached already File featuredImageFile = new File(getFeatureImageCacheFilePath()); if(featuredImageFile.exists()) { loadFeaturedImageFromCache(); } else { String[] allowedContentTypes = new String[] { "image/png", "image/jpeg", "image/gif" }; m_bIsGettingFeatureImage = true; AbianReaderApplication.DoHttpBinaryGet(featuredImageLink, new BinaryHttpResponseHandler(allowedContentTypes) { @Override public void onSuccess(byte[] fileData) { File featureFile = new File(getFeatureImageCacheFilePath()); try { FileOutputStream featureFileOutputStream = new FileOutputStream(featureFile); featureFileOutputStream.write(fileData); featureFileOutputStream.flush(); featureFileOutputStream.close(); loadFeaturedImageFromCache(); } catch(Exception e) { Log.e(TAG, e.toString()); } m_bIsGettingFeatureImage = false; } public void onFailure(Throwable e, byte[] imageData) { Log.e(TAG, "AsyncHttp failed"); m_bIsGettingFeatureImage = false; } }); } } */ } public String getFeaturedImageLink() { if (m_featuredImageLink == null) { m_featuredImageLink = ""; } return m_featuredImageLink; } public boolean getIsFeatured() { return m_bIsFeatured; } public Bitmap getThumbnailBitmap() { return m_thumbnailBitmap; } public void setThumbnailBitmap(Bitmap thumbnailBitmap) { m_thumbnailBitmap = thumbnailBitmap; } public Bitmap getFeaturedImageBitmap() { return m_featuredImageBitmap; } public void setFeaturedImageBitmap(Bitmap featuredImageBitmap) { m_featuredImageBitmap = featuredImageBitmap; } public void getExtraJsonData(final boolean bGetFeature) { m_bIsGettingExtraJsonData = true; String extraJsonDataUrl = m_itemLink; extraJsonDataUrl += "/?json=1&include=thumbnail,attachments"; if (bGetFeature) { extraJsonDataUrl += ",tags"; } extraJsonDataUrl += "&no_redirect=true"; AbianReaderApplication.DoHttpGet(extraJsonDataUrl, null, new AsyncHttpResponseHandler() { @Override public void onSuccess(String response) { try { JSONObject rootObject = new JSONObject(response); JSONObject thisPostObject = rootObject.getJSONObject("post"); boolean bThisPostIsFeatured = false; String thisPostThumbnailLink = thisPostObject.getString("thumbnail"); String thisFeatureImageLink = ""; if (thisPostObject.has("attachments")) { JSONArray attachmentArray = thisPostObject.getJSONArray("attachments"); for (int attachmentPos = 0; attachmentPos < attachmentArray.length(); attachmentPos++) { JSONObject thisAttachment = attachmentArray.getJSONObject(attachmentPos); if (thisAttachment.has("images")) { JSONObject imagesObject = thisAttachment.getJSONObject("images"); JSONObject fullImageObject = imagesObject.getJSONObject("full"); String thisUrl = fullImageObject.getString("url"); if (thisFeatureImageLink.length() == 0) { thisFeatureImageLink = thisUrl; } else { int matchingCurrentFeature = AbianReaderDataFetcher .GetNumberOfSameCharacters(thisPostThumbnailLink, thisFeatureImageLink); int matchingThisFeature = AbianReaderDataFetcher .GetNumberOfSameCharacters(thisPostThumbnailLink, thisUrl); if (matchingThisFeature > matchingCurrentFeature) { thisFeatureImageLink = thisUrl; } } } } } if (thisPostObject.has("tags") && bGetFeature) { JSONArray tagArray = thisPostObject.getJSONArray("tags"); for (int tagPos = 0; tagPos < tagArray.length(); tagPos++) { JSONObject thisTag = tagArray.getJSONObject(tagPos); String tagName = thisTag.getString("title"); if (tagName.equalsIgnoreCase(AbianReaderDataFetcher.GetFeaturedTag())) { bThisPostIsFeatured = true; break; } } } setThumbnailLink(thisPostThumbnailLink); setFeaturedImageLink(thisFeatureImageLink, bThisPostIsFeatured); } catch (Exception e) { } } }); } public boolean getHasArticleBeenRead() { return m_bHasBeenRead; } public void setArticleHasBeenRead(boolean bSaveToDisk) { m_bHasBeenRead = true; if (bSaveToDisk) { AbianReaderApplication.getInstance().saveReadUrlList(); } } public void shareItem() { AbianReaderApplication theSingleton = AbianReaderApplication.getInstance(); String shareMessage = theSingleton.getString(R.string.share_message); String shareTitle = theSingleton.getString(R.string.share_title); Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); sharingIntent.setType("text/plain"); sharingIntent.putExtra(Intent.EXTRA_SUBJECT, shareMessage); sharingIntent.putExtra(Intent.EXTRA_TEXT, getLink()); theSingleton.startActivity(Intent.createChooser(sharingIntent, shareTitle)); } } private Vector<AbianReaderItem> m_itemVector; private Vector<AbianReaderItem> m_newItemVector; private Time m_lastUpdateTime; private int m_pageNumber; private int m_autoUpdateTimeInMinutes; public AbianReaderData() { m_itemVector = new Vector<AbianReaderItem>(); m_newItemVector = new Vector<AbianReaderItem>(); m_itemVector.clear(); m_lastUpdateTime = new Time(Time.getCurrentTimezone()); m_lastUpdateTime.set(0); m_pageNumber = 1; m_autoUpdateTimeInMinutes = 0; } public synchronized void addItem(AbianReaderItem newItem) { //Log.e(getClass().getName(), "Enter addItem"); if (Looper.myLooper() != Looper.getMainLooper()) { //Log.e(getClass().getName(), "not on main thread, adding to the new item vector"); m_newItemVector.add(newItem); } else { //Log.e(getClass().getName(), "on main thread, adding to the item vector"); m_itemVector.add(newItem); } //Log.e(getClass().getName(), "Leave addItem"); } public synchronized void syncItems() { if (Looper.myLooper() == Looper.getMainLooper()) { if (m_newItemVector.size() > 0) { //Log.e(getClass().getName(), "Enter syncItems on main thread"); //Log.e(getClass().getName(), "on main thread adding vectors"); for (int i = 0; i < m_newItemVector.size(); i++) { m_itemVector.add(m_newItemVector.get(i)); } m_newItemVector.clear(); //Log.e(getClass().getName(), "Exit syncItems"); } } else { Log.e(getClass().getName(), "syncItems not on main thread"); } } public int getNumberOfItems() { return m_itemVector.size(); } public AbianReaderItem getItemNumber(int itemNumber) { if ((itemNumber >= 0) && (itemNumber < getNumberOfItems())) { return m_itemVector.elementAt(itemNumber); } return null; } public synchronized void clear() { m_itemVector.clear(); m_lastUpdateTime.set(0); m_newItemVector.clear(); } public void setLastUpdateTimeToNow() { m_lastUpdateTime.setToNow(); } public void setLastUpdateTime(long lastUpdateTimeInMillis) { m_lastUpdateTime.set(lastUpdateTimeInMillis); } public Time getLastUpdateTime() { return m_lastUpdateTime; } public void setPageNumber(int newPageNumber) { if (newPageNumber < 1) { newPageNumber = 1; } m_pageNumber = newPageNumber; } public int getPageNumber() { return m_pageNumber; } public int getAutoUpdateTimeInMinutes() { return m_autoUpdateTimeInMinutes; } public void setAutoUpdateTimeInMinutes(int minutes) { if (minutes < 0) { minutes = 0; } m_autoUpdateTimeInMinutes = minutes; } public int getNumberedOfFeaturedArticles() { int retVal = 0; for (int i = 0; i < this.m_itemVector.size(); i++) { if (m_itemVector.get(i).getIsFeatured()) { retVal++; } } return retVal; } public int getFeaturedArticlePosition(int featuredArticleNumber) { int featuredArticleCount = 0; for (int i = 0; i < m_itemVector.size(); i++) { if (m_itemVector.get(i).getIsFeatured()) { if (featuredArticleNumber == featuredArticleCount) { return i; } featuredArticleCount++; } } return 0; } public AbianReaderItem getFeaturedItem(int itemNumber) { if (getNumberedOfFeaturedArticles() <= 0) { return null; } if ((itemNumber < 0) || (itemNumber >= getNumberedOfFeaturedArticles())) { itemNumber = 0; } return getItemNumber(getFeaturedArticlePosition(itemNumber)); } public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { if (width > height) { inSampleSize = Math.round((float) height / (float) reqHeight); } else { inSampleSize = Math.round((float) width / (float) reqWidth); } } return inSampleSize; } public static Bitmap decodeSampledBitmapFromFile(String filePath, int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(filePath, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(filePath, options); } }