From a1eaf5276ad4e4c1d01d4cf9ba846d9a56d3ca19 Mon Sep 17 00:00:00 2001 From: gumartinm Date: Sun, 17 Jun 2012 04:28:51 +0200 Subject: [PATCH] My first Android FragmentList. It looks like a nice implementation. --- Android/MobiAdsTabs/gen/de/android/mobiads/R.java | 26 +- .../MobiAdsTabs/res/layout/ads_entry_list_item.xml | 40 ++ Android/MobiAdsTabs/res/layout/mobiadslist.xml | 15 - .../res/layout/news_entry_list_item.xml | 40 -- Android/MobiAdsTabs/res/values/strings.xml | 1 + .../src/de/android/mobiads/FragmentStack.java | 75 ---- .../src/de/android/mobiads/MobiAdsPreferences.java | 6 +- .../de/android/mobiads/MobiAdsTabsActivity.java | 22 +- .../src/de/android/mobiads/list/MobiAdsList.java | 489 +++++++++++++++++++++ .../android/mobiads/list/MobiAdsListFragment.java | 191 -------- .../mobiads/list/MobiAdsNewAdsActivity.java | 2 +- 11 files changed, 557 insertions(+), 350 deletions(-) create mode 100644 Android/MobiAdsTabs/res/layout/ads_entry_list_item.xml delete mode 100644 Android/MobiAdsTabs/res/layout/mobiadslist.xml delete mode 100644 Android/MobiAdsTabs/res/layout/news_entry_list_item.xml delete mode 100644 Android/MobiAdsTabs/src/de/android/mobiads/FragmentStack.java create mode 100644 Android/MobiAdsTabs/src/de/android/mobiads/list/MobiAdsList.java delete mode 100644 Android/MobiAdsTabs/src/de/android/mobiads/list/MobiAdsListFragment.java diff --git a/Android/MobiAdsTabs/gen/de/android/mobiads/R.java b/Android/MobiAdsTabs/gen/de/android/mobiads/R.java index 02eb0bd..1deec00 100644 --- a/Android/MobiAdsTabs/gen/de/android/mobiads/R.java +++ b/Android/MobiAdsTabs/gen/de/android/mobiads/R.java @@ -15,23 +15,22 @@ public final class R { public static final int wheelnotification=0x7f020001; } public static final class id { - public static final int ads_entry_icon=0x7f070006; - public static final int ads_entry_text=0x7f070008; - public static final int ads_entry_title=0x7f070007; - public static final int frameLayout1=0x7f070000; - public static final int frameLayout2=0x7f070003; - public static final int list=0x7f070005; - public static final int login_button=0x7f070004; + public static final int ads_entry_icon=0x7f070000; + public static final int ads_entry_text=0x7f070002; + public static final int ads_entry_title=0x7f070001; + public static final int frameLayout1=0x7f070003; + public static final int frameLayout2=0x7f070006; + public static final int list=0x7f070008; + public static final int login_button=0x7f070007; public static final int menuadsremove=0x7f070009; - public static final int password=0x7f070002; - public static final int username=0x7f070001; + public static final int password=0x7f070005; + public static final int username=0x7f070004; } public static final class layout { - public static final int login=0x7f030000; - public static final int main=0x7f030001; - public static final int mobiadslist=0x7f030002; + public static final int ads_entry_list_item=0x7f030000; + public static final int login=0x7f030001; + public static final int main=0x7f030002; public static final int mobiadsnewadslist=0x7f030003; - public static final int news_entry_list_item=0x7f030004; } public static final class menu { public static final int menuads=0x7f060000; @@ -52,6 +51,7 @@ public final class R { public static final int desc=0x7f05001d; public static final int encoded_web_service=0x7f05001c; public static final int error_dialog_connection_error=0x7f050005; + public static final int error_dialog_no_local_ads=0x7f05001f; public static final int error_dialog_userpwd_error=0x7f050006; public static final int header_bar=0x7f050000; public static final int menuads_remove=0x7f05001e; diff --git a/Android/MobiAdsTabs/res/layout/ads_entry_list_item.xml b/Android/MobiAdsTabs/res/layout/ads_entry_list_item.xml new file mode 100644 index 0000000..13a01c3 --- /dev/null +++ b/Android/MobiAdsTabs/res/layout/ads_entry_list_item.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android/MobiAdsTabs/res/layout/mobiadslist.xml b/Android/MobiAdsTabs/res/layout/mobiadslist.xml deleted file mode 100644 index 2fb5935..0000000 --- a/Android/MobiAdsTabs/res/layout/mobiadslist.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/Android/MobiAdsTabs/res/layout/news_entry_list_item.xml b/Android/MobiAdsTabs/res/layout/news_entry_list_item.xml deleted file mode 100644 index 13a01c3..0000000 --- a/Android/MobiAdsTabs/res/layout/news_entry_list_item.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Android/MobiAdsTabs/res/values/strings.xml b/Android/MobiAdsTabs/res/values/strings.xml index d78b3e6..c1dd817 100644 --- a/Android/MobiAdsTabs/res/values/strings.xml +++ b/Android/MobiAdsTabs/res/values/strings.xml @@ -31,4 +31,5 @@ UTF-8 description Remove + You have no downloaded ads. \ No newline at end of file diff --git a/Android/MobiAdsTabs/src/de/android/mobiads/FragmentStack.java b/Android/MobiAdsTabs/src/de/android/mobiads/FragmentStack.java deleted file mode 100644 index 9e77f27..0000000 --- a/Android/MobiAdsTabs/src/de/android/mobiads/FragmentStack.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * 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 de.android.mobiads; - -import android.app.Activity; -import android.app.Fragment; -import android.app.FragmentTransaction; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.TextView; - -public class FragmentStack extends Activity { - - - public static class CountingFragment extends Fragment { - int mNum; - - /** - * Create a new instance of CountingFragment, providing "num" - * as an argument. - */ - static CountingFragment newInstance(int num) { - CountingFragment f = new CountingFragment(); - - // Supply num input as an argument. - Bundle args = new Bundle(); - args.putInt("num", num); - f.setArguments(args); - - return f; - } - - /** - * When creating, retrieve this instance's number from its arguments. - */ - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mNum = getArguments() != null ? getArguments().getInt("num") : 1; - } - - /** - * The Fragment's UI is just a simple text view showing its - * instance number. - */ -// @Override -// public View onCreateView(LayoutInflater inflater, ViewGroup container, -// Bundle savedInstanceState) { -// View v = inflater.inflate(R.layout.logintab, container, false); -// View tv = v.findViewById(R.id.text); -// ((TextView)tv).setText("Fragment #" + mNum); -// tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb)); -// return v; -// } - } - -} diff --git a/Android/MobiAdsTabs/src/de/android/mobiads/MobiAdsPreferences.java b/Android/MobiAdsTabs/src/de/android/mobiads/MobiAdsPreferences.java index 92ffd98..5033dfb 100644 --- a/Android/MobiAdsTabs/src/de/android/mobiads/MobiAdsPreferences.java +++ b/Android/MobiAdsTabs/src/de/android/mobiads/MobiAdsPreferences.java @@ -11,9 +11,9 @@ import android.preference.PreferenceFragment; public class MobiAdsPreferences extends PreferenceFragment { - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); // Load the preferences from an XML resource addPreferencesFromResource(R.xml.preferences); diff --git a/Android/MobiAdsTabs/src/de/android/mobiads/MobiAdsTabsActivity.java b/Android/MobiAdsTabs/src/de/android/mobiads/MobiAdsTabsActivity.java index 47e47b5..d40cdec 100644 --- a/Android/MobiAdsTabs/src/de/android/mobiads/MobiAdsTabsActivity.java +++ b/Android/MobiAdsTabs/src/de/android/mobiads/MobiAdsTabsActivity.java @@ -1,6 +1,6 @@ package de.android.mobiads; -import de.android.mobiads.list.MobiAdsListFragment; +import de.android.mobiads.list.MobiAdsList; import android.app.ActionBar; import android.app.Activity; import android.app.ActivityManager; @@ -16,7 +16,6 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; -import android.widget.Toast; public class MobiAdsTabsActivity extends Activity { @@ -31,19 +30,19 @@ public class MobiAdsTabsActivity extends Activity { bar.addTab(bar.newTab() .setText("Local Ads") - .setTabListener(new TabListener( - this, "localads", MobiAdsListFragment.class))); + .setTabListener(new TabListener( + this, "localads", MobiAdsList.MobiAdsListFragment.class))); if (Cookie.getCookie() != null || isMyServiceRunning()) { bar.addTab(bar.newTab() .setText("Control Panel") - .setTabListener(new TabListener( - this, "controlpanel", MobiAdsPreferences.class))); + .setTabListener(new TabListener( + this, "controlpanel", MobiAdsPreferences.class))); } bar.addTab(bar.newTab() .setText("Login") - .setTabListener(new Login())); + .setTabListener(new Login())); @@ -63,8 +62,8 @@ public class MobiAdsTabsActivity extends Activity { super.onResume(); if ((Cookie.getCookie() != null) && (getActionBar().getTabCount() == 2)) { getActionBar().addTab(getActionBar().newTab() - .setText("Control Panel") - .setTabListener(new TabListener( + .setText("Control Panel") + .setTabListener(new TabListener( this, "controlpanel", MobiAdsPreferences.class)), 1); } @@ -114,7 +113,7 @@ public class MobiAdsTabsActivity extends Activity { } public void onTabReselected(Tab tab, FragmentTransaction ft) { - Toast.makeText(mActivity, "Reselected!", Toast.LENGTH_SHORT).show(); + //Nothing to do here. } } @@ -134,8 +133,7 @@ public class MobiAdsTabsActivity extends Activity { @Override public void onTabUnselected(Tab tab, FragmentTransaction ft) { - // TODO Auto-generated method stub - + //Nothing to do here } @Override diff --git a/Android/MobiAdsTabs/src/de/android/mobiads/list/MobiAdsList.java b/Android/MobiAdsTabs/src/de/android/mobiads/list/MobiAdsList.java new file mode 100644 index 0000000..94daec8 --- /dev/null +++ b/Android/MobiAdsTabs/src/de/android/mobiads/list/MobiAdsList.java @@ -0,0 +1,489 @@ +package de.android.mobiads.list; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import android.app.Activity; +import android.app.ActivityManager; +import android.app.ActivityManager.RunningServiceInfo; +import android.app.ListFragment; +import android.app.LoaderManager; +import android.app.Notification; +import android.app.NotificationManager; +import android.content.AsyncTaskLoader; +import android.content.ContentValues; +import android.content.Context; +import android.content.Intent; +import android.content.Loader; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.net.Uri; +import android.os.Bundle; +import android.text.TextUtils; +import android.util.Log; +import android.view.ContextMenu; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.ContextMenu.ContextMenuInfo; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.SearchView; +import android.widget.AdapterView.AdapterContextMenuInfo; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.SearchView.OnQueryTextListener; +import android.widget.TextView; +import de.android.mobiads.MobiAdsService; +import de.android.mobiads.R; +import de.android.mobiads.provider.Indexer; + +public class MobiAdsList extends Activity { + + /** + * A custom Loader that loads all of the installed applications. + */ + public static class AdsListLoader extends AsyncTaskLoader> { + private static final String TAG = "AdsListLoader"; + List mApps; + + public AdsListLoader(Context context) { + super(context); + } + + /** + * This is where the bulk of our work is done. This function is + * called in a background thread and should generate a new set of + * data to be published by the loader. + */ + @Override + public List loadInBackground() { + // Create corresponding array of entries and load their labels. + List entries = getAdsEntries(); + + return entries; + } + + private List getAdsEntries() { + final List entries = new ArrayList(); + final Uri uri = Uri.parse("content://" + "de.android.mobiads.provider" + "/" + "indexer"); + final ContentValues values = new ContentValues(); + + Cursor cursor = getContext().getContentResolver().query(uri, null, null, null, null); + try { + if (cursor.moveToFirst()) { + do { + values.clear(); + Bitmap bitMap = null; + FileInputStream file = null; + try { + file = getContext().openFileInput(cursor.getString(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_PATH))); + bitMap = BitmapFactory.decodeStream(file); + } catch (FileNotFoundException e) { + //Giving more chances to other ads + continue; + } catch (IllegalArgumentException e) { + //Giving more chances to other ads + continue; + } + finally { + if (file != null) { + try { + file.close(); + } catch (IOException e) { + Log.w(TAG, "Error while closing image file."); + } + } + } + entries.add(new AdsEntry(cursor.getString(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_AD_NAME)), + cursor.getString(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_TEXT)), bitMap, + cursor.getInt(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_ID_AD)), + cursor.getString(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_URL)))); + if (cursor.getInt(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_IS_READ)) == 0) + { + values.put(Indexer.Index.COLUMN_NAME_IS_READ, new Integer(1)); + Uri uriUpdate = Uri.parse("content://" + "de.android.mobiads.provider" + "/" + "indexer/" + + cursor.getString(cursor.getColumnIndexOrThrow(Indexer.Index._ID))); + getContext().getContentResolver().update(uriUpdate, values, null, null); + } + }while (cursor.moveToNext()); + } + }finally { + cursor.close(); + } + + return entries; + } + + /** + * Called when there is new data to deliver to the client. The + * super class will take care of delivering it; the implementation + * here just adds a little more logic. + */ + @Override + public void deliverResult(List apps) { + mApps = apps; + + if (isStarted()) { + // If the Loader is currently started, we can immediately + // deliver its results. + super.deliverResult(apps); + } + } + + /** + * Handles a request to start the Loader. + */ + @Override + protected void onStartLoading() { + if (mApps != null) { + // If we currently have a result available, deliver it + // immediately. + deliverResult(mApps); + } + + if (takeContentChanged() || mApps == null) { + // If the data has changed since the last time it was loaded + // or is not currently available, start a load. + forceLoad(); + } + } + + /** + * Handles a request to cancel a load. + */ + @Override + public void onCanceled(List apps) { + super.onCanceled(apps); + + // At this point we can release the resources associated with 'apps' + // if needed. + } + + /** + * Handles a request to completely reset the Loader. + */ + @Override + protected void onReset() { + super.onReset(); + + // Ensure the loader is stopped + onStopLoading(); + + // At this point we can release the resources associated with 'apps' + // if needed. + if (mApps != null) { + mApps = null; + } + } + } + + public static class MobiAdsListFragment extends ListFragment implements OnQueryTextListener, + LoaderManager.LoaderCallbacks> { + AdsEntryAdapter mAdapter; + // If non-null, this is the current filter the user has provided. + String mCurFilter; + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + ListView listView = getListView(); + + getActivity().registerForContextMenu(listView); + + listView.setOnItemClickListener(new OnItemClickListener() { + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Uri uri = Uri.parse(mAdapter.getItem(position).getURL()); + startActivity(new Intent(Intent.ACTION_VIEW, uri)); + } + }); + + setEmptyText("No downloaded Ads."); + + // We have a menu item to show in action bar. + setHasOptionsMenu(true); + + + mAdapter = new AdsEntryAdapter(getActivity(), R.layout.ads_entry_list_item); + + setListAdapter(mAdapter); + // Start out with a progress indicator. + setListShown(false); + + // Prepare the loader. Either re-connect with an existing one, + // or start a new one. + getLoaderManager().initLoader(0, null, this); + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + MenuInflater inflater = getActivity().getMenuInflater(); + inflater.inflate(R.menu.menuads, menu); + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); + switch (item.getItemId()) { + case R.id.menuadsremove: + removeAd(info.position); + return true; + default: + return super.onContextItemSelected(item); + } + } + + private void removeAd(int position){ + AdsEntry entry = mAdapter.getItem(position); + int idAd = entry.getIdAd(); + Uri uriDelete = Uri.parse("content://" + "de.android.mobiads.provider" + "/" + "indexer" + "/idad/" + idAd); + + getActivity().getContentResolver().delete(uriDelete, null, null); + mAdapter.remove(entry); + mAdapter.notifyDataSetChanged(); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + // Place an action bar item for searching. + MenuItem item = menu.add("Search"); + item.setIcon(android.R.drawable.ic_menu_search); + item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + SearchView sv = new SearchView(getActivity()); + sv.setOnQueryTextListener(this); + item.setActionView(sv); + } + + @Override + public Loader> onCreateLoader(int id, Bundle args) { + // This is called when a new Loader needs to be created. This + // sample only has one Loader with no arguments, so it is simple. + return new AdsListLoader(getActivity()); + } + + @Override + public void onLoadFinished(Loader> loader, List data) { + mAdapter.setData(data); + + // The list should now be shown. + if (isResumed()) { + setListShown(true); + } else { + setListShownNoAnimation(true); + } + + if (isMyServiceRunning()) { + showNotification(0, 0, getText(R.string.remote_service_content_empty_notification)); + } + } + + @Override + public void onLoaderReset(Loader> loader) { + mAdapter.setData(null); + } + + @Override + public boolean onQueryTextSubmit(String query) { + // Don't care about this. + return true; + } + + @Override + public boolean onQueryTextChange(String newText) { + // Called when the action bar search text has changed. Update + // the search filter, and restart the loader to do a new query + // with this filter. + mCurFilter = !TextUtils.isEmpty(newText) ? newText : null; + getLoaderManager().restartLoader(0, null, this); + return true; + } + + private boolean isMyServiceRunning() { + ActivityManager manager = (ActivityManager) getActivity().getSystemService(Context.ACTIVITY_SERVICE); + for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { + if (MobiAdsService.class.getName().equals(service.service.getClassName())) { + return true; + } + } + return false; + } + + public void showNotification(final int level, final int noReadAds, CharSequence contentText) { + NotificationManager notificationManager = (NotificationManager)getActivity().getSystemService(Context.NOTIFICATION_SERVICE); + + // Set the icon, scrolling text and timestamp + Notification.Builder notificationBuilder = new Notification.Builder(getActivity().getApplicationContext()). + setSmallIcon(R.drawable.wheelnotification, level). + setTicker(getText(R.string.remote_service_started_notification)). + setWhen(System.currentTimeMillis()). + setContentText(contentText). + setContentTitle(getText(R.string.remote_service_title_notification)). + setNumber(noReadAds); + Notification notification = notificationBuilder.getNotification(); + notification.flags |= Notification.FLAG_NO_CLEAR; + + // Send the notification. + // We use a string id because it is a unique number. We use it later to cancel. + notificationManager.notify(R.string.remote_service_title_notification, notification); + } + } + + + + + public static class AdsEntryAdapter extends ArrayAdapter { + private final int adsItemLayoutResource; + + public AdsEntryAdapter(final Context context, final int adsItemLayoutResource) { + super(context, 0); + this.adsItemLayoutResource = adsItemLayoutResource; + } + + public void setData(List data) { + clear(); + if (data != null) { + addAll(data); + } + } + + /** + * Populate new items in the list. + */ + @Override + public View getView(final int position, final View convertView, final ViewGroup parent) { + + // We need to get the best view (re-used if possible) and then + // retrieve its corresponding ViewHolder, which optimizes lookup efficiency + final View view = getWorkingView(convertView); + final ViewHolder viewHolder = getViewHolder(view); + final AdsEntry entry = getItem(position); + + // Setting the text view + viewHolder.titleView.setText(entry.getTitle()); + + viewHolder.textView.setText(entry.getText()); + + // Setting image view + viewHolder.imageView.setImageBitmap(entry.getIcon()); + + return view; + } + + private View getWorkingView(final View convertView) { + // The workingView is basically just the convertView re-used if possible + // or inflated new if not possible + View workingView = null; + + if(null == convertView) { + final Context context = getContext(); + final LayoutInflater inflater = (LayoutInflater)context.getSystemService + (Context.LAYOUT_INFLATER_SERVICE); + + workingView = inflater.inflate(adsItemLayoutResource, null); + } else { + workingView = convertView; + } + + return workingView; + } + + private ViewHolder getViewHolder(final View workingView) { + // The viewHolder allows us to avoid re-looking up view references + // Since views are recycled, these references will never change + final Object tag = workingView.getTag(); + ViewHolder viewHolder = null; + + + if(null == tag || !(tag instanceof ViewHolder)) { + viewHolder = new ViewHolder(); + + viewHolder.titleView = (TextView) workingView.findViewById(R.id.ads_entry_title); + viewHolder.textView = (TextView) workingView.findViewById(R.id.ads_entry_text); + viewHolder.imageView = (ImageView) workingView.findViewById(R.id.ads_entry_icon); + + workingView.setTag(viewHolder); + + } else { + viewHolder = (ViewHolder) tag; + } + + return viewHolder; + } + + /** + * ViewHolder allows us to avoid re-looking up view references + * Since views are recycled, these references will never change + */ + private static class ViewHolder { + public TextView titleView; + public TextView textView; + public ImageView imageView; + } + } + + /** + * Encapsulates information about an ads entry + */ + public static class AdsEntry { + + private final String title; + private final String text; + private final Bitmap icon; + private final int idAd; + private final String URL; + + public AdsEntry(final String title, final String text, final Bitmap icon, final int idAd, final String URL) { + this.title = title; + this.text = text; + this.icon = icon; + this.idAd = idAd; + this.URL = URL; + } + + /** + * @return Title of ads entry + */ + public String getTitle() { + return title; + } + + /** + * @return Text of ads entry + */ + public String getText() { + return text; + } + + /** + * @return Icon of this ads entry + */ + public Bitmap getIcon() { + return icon; + } + + /** + * @return Ad unique identifier of this ads entry + */ + public int getIdAd() { + return idAd; + } + + /** + * @return URL matching this ad. + */ + public String getURL() { + return URL; + } + } +} diff --git a/Android/MobiAdsTabs/src/de/android/mobiads/list/MobiAdsListFragment.java b/Android/MobiAdsTabs/src/de/android/mobiads/list/MobiAdsListFragment.java deleted file mode 100644 index 751f85c..0000000 --- a/Android/MobiAdsTabs/src/de/android/mobiads/list/MobiAdsListFragment.java +++ /dev/null @@ -1,191 +0,0 @@ -package de.android.mobiads.list; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import android.app.ActivityManager; -import android.app.ActivityManager.RunningServiceInfo; -import android.app.Fragment; -import android.app.Notification; -import android.app.NotificationManager; -import android.content.ContentValues; -import android.content.Context; -import android.content.Intent; -import android.database.Cursor; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.net.Uri; -import android.os.Bundle; -import android.util.Log; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.LayoutInflater; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ListView; -import de.android.mobiads.MobiAdsService; -import de.android.mobiads.R; -import de.android.mobiads.provider.Indexer; - -public class MobiAdsListFragment extends Fragment { - private static final String TAG = "MobiAdsListFragment"; - private AdsEntryAdapter newsEntryAdapter; - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.mobiadslist, container, false); - - // Setup the list view - final ListView newsEntryListView = (ListView) v.findViewById(R.id.list); - newsEntryAdapter = new AdsEntryAdapter(getActivity(), R.layout.news_entry_list_item); - newsEntryListView.setAdapter(newsEntryAdapter); - - this.registerForContextMenu(newsEntryListView); - - newsEntryListView.setOnItemClickListener(new OnItemClickListener() { - - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - Uri uri = Uri.parse(newsEntryAdapter.getItem(position).getURL()); - startActivity(new Intent(Intent.ACTION_VIEW, uri)); - } - }); - - - return v; - } - - @Override - public void onResume() { - // Populate the list, through the adapter. Should I populate the whole list right now? I do not think so... - // Find out a way to populate this list just when it is required... :/ - // Using FragmentList? - for(final AdsEntry entry : getAdsEntries()) { - newsEntryAdapter.add(entry); - } - super.onResume(); - } - - private List getAdsEntries() { - final List entries = new ArrayList(); - final Uri uri = Uri.parse("content://" + "de.android.mobiads.provider" + "/" + "indexer"); - final ContentValues values = new ContentValues(); - - Cursor cursor = getActivity().getContentResolver().query(uri, null, null, null, null); - try { - if (cursor.moveToFirst()) { - do { - values.clear(); - Bitmap bitMap = null; - FileInputStream file = null; - try { - file = getActivity().openFileInput(cursor.getString(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_PATH))); - bitMap = BitmapFactory.decodeStream(file); - } catch (FileNotFoundException e) { - //Giving more chances to other ads - continue; - } catch (IllegalArgumentException e) { - //Giving more chances to other ads - continue; - } - finally { - if (file != null) { - try { - file.close(); - } catch (IOException e) { - Log.w(TAG, "Error while closing image file."); - } - } - } - entries.add(new AdsEntry(cursor.getString(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_AD_NAME)), - cursor.getString(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_TEXT)), bitMap, - cursor.getInt(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_ID_AD)), - cursor.getString(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_URL)))); - if (cursor.getInt(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_IS_READ)) == 0) - { - values.put(Indexer.Index.COLUMN_NAME_IS_READ, new Integer(1)); - Uri uriUpdate = Uri.parse("content://" + "de.android.mobiads.provider" + "/" + "indexer/" + - cursor.getString(cursor.getColumnIndexOrThrow(Indexer.Index._ID))); - getActivity().getContentResolver().update(uriUpdate, values, null, null); - } - }while (cursor.moveToNext()); - } - }finally { - cursor.close(); - } - - if (this.isMyServiceRunning()) { - showNotification(0, 0, getText(R.string.remote_service_content_empty_notification)); - } - - return entries; - } - - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - MenuInflater inflater = getActivity().getMenuInflater(); - inflater.inflate(R.menu.menuads, menu); - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); - switch (item.getItemId()) { - case R.id.menuadsremove: - removeAd(info.position); - return true; - default: - return super.onContextItemSelected(item); - } - } - - public void removeAd(int position){ - AdsEntry entry = this.newsEntryAdapter.getItem(position); - int idAd = entry.getIdAd(); - Uri uriDelete = Uri.parse("content://" + "de.android.mobiads.provider" + "/" + "indexer" + "/idad/" + idAd); - - getActivity().getContentResolver().delete(uriDelete, null, null); - this.newsEntryAdapter.remove(entry); - this.newsEntryAdapter.notifyDataSetChanged(); - } - - private boolean isMyServiceRunning() { - ActivityManager manager = (ActivityManager) getActivity().getSystemService(Context.ACTIVITY_SERVICE); - for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { - if (MobiAdsService.class.getName().equals(service.service.getClassName())) { - return true; - } - } - return false; - } - - public void showNotification(final int level, final int noReadAds, CharSequence contentText) { - NotificationManager notificationManager = (NotificationManager)getActivity().getSystemService(Context.NOTIFICATION_SERVICE); - - // Set the icon, scrolling text and timestamp - Notification.Builder notificationBuilder = new Notification.Builder(getActivity().getApplicationContext()). - setSmallIcon(R.drawable.wheelnotification, level). - setTicker(getText(R.string.remote_service_started_notification)). - setWhen(System.currentTimeMillis()). - setContentText(contentText). - setContentTitle(getText(R.string.remote_service_title_notification)). - setNumber(noReadAds); - Notification notification = notificationBuilder.getNotification(); - notification.flags |= Notification.FLAG_NO_CLEAR; - - // Send the notification. - // We use a string id because it is a unique number. We use it later to cancel. - notificationManager.notify(R.string.remote_service_title_notification, notification); - } -} diff --git a/Android/MobiAdsTabs/src/de/android/mobiads/list/MobiAdsNewAdsActivity.java b/Android/MobiAdsTabs/src/de/android/mobiads/list/MobiAdsNewAdsActivity.java index 936278c..7a1239b 100644 --- a/Android/MobiAdsTabs/src/de/android/mobiads/list/MobiAdsNewAdsActivity.java +++ b/Android/MobiAdsTabs/src/de/android/mobiads/list/MobiAdsNewAdsActivity.java @@ -37,7 +37,7 @@ public class MobiAdsNewAdsActivity extends Activity { // Setup the list view final ListView newsEntryListView = (ListView) findViewById(R.id.list); - final AdsEntryAdapter newsEntryAdapter = new AdsEntryAdapter(this, R.layout.news_entry_list_item); + final AdsEntryAdapter newsEntryAdapter = new AdsEntryAdapter(this, R.layout.ads_entry_list_item); newsEntryListView.setAdapter(newsEntryAdapter); // Populate the list, through the adapter. Should I populate the whole list right now? I do not think so... -- 2.1.4