From cc5a5695dab3e23e2b3a4324aafea149c252f92f Mon Sep 17 00:00:00 2001 From: David Development Date: Mon, 21 Apr 2014 16:56:16 +0200 Subject: [PATCH] Performance Update --- .../News-Android-App-News-Android-App.iml | 1 + News-Android-App/build.gradle | 2 +- News-Android-App/src/main/AndroidManifest.xml | 4 +- .../DownloadImagesActivity.java | 2 +- .../SubscriptionExpandableListAdapter.java | 183 ++++++++------- .../owncloudnewsreader/NewFeedActivity.java | 17 -- .../NewsReaderDetailFragment.java | 82 ++++--- .../NewsReaderListActivity.java | 4 +- .../SyncIntervalSelectorActivity.java | 1 - .../cursor/NewsListCursorAdapter.java | 210 +++++++++++++----- .../database/DatabaseConnection.java | 30 ++- .../helper/FavIconHandler.java | 84 ++++--- .../helper/ImageHandler.java | 64 +++--- .../reader/DownloadItemsToCache.java | 15 +- .../services/DownloadImagesService.java | 121 ++++++---- ...subscription_detail_list_item_extended.xml | 41 ++-- .../subscription_detail_list_item_simple.xml | 73 +++--- .../res/layout/subscription_list_item.xml | 18 +- .../src/main/res/values/colors.xml | 4 +- 19 files changed, 566 insertions(+), 390 deletions(-) diff --git a/News-Android-App/News-Android-App-News-Android-App.iml b/News-Android-App/News-Android-App-News-Android-App.iml index 5b339665..7c8b1235 100644 --- a/News-Android-App/News-Android-App-News-Android-App.iml +++ b/News-Android-App/News-Android-App-News-Android-App.iml @@ -72,6 +72,7 @@ + diff --git a/News-Android-App/build.gradle b/News-Android-App/build.gradle index ebfb64bb..3612835d 100644 --- a/News-Android-App/build.gradle +++ b/News-Android-App/build.gradle @@ -35,9 +35,9 @@ android { dependencies { compile 'com.android.support:support-v4:19.0.+' compile 'com.jakewharton:butterknife:4.0.+' + compile 'com.squareup.picasso:picasso:2.2.0@jar' compile 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar' compile 'com.github.chrisbanes.actionbarpulltorefresh:extra-abs:+' - // You must install or update the Google Repository through the SDK manager to use this dependency. // The Google Repository (separate from the corresponding library) can be found in the Extras category. // compile 'com.google.android.gms:play-services:4.2.42' diff --git a/News-Android-App/src/main/AndroidManifest.xml b/News-Android-App/src/main/AndroidManifest.xml index 953129c1..6de5a541 100644 --- a/News-Android-App/src/main/AndroidManifest.xml +++ b/News-Android-App/src/main/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="44" + android:versionName="0.5.9" > 0) - new FavIconHandler().GetImageAsync(imgView, favIconURL, mContext, feedID, favIconCache); - else - imgView.setImageResource(FavIconHandler.getResourceIdForRightDefaultFeedIcon(mContext)); - } - else - imgView.setImageResource(FavIconHandler.getResourceIdForRightDefaultFeedIcon(mContext)); - } - catch(Exception ex) - { - ex.printStackTrace(); - } - } + + static class GroupHolder { - TextView txt_Summary; - TextView txt_UnreadCount; - ImageView imgView; + @InjectView(R.id.summary) TextView txt_Summary; + @InjectView(R.id.tV_feedsCount) TextView txt_UnreadCount; + @InjectView(R.id.img_View_expandable_indicator) ImageView imgView; + + public GroupHolder(View view, Context mContext) { + ButterKnife.inject(this, view); + + txt_Summary.setClickable(true); + + FontHelper fHelper = new FontHelper(mContext); + fHelper.setFontForAllChildren(view, fHelper.getFont()); + } } diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewFeedActivity.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewFeedActivity.java index aad5f205..f80e8bd3 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewFeedActivity.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewFeedActivity.java @@ -3,47 +3,30 @@ package de.luhmer.owncloudnewsreader; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.annotation.TargetApi; -import android.app.Activity; -import android.app.LoaderManager.LoaderCallbacks; -import android.content.ContentResolver; import android.content.Context; -import android.content.CursorLoader; import android.content.Intent; -import android.content.Loader; -import android.database.Cursor; -import android.net.Uri; import android.os.AsyncTask; -import android.os.Build.VERSION; import android.os.Build; import android.os.Bundle; -import android.provider.ContactsContract; -import android.support.v4.app.NavUtils; import android.text.TextUtils; import android.util.Log; -import android.view.KeyEvent; import android.view.View; import android.view.View.OnClickListener; -import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.ArrayAdapter; -import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.EditText; import android.widget.Spinner; -import android.widget.TextView; import com.actionbarsherlock.app.SherlockActivity; import com.actionbarsherlock.view.MenuItem; import java.net.URL; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import butterknife.ButterKnife; import butterknife.InjectView; import de.luhmer.owncloudnewsreader.database.DatabaseConnection; -import de.luhmer.owncloudnewsreader.reader.GoogleReaderApi.HttpHelper; import de.luhmer.owncloudnewsreader.reader.HttpJsonRequest; import de.luhmer.owncloudnewsreader.reader.owncloud.API; import de.luhmer.owncloudnewsreader.reader.owncloud.apiv2.APIv2; diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderDetailFragment.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderDetailFragment.java index ee8b8ab1..a01ad60b 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderDetailFragment.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderDetailFragment.java @@ -45,7 +45,6 @@ import com.devspark.robototextview.widget.RobotoCheckBox; import java.util.ArrayList; -import de.luhmer.owncloudnewsreader.ListView.BlockingExpandableListView; import de.luhmer.owncloudnewsreader.ListView.BlockingListView; import de.luhmer.owncloudnewsreader.ListView.SubscriptionExpandableListAdapter; import de.luhmer.owncloudnewsreader.cursor.IOnStayUnread; @@ -70,12 +69,12 @@ public class NewsReaderDetailFragment extends SherlockListFragment implements IO protected static final String TAG = "NewsReaderDetailFragment"; //private DatabaseConnection dbConn; - - //private boolean DialogShowedToMarkLastItemsAsRead = false; - + + //private boolean DialogShowedToMarkLastItemsAsRead = false; + /* private NewsListCursorAdapter lvAdapter; - + public NewsListCursorAdapter getLvAdapter() { return lvAdapter; }*/ @@ -97,7 +96,7 @@ public class NewsReaderDetailFragment extends SherlockListFragment implements IO } String titel; - + /** * @return the titel */ @@ -115,11 +114,11 @@ public class NewsReaderDetailFragment extends SherlockListFragment implements IO //private static ArrayList databaseIdsOfItems; ArrayList stayUnreadCheckboxes; - + /** * Mandatory empty constructor for the fragment manager to instantiate the * fragment (e.g. upon screen orientation changes). - */ + */ public NewsReaderDetailFragment() { //databaseIdsOfItems = new ArrayList(); stayUnreadCheckboxes = new ArrayList(); @@ -128,23 +127,23 @@ public class NewsReaderDetailFragment extends SherlockListFragment implements IO public void setUpdateListViewOnStartUp(boolean reloadCursorOnStartUp) { this.reloadCursorOnStartUp = reloadCursorOnStartUp; } - + public void setActivatedPosition(int position) { mActivatedPosition = position; } public void setMarginFromTop(int margin) { marginFromTop = margin; } - - + + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - + //setRetainInstance(true); - + //dbConn = new DatabaseConnection(getActivity()); - + if(getArguments() != null) { if (getArguments().containsKey(NewsReaderListActivity.SUBSCRIPTION_ID)) { idFeed = getArguments().getString(NewsReaderListActivity.SUBSCRIPTION_ID); @@ -155,13 +154,13 @@ public class NewsReaderDetailFragment extends SherlockListFragment implements IO if (getArguments().containsKey(NewsReaderListActivity.FOLDER_ID)) { idFolder = getArguments().getString(NewsReaderListActivity.FOLDER_ID); } - + ((SherlockFragmentActivity) getActivity()).getSupportActionBar().setTitle(titel); - + UpdateMenuItemsState();//Is called on Tablets and Smartphones but on Smartphones the menuItemDownloadMoreItems is null. So it will be ignored - + //getListView().setLayerType(View.LAYER_TYPE_SOFTWARE, null); - + //lvAdapter = null; getActivity().getSupportLoaderManager().destroyLoader(0); @@ -172,10 +171,10 @@ public class NewsReaderDetailFragment extends SherlockListFragment implements IO UpdateCursor(); } } - + public void UpdateMenuItemsState() - { + { if(MenuUtilsSherlockFragmentActivity.getMenuItemDownloadMoreItems() != null) { if(idFolder != null) { @@ -187,45 +186,45 @@ public class NewsReaderDetailFragment extends SherlockListFragment implements IO MenuUtilsSherlockFragmentActivity.getMenuItemDownloadMoreItems().setEnabled(false); } } - - + + /* (non-Javadoc) * @see android.support.v4.app.ListFragment#onViewCreated(android.view.View, android.os.Bundle) */ @Override public void onViewCreated(View view, Bundle savedInstanceState) { - + SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); if(mPrefs.getBoolean(SettingsActivity.CB_MARK_AS_READ_WHILE_SCROLLING_STRING, false)) - { + { getListView().setOnScrollListener(new AbsListView.OnScrollListener() { - + public void onScrollStateChanged(AbsListView view, int scrollState) { - + } - + RobotoCheckBox lastViewedArticleCheckbox = null; public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount, int totalItemCount) { - + if(lastViewedArticleCheckbox == null) - lastViewedArticleCheckbox = getCheckBoxAtPosition(0, view); + lastViewedArticleCheckbox = getCheckBoxAtPosition(0, view); RobotoCheckBox cb = getCheckBoxAtPosition(0, view); if(lastViewedArticleCheckbox != cb) { if(! (lastViewedArticleCheckbox.isChecked() && stayUnreadCheckboxes.contains(lastViewedArticleCheckbox))); NewsListCursorAdapter.ChangeCheckBoxState(lastViewedArticleCheckbox, true, getActivity()); - + lastViewedArticleCheckbox = cb; } } }); } - + super.onViewCreated(view, savedInstanceState); } - - - + + + private RobotoCheckBox getCheckBoxAtPosition(int pos, AbsListView viewLV) { ListView lv = (ListView) viewLV; @@ -250,7 +249,7 @@ public class NewsReaderDetailFragment extends SherlockListFragment implements IO public void UpdateCursor() { try - { + { LoaderManager loader = getActivity().getSupportLoaderManager(); loader.initLoader(0, null, loaderCallbacks); } @@ -270,7 +269,6 @@ public class NewsReaderDetailFragment extends SherlockListFragment implements IO public void onLoadFinished(Loader loader, Cursor cursor) { NewsListCursorAdapter nca = (NewsListCursorAdapter) getListAdapter(); - // Block children layout for now BlockingListView bView = ((BlockingListView) getListView()); @@ -360,7 +358,7 @@ public class NewsReaderDetailFragment extends SherlockListFragment implements IO DatabaseConnection dbConn = new DatabaseConnection(context); return dbConn.getCurrentSelectedRssItems(getSortDirection(context)); } - + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -369,23 +367,23 @@ public class NewsReaderDetailFragment extends SherlockListFragment implements IO } - + public static class NewsDetailCursorLoader extends SimpleCursorLoader { String idFolder; String idFeed; - + public NewsDetailCursorLoader(Context context, String idFolder, String idFeed) { - super(context); + super(context); this.idFolder = idFolder; this.idFeed = idFeed; } - @Override + @Override public Cursor loadInBackground() { return getRightCusor(getContext() /*, idFolder, idFeed */); } } - + @Override public void onListItemClick(ListView l, View v, int position, long id) { diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListActivity.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListActivity.java index 065e65e6..9720a116 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListActivity.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListActivity.java @@ -28,9 +28,6 @@ import android.content.Intent; import android.content.SharedPreferences; import android.os.Build; import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; import android.os.RemoteException; import android.preference.PreferenceManager; import android.provider.Settings; @@ -508,6 +505,7 @@ public class NewsReaderListActivity extends MenuUtilsSherlockFragmentActivity im long highestItemId = dbConn.getLowestItemIdUnread(); Intent service = new Intent(this, DownloadImagesService.class); service.putExtra(DownloadImagesService.LAST_ITEM_ID, highestItemId); + //service.putExtra(DownloadImagesService.DOWNLOAD_FAVICONS_EXCLUSIVE, true); startService(service); } finally { dbConn.closeDatabase(); diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/SyncIntervalSelectorActivity.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/SyncIntervalSelectorActivity.java index be402760..f08edde0 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/SyncIntervalSelectorActivity.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/SyncIntervalSelectorActivity.java @@ -14,7 +14,6 @@ import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ListView; - import com.actionbarsherlock.app.SherlockFragment; import com.actionbarsherlock.app.SherlockFragmentActivity; import com.actionbarsherlock.view.Menu; diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/cursor/NewsListCursorAdapter.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/cursor/NewsListCursorAdapter.java index d9221756..9a9480e1 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/cursor/NewsListCursorAdapter.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/cursor/NewsListCursorAdapter.java @@ -26,6 +26,7 @@ import android.annotation.TargetApi; import android.content.Context; import android.content.SharedPreferences; import android.database.Cursor; +import android.os.AsyncTask; import android.os.Build; import android.preference.PreferenceManager; import android.support.v4.widget.CursorAdapter; @@ -37,6 +38,9 @@ import android.text.style.ForegroundColorSpan; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.AlphaAnimation; +import android.view.animation.Animation; import android.webkit.WebView; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; @@ -47,6 +51,10 @@ import com.actionbarsherlock.app.SherlockFragmentActivity; import com.devspark.robototextview.widget.RobotoCheckBox; import com.devspark.robototextview.widget.RobotoTextView; +import java.lang.ref.WeakReference; + +import butterknife.ButterKnife; +import butterknife.InjectView; import de.luhmer.owncloudnewsreader.NewsDetailFragment; import de.luhmer.owncloudnewsreader.NewsReaderListActivity; import de.luhmer.owncloudnewsreader.R; @@ -66,26 +74,26 @@ public class NewsListCursorAdapter extends CursorAdapter { final int LengthBody = 300; ForegroundColorSpan bodyForegroundColor; IOnStayUnread onStayUnread; - + PostDelayHandler pDelayHandler; - + int selectedDesign = 0; - + @SuppressLint("SimpleDateFormat") @SuppressWarnings("deprecation") public NewsListCursorAdapter(Context context, Cursor c, IOnStayUnread onStayUnread) { super(context, c); this.onStayUnread = onStayUnread; - + pDelayHandler = new PostDelayHandler(context); - + //simpleDateFormat = new SimpleDateFormat("EEE, d. MMM HH:mm:ss"); bodyForegroundColor = new ForegroundColorSpan(context.getResources().getColor(android.R.color.secondary_text_dark)); _Reader = new OwnCloud_Reader(); dbConn = new DatabaseConnection(context); - + SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext); selectedDesign = Integer.valueOf(mPrefs.getString(SettingsActivity.SP_FEED_LIST_LAYOUT, "0")); } @@ -93,27 +101,27 @@ public class NewsListCursorAdapter extends CursorAdapter { @Override public void bindView(final View view, final Context context, Cursor cursor) { final String idItemDb = cursor.getString(0); - + switch (selectedDesign) { case 0: setSimpleLayout(view, cursor); break; - + case 1: setExtendedLayout(view, cursor); break; - + case 2: setExtendedLayoutWebView(view, cursor); break; - + default: break; } - + FontHelper fHelper = new FontHelper(context); fHelper.setFontForAllChildren(view, fHelper.getFont()); - + RobotoCheckBox cbStarred = (RobotoCheckBox) view.findViewById(R.id.cb_lv_item_starred); if(ThemeChooser.isDarkTheme(mContext)) cbStarred.setBackgroundResource(R.drawable.checkbox_background_holo_dark); @@ -129,14 +137,14 @@ public class NewsListCursorAdapter extends CursorAdapter { cbStarred.setChecked(isStarred); cbStarred.setClickable(true); cbStarred.setOnCheckedChangeListener(new OnCheckedChangeListener() { - + @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { dbConn.updateIsStarredOfItem(idItemDb, isChecked); if(isChecked) UpdateIsReadCheckBox(buttonView, idItemDb); - + pDelayHandler.DelayTimer(); } }); @@ -163,17 +171,17 @@ public class NewsListCursorAdapter extends CursorAdapter { fHelper.setFontStyleForSingleView(textView, fHelper.getFontUnreadStyle()); } - + cbRead.setClickable(true); cbRead.setOnCheckedChangeListener(new OnCheckedChangeListener() { - + @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { ChangeReadStateOfItem((RobotoCheckBox) buttonView, view, isChecked, context); } }); - - + + String colorString = dbConn.getAvgColourOfFeedByDbId(cursor.getString(cursor.getColumnIndex(DatabaseConnection.RSS_ITEM_SUBSCRIPTION_ID))); View viewColor = view.findViewById(R.id.color_line_feed); if(colorString != null) @@ -207,58 +215,80 @@ public class NewsListCursorAdapter extends CursorAdapter { public void setSimpleLayout(View view, Cursor cursor) { - TextView textViewSummary = (TextView) view.findViewById(R.id.summary); - textViewSummary.setText(Html.fromHtml(cursor.getString(cursor.getColumnIndex(DatabaseConnection.RSS_ITEM_TITLE))).toString()); + SimpleLayout simpleLayout = new SimpleLayout(view); + + simpleLayout.textViewSummary.setText(Html.fromHtml(cursor.getString(cursor.getColumnIndex(DatabaseConnection.RSS_ITEM_TITLE))).toString()); - TextView textViewItemDate = (TextView) view.findViewById(R.id.tv_item_date); long pubDate = cursor.getLong(cursor.getColumnIndex(DatabaseConnection.RSS_ITEM_PUBDATE)); - //textViewItemDate.setText(simpleDateFormat.format(new Date(pubDate))); String dateString = (String) DateUtils.getRelativeTimeSpanString(pubDate); - textViewItemDate.setText(dateString); - - TextView textViewTitle = (TextView) view.findViewById(R.id.tv_subscription); - textViewTitle.setText(dbConn.getTitleOfSubscriptionByRowID(cursor.getString(cursor.getColumnIndex(DatabaseConnection.RSS_ITEM_SUBSCRIPTION_ID)))); - textViewSummary.setTag(cursor.getString(0)); + simpleLayout.textViewItemDate.setText(dateString); + + simpleLayout.textViewTitle.setText(dbConn.getTitleOfSubscriptionByRowID(cursor.getString(cursor.getColumnIndex(DatabaseConnection.RSS_ITEM_SUBSCRIPTION_ID)))); + simpleLayout.textViewSummary.setTag(cursor.getString(0)); } - + + static class SimpleLayout { + @InjectView(R.id.summary) TextView textViewSummary; + @InjectView(R.id.tv_item_date) TextView textViewItemDate; + @InjectView(R.id.tv_subscription) TextView textViewTitle; + + SimpleLayout(View view) { + ButterKnife.inject(this, view); + } + } + public void setExtendedLayout(View view, Cursor cursor) { - TextView textViewSummary = (TextView) view.findViewById(R.id.summary); - textViewSummary.setText(Html.fromHtml(cursor.getString(cursor.getColumnIndex(DatabaseConnection.RSS_ITEM_TITLE))).toString()); + ExtendedLayout extendedLayout = new ExtendedLayout(view); + + extendedLayout.textViewSummary.setText(Html.fromHtml(cursor.getString(cursor.getColumnIndex(DatabaseConnection.RSS_ITEM_TITLE))).toString()); - TextView textViewItemDate = (TextView) view.findViewById(R.id.tv_item_date); long pubDate = cursor.getLong(cursor.getColumnIndex(DatabaseConnection.RSS_ITEM_PUBDATE)); //textViewItemDate.setText(simpleDateFormat.format(new Date(pubDate))); String dateString = (String) DateUtils.getRelativeTimeSpanString(pubDate); - textViewItemDate.setText(dateString); + extendedLayout.textViewItemDate.setText(dateString); - TextView textViewItemBody = (TextView) view.findViewById(R.id.body); - String body = cursor.getString(cursor.getColumnIndex(DatabaseConnection.RSS_ITEM_BODY)); - textViewItemBody.setText(getBodyText(body)); + extendedLayout.textViewItemBody.setVisibility(View.INVISIBLE); + String idItemDb = cursor.getString(0); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) + // Execute in parallel + new DescriptionTextLoaderTask(extendedLayout.textViewItemBody, idItemDb).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ((Void) null)); + else + new DescriptionTextLoaderTask(extendedLayout.textViewItemBody, idItemDb).execute((Void) null); - TextView textViewTitle = (TextView) view.findViewById(R.id.tv_subscription); - textViewTitle.setText(dbConn.getTitleOfSubscriptionByRowID(cursor.getString(cursor.getColumnIndex(DatabaseConnection.RSS_ITEM_SUBSCRIPTION_ID)))); - textViewSummary.setTag(cursor.getString(0)); + extendedLayout.textViewTitle.setText(dbConn.getTitleOfSubscriptionByRowID(cursor.getString(cursor.getColumnIndex(DatabaseConnection.RSS_ITEM_SUBSCRIPTION_ID)))); + extendedLayout.textViewSummary.setTag(cursor.getString(0)); } - + + static class ExtendedLayout { + @InjectView(R.id.summary) TextView textViewSummary; + @InjectView(R.id.tv_item_date) TextView textViewItemDate; + @InjectView(R.id.body) TextView textViewItemBody; + @InjectView(R.id.tv_subscription) TextView textViewTitle; + + ExtendedLayout(View view) { + ButterKnife.inject(this, view); + } + } + @TargetApi(Build.VERSION_CODES.HONEYCOMB) public void setExtendedLayoutWebView(View view, Cursor cursor) - { + { WebView webViewContent = (WebView) view.findViewById(R.id.webView_body); webViewContent.setClickable(false); webViewContent.setFocusable(false); //if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) // webViewContent.setLayerType(View.LAYER_TYPE_SOFTWARE, null); - + webViewContent.loadDataWithBaseURL("", NewsDetailFragment.getHtmlPage(mContext, dbConn , cursor.getInt(0)), "text/html", "UTF-8", ""); } - + public void CloseDatabaseConnection() { if(dbConn != null) dbConn.closeDatabase(); } - + private void UpdateIsReadCheckBox(View view, String idItemDb) { LinearLayout lLayout = (LinearLayout) view.getParent(); @@ -270,13 +300,13 @@ public class NewsListCursorAdapter extends CursorAdapter { } cbRead.setChecked(isChecked); } - + public static void ChangeCheckBoxState(RobotoCheckBox cb, boolean state, Context context) { if(cb != null && cb.isChecked() != state) cb.setChecked(state); } - + public static void UpdateListCursor(Context context) { SherlockFragmentActivity sfa = (SherlockFragmentActivity) context; @@ -284,7 +314,7 @@ public class NewsListCursorAdapter extends CursorAdapter { if(sfa instanceof NewsReaderListActivity && ((NewsReaderListActivity) sfa).isSlidingPaneOpen()) ((NewsReaderListActivity) sfa).updateAdapter(); } - + private String getBodyText(String body) { @@ -292,13 +322,13 @@ public class NewsListCursorAdapter extends CursorAdapter { // body = body.substring(0, LengthBody); body = body.replaceAll("]*>", ""); - body = body.replaceAll("]*>", ""); + body = body.replaceAll("]*>", ""); SpannableString bodyStringSpannable = new SpannableString(Html.fromHtml(body)); bodyStringSpannable.setSpan(bodyForegroundColor, 0, bodyStringSpannable.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); String bodyString = bodyStringSpannable.toString().trim(); - + if(bodyString.length() > LengthBody) bodyString = bodyString.substring(0, LengthBody); @@ -309,9 +339,9 @@ public class NewsListCursorAdapter extends CursorAdapter { public View newView(Context cont, Cursor cursor, ViewGroup parent) { // when the view will be created for first time, // we need to tell the adapters, how each item will look - LayoutInflater inflater = LayoutInflater.from(parent.getContext()); + LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View retView = null; - + switch (selectedDesign) { case 0: retView = inflater.inflate(R.layout.subscription_detail_list_item_simple, parent, false); @@ -321,13 +351,85 @@ public class NewsListCursorAdapter extends CursorAdapter { break; case 2: retView = inflater.inflate(R.layout.subscription_detail_list_item_extended_webview, parent, false); - break; + break; } - - + + if(retView != null) retView.setTag(cursor.getString(0)); - + return retView; } + + + + + + + + + + + class DescriptionTextLoaderTask extends AsyncTask { + private String idItemDb; + private final WeakReference textViewWeakReference; + + public DescriptionTextLoaderTask(TextView textView, String idItemDb) { + textViewWeakReference = new WeakReference(textView); + this.idItemDb = idItemDb; + } + + @Override + // Actual download method, run in the task thread + protected String doInBackground(Void... params) { + + DatabaseConnection dbConn = new DatabaseConnection(mContext); + + Cursor cursor = dbConn.getItemByDbID(idItemDb); + cursor.moveToFirst(); + String body = cursor.getString(cursor.getColumnIndex(DatabaseConnection.RSS_ITEM_BODY)); + String result = getBodyText(body); + cursor.close(); + + return result; + } + + @Override + // Once the image is downloaded, associates it to the imageView + protected void onPostExecute(String text) { + if (isCancelled()) { + text = null; + } + + if (textViewWeakReference != null) { + TextView textView = textViewWeakReference.get(); + if (textView != null) { + textView.setText(text); + + fadeInTextView(textView); + } + } + } + + + + private void fadeInTextView(final TextView textView) + { + Animation fadeOut = new AlphaAnimation(0, 1); + fadeOut.setInterpolator(new AccelerateInterpolator()); + fadeOut.setDuration(300); + + fadeOut.setAnimationListener(new Animation.AnimationListener() + { + public void onAnimationEnd(Animation animation) + { + textView.setVisibility(View.VISIBLE); + } + public void onAnimationRepeat(Animation animation) {} + public void onAnimationStart(Animation animation) {} + }); + + textView.startAnimation(fadeOut); + } + } } diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnection.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnection.java index 3401b357..809589f1 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnection.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnection.java @@ -52,7 +52,7 @@ public class DatabaseConnection { } public SparseArray getUnreadItemCountForFeed() { - String buildSQL = "SELECT " + RSS_ITEM_SUBSCRIPTION_ID + ", COUNT(" + RSS_ITEM_RSSITEM_ID + ")" + + String buildSQL = "SELECT " + RSS_ITEM_SUBSCRIPTION_ID + ", COUNT(" + RSS_ITEM_RSSITEM_ID + ")" + // rowid as _id, " FROM " + RSS_ITEM_TABLE + " GROUP BY " + RSS_ITEM_SUBSCRIPTION_ID; @@ -330,7 +330,7 @@ public class DatabaseConnection { public long getLowestItemIdStarred() { - String buildSQL = "SELECT MIN(" + RSS_ITEM_RSSITEM_ID + ") FROM " + RSS_ITEM_TABLE + " WHERE " + RSS_ITEM_STARRED_TEMP + " == 1"; + String buildSQL = "SELECT MIN(" + RSS_ITEM_RSSITEM_ID + ") FROM " + RSS_ITEM_TABLE + " WHERE " + RSS_ITEM_STARRED_TEMP + " = 1"; return getLongValueBySQL(buildSQL); } @@ -351,6 +351,24 @@ public class DatabaseConnection { return database.delete(RSS_ITEM_TABLE, "rowid < ?", new String[] { id_db }); } + public void removeXLatestItems(int limit, String execludeFeed) { + String sql = "DELETE FROM " + RSS_ITEM_TABLE + " WHERE rowid IN (SELECT rowid FROM " + RSS_ITEM_TABLE + " WHERE " + RSS_ITEM_READ + " != 0 " + + " AND " + RSS_ITEM_READ_TEMP + " != 0 XX ORDER BY " + RSS_ITEM_PUBDATE + " desc LIMIT " + limit + ")"; + + if(execludeFeed != null) + sql = sql.replace("XX", "AND " + RSS_ITEM_SUBSCRIPTION_ID +" != " + execludeFeed); + else + sql = sql.replace("XX", ""); + + database.execSQL(sql); + } + + public void removeReadItems(int limit) { + String sql = "DELETE FROM " + RSS_ITEM_TABLE + " WHERE rowid IN (SELECT rowid FROM " + RSS_ITEM_TABLE + " WHERE " + RSS_ITEM_READ_TEMP + " = 1 " + + " AND " + RSS_ITEM_READ + " = 1 ORDER BY " + RSS_ITEM_PUBDATE + " desc LIMIT " + limit + ")"; + database.execSQL(sql); + } + /* public Cursor getAllData(String TABLE_NAME) { String buildSQL = "SELECT rowid as _id, * FROM " + TABLE_NAME; @@ -429,6 +447,14 @@ public class DatabaseConnection { return database.rawQuery(buildSQL, null); } + public Cursor getItemByDbID(String ID_ITEM_DB) {//Feeds + String buildSQL = "SELECT rowid as _id, * FROM " + RSS_ITEM_TABLE + " WHERE rowid = '" + ID_ITEM_DB + "'"; + + if(DATABASE_DEBUG_MODE) + Log.d("DB_HELPER", "getSubSubscriptionsByID SQL: " + buildSQL); + return database.rawQuery(buildSQL, null); + } + public Cursor getFeedByDbID(String ID_FEED_DB) {//Feeds String buildSQL = "SELECT rowid as _id, * FROM " + SUBSCRIPTION_TABLE + " WHERE rowid = '" + ID_FEED_DB + "'"; diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FavIconHandler.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FavIconHandler.java index 442e1cde..b7d992e7 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FavIconHandler.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FavIconHandler.java @@ -43,20 +43,20 @@ public class FavIconHandler { public static Drawable GetFavIconFromCache(String URL_TO_PAGE, Context context, String feedID) { try - { - File favIconFile = ImageHandler.getFullPathOfCacheFile(URL_TO_PAGE, ImageHandler.getPathFavIcons(context)); + { + File favIconFile = ImageHandler.getFullPathOfCacheFile(URL_TO_PAGE, ImageHandler.getPathFavIcons(context)); if(favIconFile.isFile() && favIconFile.length() > 0) { /* InputStream fs = new FileInputStream(favIconFile); - BufferedInputStream is = new BufferedInputStream(fs, 32*1024); + BufferedInputStream is = new BufferedInputStream(fs, 32*1024); Bitmap bitmap = GetScaledImage(is, 50, 50); if(bitmap != null) return new BitmapDrawable(context.getResources(), bitmap); else return null; */ - + if(feedID != null) { DatabaseConnection dbConn = new DatabaseConnection(context); try { @@ -69,7 +69,7 @@ public class FavIconHandler { dbConn.closeDatabase(); } } - + return Drawable.createFromPath(favIconFile.getPath()); } } @@ -79,16 +79,16 @@ public class FavIconHandler { } return null; } - + public static int getResourceIdForRightDefaultFeedIcon(Context context) { if(ThemeChooser.isDarkTheme(context)) return R.drawable.default_feed_icon_light; else return R.drawable.default_feed_icon_dark; - + } - + /* private static Bitmap GetScaledImage(BufferedInputStream is, int minimumDesiredBitmapWidth, int minimumDesiredBitmapHeight) { @@ -110,7 +110,7 @@ public class FavIconHandler { // inSampleSize prefers multiples of 2, but we prefer to prioritize memory savings decodeBitmapOptions.inSampleSize= Math.max(1,Math.min(originalWidth / minimumDesiredBitmapWidth, originalHeight / minimumDesiredBitmapHeight)); } - + return BitmapFactory.decodeStream(is,null,decodeBitmapOptions); } catch( IOException e ) { @@ -121,16 +121,50 @@ public class FavIconHandler { } catch( IOException ignored ) {} } }*/ - - + + static SparseArray imageViewReferences = new SparseArray(); String feedID; - + + + static SparseArray favIconToFeedId = new SparseArray(); + public static void PreCacheFavIcon(String WEB_URL_TO_FILE, Context context, String feedID) { + + FavIconCache favIconCache = new FavIconCache(); + favIconCache.context = context; + favIconCache.WEB_URL_TO_FILE = WEB_URL_TO_FILE; + + int key = Integer.parseInt(feedID); + favIconToFeedId.put(key, favIconCache); + GetImageAsyncTask giAsync = new GetImageAsyncTask(WEB_URL_TO_FILE, favIconDownloadFinished, key, ImageHandler.getPathFavIcons(context), context, null); + giAsync.scaleImage = true; + giAsync.dstHeight = 2*32; + giAsync.dstWidth = 2*32; + giAsync.feedID = feedID; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) + // Execute in parallel + giAsync.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ((Void)null)); + else + giAsync.execute((Void)null); + } + + static ImageDownloadFinished favIconDownloadFinished = new ImageDownloadFinished() { + + @Override + public void DownloadFinished(int AsynkTaskId, String fileCachePath, BitmapDrawableLruCache lruCache) { + FavIconCache favIconCache = favIconToFeedId.get(AsynkTaskId); + FavIconHandler.GetFavIconFromCache(favIconCache.WEB_URL_TO_FILE, favIconCache.context, String.valueOf(AsynkTaskId)); + imageViewReferences.remove(AsynkTaskId); + } + }; + + @TargetApi(Build.VERSION_CODES.HONEYCOMB) public void GetImageAsync(ImageView imageView, String WEB_URL_TO_FILE, Context context, String feedID, BitmapDrawableLruCache lruCache) - { + { this.feedID = feedID; - + boolean setImageAlready = false; if(lruCache != null) { if(lruCache.get(feedID) != null) { @@ -146,13 +180,13 @@ public class FavIconHandler { favIconCache.context = context; favIconCache.WEB_URL_TO_FILE = WEB_URL_TO_FILE; favIconCache.imageViewReference = imageViewReference; - + int key = 0; if(imageViewReferences.size() > 0) key = imageViewReferences.keyAt(imageViewReferences.size() -1) + 1; imageViewReferences.append(key, favIconCache); - - + + imageView.setImageDrawable(null); GetImageAsyncTask giAsync = new GetImageAsyncTask(WEB_URL_TO_FILE, imgDownloadFinished, key, ImageHandler.getPathFavIcons(context), context/*, imageView*/, lruCache); giAsync.scaleImage = true; @@ -168,30 +202,30 @@ public class FavIconHandler { giAsync.execute((Void)null); } } - + ImageDownloadFinished imgDownloadFinished = new ImageDownloadFinished() { @Override public void DownloadFinished(int AsynkTaskId, String fileCachePath, BitmapDrawableLruCache lruCache) { - //WeakReference imageViewRef = imageViewReferences.get(AsynkTaskId); + //WeakReference imageViewRef = imageViewReferences.get(AsynkTaskId); FavIconCache favIconCache = imageViewReferences.get(AsynkTaskId); WeakReference imageViewRef = favIconCache.imageViewReference; - + if(imageViewRef != null) - { + { ImageView imageView = imageViewRef.get(); if (imageView != null) { BitmapDrawable bd = (BitmapDrawable) FavIconHandler.GetFavIconFromCache(favIconCache.WEB_URL_TO_FILE, favIconCache.context, feedID); - if(lruCache != null && feedID != null && bd != null) + if(lruCache != null && feedID != null && bd != null) lruCache.put(feedID, bd); imageView.setImageDrawable(bd); } } - - imageViewReferences.remove(AsynkTaskId); + + imageViewReferences.remove(AsynkTaskId); } }; - + static class FavIconCache { public WeakReference imageViewReference; diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ImageHandler.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ImageHandler.java index 8ceaf949..9db60da0 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ImageHandler.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ImageHandler.java @@ -39,9 +39,9 @@ import java.util.regex.Pattern; public class ImageHandler { //private static final String TAG = "DownloadImagesFromWeb"; - - - + + + public static Drawable LoadImageFromWebOperations(String url) { try { InputStream is = (InputStream) new URL(url).getContent(); @@ -52,19 +52,19 @@ public class ImageHandler { return null; } } - - - - + + + + public static List getFilesFromDir(File dir) { List files = new ArrayList(); if(dir.isDirectory()) - for (File file : dir.listFiles()) + for (File file : dir.listFiles()) if (file.isFile()) files.add(file); return files; } - + public static long getFolderSize(File dir) { long size = 0; if(dir.isDirectory()) @@ -79,18 +79,26 @@ public class ImageHandler { } return size; } - + + public static File getFullPathOfCacheFileSafe(String WEB_URL_TO_FILE, String rootPath) { + try { + return getFullPathOfCacheFile(WEB_URL_TO_FILE, rootPath); + } catch (Exception ex) { + return null; + } + } + public static File getFullPathOfCacheFile(String WEB_URL_TO_FILE, String rootPath) throws Exception { URL url = new URL(WEB_URL_TO_FILE.trim()); - + MessageDigest m = MessageDigest.getInstance("MD5"); m.reset(); m.update(url.toString().getBytes()); byte[] digest = m.digest(); BigInteger bigInt = new BigInteger(1,digest); String hashtext = bigInt.toString(16); - + String fileEnding = ""; try { @@ -102,22 +110,22 @@ public class ImageHandler { fileEnding = ".png"; //ex.printStackTrace(); } - + return new File(rootPath + "/" + hashtext + fileEnding); } - - - + + + public static String getPathFavIcons(Context context) { return getPath(context) + "/favIcons"; } - + public static String getPathImageCache(Context context) { return getPath(context) + "/imgCache"; } - + public static String getPath(Context context) { String url; Boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); @@ -132,11 +140,11 @@ public class ImageHandler { } else url = context.getCacheDir().getAbsolutePath(); - + return url; } - - + + public static List getImageLinksFromText(String text) { List links = new ArrayList(); @@ -148,16 +156,16 @@ public class ImageHandler { //System.out.print("Start index: " + matcher.start()); //System.out.print(" End index: " + matcher.end() + " "); //System.out.println(matcher.group()); - + Matcher matcherSrcLink = patternSrcLink.matcher(matcher.group()); if(matcherSrcLink.find()) { - links.add(matcherSrcLink.group(1)); + links.add(matcherSrcLink.group(1)); } } return links; } - + public static boolean clearCache(Context context) { String path = getPath(context); @@ -180,7 +188,7 @@ public class ImageHandler { ex.printStackTrace(); } } - + // Deletes all files and subdirectories under dir. // Returns true if all deletions were successful. // If a deletion fails, the method stops attempting to delete and returns @@ -199,11 +207,11 @@ public class ImageHandler { // The directory is now empty so delete it return dir.delete(); } - - - + + + /* public static Bitmap loadBitmap(String url) { diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/DownloadItemsToCache.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/DownloadItemsToCache.java index 7f7d840d..2540a887 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/DownloadItemsToCache.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/DownloadItemsToCache.java @@ -26,7 +26,6 @@ import android.os.AsyncTask; import android.os.Build; import android.util.SparseArray; -import de.luhmer.owncloudnewsreader.async_tasks.FillTextForTextViewAsyncTask; import de.luhmer.owncloudnewsreader.async_tasks.GetImageAsyncTask; import de.luhmer.owncloudnewsreader.helper.BitmapDrawableLruCache; import de.luhmer.owncloudnewsreader.helper.ImageDownloadFinished; @@ -35,32 +34,32 @@ import de.luhmer.owncloudnewsreader.helper.ImageHandler; public class DownloadItemsToCache { SparseArray URLs; Context context; - + public DownloadItemsToCache(Context context) { URLs = new SparseArray(); this.context = context; } - + public void StartDownloadOfImage(String URL_TO_IMAGE) { int key = 0; if(URLs.size() > 0) key = URLs.keyAt(URLs.size() -1) + 1; URLs.append(key, URL_TO_IMAGE); - + GetImageAsyncTask getImageAsync = new GetImageAsyncTask(URL_TO_IMAGE, imgDownloadFinished, key, ImageHandler.getPathImageCache(context), context, null); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) getImageAsync.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ((Void) null));// Execute in parallel else getImageAsync.execute((Void)null); - } - + } + ImageDownloadFinished imgDownloadFinished = new ImageDownloadFinished() { @Override public void DownloadFinished(int AsynkTaskId, String fileCachePath, BitmapDrawableLruCache lruCache) { - - } + + } }; } diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/DownloadImagesService.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/DownloadImagesService.java index d9222feb..492cef8d 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/DownloadImagesService.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/DownloadImagesService.java @@ -31,6 +31,7 @@ import android.content.SharedPreferences; import android.database.Cursor; import android.preference.PreferenceManager; import android.support.v4.app.NotificationCompat; +import android.util.SparseArray; import java.io.File; import java.util.ArrayList; @@ -47,31 +48,33 @@ import de.luhmer.owncloudnewsreader.SettingsActivity; import de.luhmer.owncloudnewsreader.async_tasks.GetImageAsyncTask; import de.luhmer.owncloudnewsreader.database.DatabaseConnection; import de.luhmer.owncloudnewsreader.helper.BitmapDrawableLruCache; +import de.luhmer.owncloudnewsreader.helper.FavIconHandler; import de.luhmer.owncloudnewsreader.helper.ImageDownloadFinished; import de.luhmer.owncloudnewsreader.helper.ImageHandler; public class DownloadImagesService extends IntentService { public static final String LAST_ITEM_ID = "LAST_ITEM_ID"; + public static final String DOWNLOAD_FAVICONS_EXCLUSIVE = "DOWNLOAD_FAVICONS_EXCLUSIVE"; private static Random random; - + private int NOTIFICATION_ID = 1; private NotificationManager notificationManager; private NotificationCompat.Builder NotificationDownloadImages; private int count; private int maxCount; //private int total_size = 0; - + public DownloadImagesService() { super(null); initService(); } - + public DownloadImagesService(String name) { super(name); initService(); } - + private void initService() { count = 0; @@ -100,50 +103,70 @@ public class DownloadImagesService extends IntentService { @Override protected void onHandleIntent(Intent intent) { - String lastId = String.valueOf(intent.getLongExtra(LAST_ITEM_ID, 0)); - DatabaseConnection dbConn = new DatabaseConnection(this); - Cursor cursor = dbConn.getAllItemsWithIdHigher(lastId); - List links = new ArrayList(); - try - { - if(cursor != null) - { - while(cursor.moveToNext()) - { - String body = cursor.getString(cursor.getColumnIndex(DatabaseConnection.RSS_ITEM_BODY)); - links.addAll(ImageHandler.getImageLinksFromText(body)); - } - } - } catch(Exception ex) { - ex.printStackTrace(); - } finally { - cursor.close(); - dbConn.closeDatabase(); - } - maxCount = links.size(); - - Intent intentNewsReader = new Intent(this, NewsReaderListActivity.class); - PendingIntent pIntent = PendingIntent.getActivity(this, 0, intentNewsReader, 0); - notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); - NotificationDownloadImages = new NotificationCompat.Builder(this) - .setContentTitle("ownCloud News Reader") - .setContentText("Downloading Images for offline usage") - .setSmallIcon(R.drawable.ic_launcher) - .setContentIntent(pIntent); - - Notification notify = NotificationDownloadImages.build(); - - //Hide the notification after its selected - notify.flags |= Notification.FLAG_AUTO_CANCEL; - //notify.flags |= Notification.FLAG_NO_CLEAR; - - if(maxCount > 0) - notificationManager.notify(NOTIFICATION_ID, notify); - - for(String link : links) - new GetImageAsyncTask(link, imgDownloadFinished, 999, ImageHandler.getPathImageCache(this), this, null).execute(); + boolean downloadFavIconsExclusive = intent.getBooleanExtra(DOWNLOAD_FAVICONS_EXCLUSIVE, false); + + DatabaseConnection dbConn = new DatabaseConnection(this); + Notification notify = BuildNotification(); + SparseArray linksFavIcons = dbConn.getUrlsToFavIcons(); + + if(linksFavIcons.size() > 0) + notificationManager.notify(NOTIFICATION_ID, notify); + + for(int i = 0; i < linksFavIcons.size(); i++) { + int key = linksFavIcons.keyAt(i); + String link = linksFavIcons.get(i); + FavIconHandler.PreCacheFavIcon(link, this, String.valueOf(key)); + } + + + + + if(!downloadFavIconsExclusive) { + String lastId = String.valueOf(intent.getLongExtra(LAST_ITEM_ID, 0)); + Cursor cursor = dbConn.getAllItemsWithIdHigher(lastId); + List links = new ArrayList(); + try { + if (cursor != null) { + while (cursor.moveToNext()) { + String body = cursor.getString(cursor.getColumnIndex(DatabaseConnection.RSS_ITEM_BODY)); + links.addAll(ImageHandler.getImageLinksFromText(body)); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } finally { + cursor.close(); + dbConn.closeDatabase(); + } + maxCount = links.size(); + + if (maxCount > 0) + notificationManager.notify(NOTIFICATION_ID, notify); + + for (String link : links) + new GetImageAsyncTask(link, imgDownloadFinished, 999, ImageHandler.getPathImageCache(this), this, null).execute(); + } } + private Notification BuildNotification() { + Intent intentNewsReader = new Intent(this, NewsReaderListActivity.class); + PendingIntent pIntent = PendingIntent.getActivity(this, 0, intentNewsReader, 0); + notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationDownloadImages = new NotificationCompat.Builder(this) + .setContentTitle("ownCloud News Reader") + .setContentText("Downloading Images for offline usage") + .setSmallIcon(R.drawable.ic_launcher) + .setContentIntent(pIntent); + + Notification notify = NotificationDownloadImages.build(); + + //Hide the notification after its selected + notify.flags |= Notification.FLAG_AUTO_CANCEL; + //notify.flags |= Notification.FLAG_NO_CLEAR; + + return notify; + } + private void RemoveOldImages(Context context) { HashMap files; long size = ImageHandler.getFolderSize(new File(ImageHandler.getPath(context))); @@ -199,9 +222,9 @@ public class DownloadImagesService extends IntentService { } return sortedMap; } - + ImageDownloadFinished imgDownloadFinished = new ImageDownloadFinished() { - + @Override public void DownloadFinished(int AsynkTaskId, String fileCachePath, BitmapDrawableLruCache lruCache) { @@ -222,7 +245,7 @@ public class DownloadImagesService extends IntentService { NotificationDownloadImages.setContentText("Downloading Images for offline usage - " + count + "/" + maxCount); // Displays the progress bar for the first time. notificationManager.notify(NOTIFICATION_ID, NotificationDownloadImages.build()); - + if(maxCount == count) { notificationManager.cancel(NOTIFICATION_ID); if(DownloadImagesService.this != null) diff --git a/News-Android-App/src/main/res/layout/subscription_detail_list_item_extended.xml b/News-Android-App/src/main/res/layout/subscription_detail_list_item_extended.xml index 2c165a90..3c9bb76b 100644 --- a/News-Android-App/src/main/res/layout/subscription_detail_list_item_extended.xml +++ b/News-Android-App/src/main/res/layout/subscription_detail_list_item_extended.xml @@ -6,22 +6,22 @@ - + - + - - + + - + - + - + - + - + - + - - + + - + + + + \ No newline at end of file diff --git a/News-Android-App/src/main/res/layout/subscription_detail_list_item_simple.xml b/News-Android-App/src/main/res/layout/subscription_detail_list_item_simple.xml index c0bd5372..e16a0232 100644 --- a/News-Android-App/src/main/res/layout/subscription_detail_list_item_simple.xml +++ b/News-Android-App/src/main/res/layout/subscription_detail_list_item_simple.xml @@ -3,27 +3,26 @@ - + android:layout_height="72dp" + android:orientation="horizontal" > + - + - - - - + - + - + - + - + - + - - + - - - - - - - - - + android:clickable="false" + android:focusable="false" /> + + + + + \ No newline at end of file diff --git a/News-Android-App/src/main/res/layout/subscription_list_item.xml b/News-Android-App/src/main/res/layout/subscription_list_item.xml index 6be3fcf1..8c818616 100644 --- a/News-Android-App/src/main/res/layout/subscription_list_item.xml +++ b/News-Android-App/src/main/res/layout/subscription_list_item.xml @@ -1,5 +1,5 @@ - - - + + - - + + - + \ No newline at end of file diff --git a/News-Android-App/src/main/res/values/colors.xml b/News-Android-App/src/main/res/values/colors.xml index 61984dda..ea8ed898 100644 --- a/News-Android-App/src/main/res/values/colors.xml +++ b/News-Android-App/src/main/res/values/colors.xml @@ -2,6 +2,8 @@ #383d43 - #F0F0F0 + #F0F0F0 #292929 + + #ff9e9e9e