It looks like a nice implementation.
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;
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;
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Layout for individual ads entries in a list -->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical">
+
+ <!-- Icon shown next to the title/text -->
+ <ImageView
+ android:id="@+id/ads_entry_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentLeft="true"
+ android:padding="3dp"
+ android:orientation="vertical"
+ android:contentDescription="@string/desc"/>
+
+ <!-- Title of the ads entry -->
+ <TextView
+ android:id="@+id/ads_entry_title"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@id/ads_entry_icon"
+ android:layout_alignTop="@id/ads_entry_icon"
+ android:layout_margin="5dp"
+ android:textSize="14sp"
+ android:textStyle="bold" />
+
+ <!-- Text of our entry -->
+ <TextView
+ android:id="@+id/ads_entry_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignLeft="@id/ads_entry_title"
+ android:layout_below="@id/ads_entry_title"
+ android:textSize="12sp" />
+
+</RelativeLayout>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
-
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
-
- <ListView android:id="@+id/list"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" />
-
-</LinearLayout>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-
-<!-- Layout for individual ads entries in a list -->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical">
-
- <!-- Icon shown next to the title/text -->
- <ImageView
- android:id="@+id/ads_entry_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:layout_alignParentLeft="true"
- android:padding="3dp"
- android:orientation="vertical"
- android:contentDescription="@string/desc"/>
-
- <!-- Title of the ads entry -->
- <TextView
- android:id="@+id/ads_entry_title"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/ads_entry_icon"
- android:layout_alignTop="@id/ads_entry_icon"
- android:layout_margin="5dp"
- android:textSize="14sp"
- android:textStyle="bold" />
-
- <!-- Text of our entry -->
- <TextView
- android:id="@+id/ads_entry_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignLeft="@id/ads_entry_title"
- android:layout_below="@id/ads_entry_title"
- android:textSize="12sp" />
-
-</RelativeLayout>
\ No newline at end of file
<string name="encoded_web_service">UTF-8</string>
<string name="desc">description</string>
<string name="menuads_remove">Remove</string>
+ <string name="error_dialog_no_local_ads">You have no downloaded ads.</string>
</resources>
\ No newline at end of file
+++ /dev/null
-/*
- * 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;
-// }
- }
-
-}
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);
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;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
-import android.widget.Toast;
public class MobiAdsTabsActivity extends Activity {
bar.addTab(bar.newTab()
.setText("Local Ads")
- .setTabListener(new TabListener<MobiAdsListFragment>(
- this, "localads", MobiAdsListFragment.class)));
+ .setTabListener(new TabListener<MobiAdsList.MobiAdsListFragment>(
+ this, "localads", MobiAdsList.MobiAdsListFragment.class)));
if (Cookie.getCookie() != null || isMyServiceRunning()) {
bar.addTab(bar.newTab()
.setText("Control Panel")
- .setTabListener(new TabListener<MobiAdsPreferences>(
- this, "controlpanel", MobiAdsPreferences.class)));
+ .setTabListener(new TabListener<MobiAdsPreferences>(
+ this, "controlpanel", MobiAdsPreferences.class)));
}
bar.addTab(bar.newTab()
.setText("Login")
- .setTabListener(new Login()));
+ .setTabListener(new Login()));
super.onResume();
if ((Cookie.getCookie() != null) && (getActionBar().getTabCount() == 2)) {
getActionBar().addTab(getActionBar().newTab()
- .setText("Control Panel")
- .setTabListener(new TabListener<MobiAdsPreferences>(
+ .setText("Control Panel")
+ .setTabListener(new TabListener<MobiAdsPreferences>(
this, "controlpanel", MobiAdsPreferences.class)), 1);
}
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
- Toast.makeText(mActivity, "Reselected!", Toast.LENGTH_SHORT).show();
+ //Nothing to do here.
}
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
- // TODO Auto-generated method stub
-
+ //Nothing to do here
}
@Override
--- /dev/null
+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<List<AdsEntry>> {
+ private static final String TAG = "AdsListLoader";
+ List<AdsEntry> 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<AdsEntry> loadInBackground() {
+ // Create corresponding array of entries and load their labels.
+ List<AdsEntry> entries = getAdsEntries();
+
+ return entries;
+ }
+
+ private List<AdsEntry> getAdsEntries() {
+ final List<AdsEntry> entries = new ArrayList<AdsEntry>();
+ 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<AdsEntry> 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<AdsEntry> 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<List<AdsEntry>> {
+ 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<List<AdsEntry>> 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<List<AdsEntry>> loader, List<AdsEntry> 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<List<AdsEntry>> 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<AdsEntry> {
+ private final int adsItemLayoutResource;
+
+ public AdsEntryAdapter(final Context context, final int adsItemLayoutResource) {
+ super(context, 0);
+ this.adsItemLayoutResource = adsItemLayoutResource;
+ }
+
+ public void setData(List<AdsEntry> 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;
+ }
+ }
+}
+++ /dev/null
-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<AdsEntry> getAdsEntries() {
- final List<AdsEntry> entries = new ArrayList<AdsEntry>();
- 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);
- }
-}
// 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...