Added chooser activity

This commit is contained in:
daniel oeh 2012-07-23 17:05:34 +02:00
parent d33b959e11
commit c9197522de
11 changed files with 332 additions and 43 deletions

View File

@ -128,6 +128,7 @@
</activity>
<activity android:label="@string/about_pref" android:name=".activity.AboutActivity" android:theme="@style/Theme.Sherlock.Light.NoActionBar"></activity>
<activity android:label="@string/opml_import_label" android:name=".activity.OpmlImportActivity"></activity>
<activity android:label="@string/opml_import_label" android:name=".activity.OpmlFeedChooserActivity" android:theme="@style/Theme.Sherlock.Light.NoActionBar"></activity>
</application>
</manifest>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/footer"
style="@android:style/ButtonBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal" >
<Button
android:id="@+id/butConfirm"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/confirm_label" />
<Button
android:id="@+id/butCancel"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/cancel_label" />
</LinearLayout>
<ListView
android:id="@+id/feedlist"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_above="@id/footer"
android:layout_alignParentTop="true"
tools:listitem="@android:layout/simple_list_item_multiple_choice" >
</ListView>
</RelativeLayout>

View File

@ -20,4 +20,5 @@
</item>
<item android:id="@+id/show_preferences" android:title="@string/settings_label" android:icon="@drawable/action_settings" android:showAsAction="collapseActionView"></item>
<item android:id="@+id/show_player" android:title="@string/show_player_label" android:icon="@drawable/av_play" android:showAsAction="collapseActionView"></item>
<item android:id="@+id/opml_import" android:title="@string/opml_import_label" android:showAsAction="collapseActionView"></item>
</menu>

View File

@ -1,5 +1,5 @@
package de.danoeh.antennapod;
public final class AppConfig {
public final static boolean DEBUG = false;
public final static boolean DEBUG = true;
}

View File

@ -105,6 +105,9 @@ public class MainActivity extends SherlockFragmentActivity {
case R.id.show_player:
startActivity(new Intent(this, MediaplayerActivity.class));
return true;
case R.id.opml_import:
startActivity(new Intent(this, OpmlImportActivity.class));
return true;
default:
return super.onOptionsItemSelected(item);
}

View File

@ -0,0 +1,95 @@
package de.danoeh.antennapod.activity;
import java.util.ArrayList;
import java.util.List;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import com.actionbarsherlock.app.SherlockActivity;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.opml.OpmlElement;
public class OpmlFeedChooserActivity extends SherlockActivity {
private static final String TAG = "OpmlFeedChooserActivity";
public static final String EXTRA_SELECTED_ITEMS = "de.danoeh.antennapod.selectedItems";
private Button butConfirm;
private Button butCancel;
private ListView feedlist;
private ArrayAdapter<String> listAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.opml_selection);
butConfirm = (Button) findViewById(R.id.butConfirm);
butCancel = (Button) findViewById(R.id.butCancel);
feedlist = (ListView) findViewById(R.id.feedlist);
feedlist.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_multiple_choice,
getTitleList());
feedlist.setAdapter(listAdapter);
butCancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
setResult(RESULT_CANCELED);
finish();
}
});
butConfirm.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
SparseBooleanArray checked = feedlist.getCheckedItemPositions();
int checkedCount = 0;
// Get number of checked items
for (int i = 0; i < checked.size(); i++) {
if (checked.valueAt(i)) {
checkedCount++;
}
}
int[] selection = new int[checkedCount];
for (int i = 0, collected = 0; collected < checkedCount; i++) {
if (checked.valueAt(i)) {
selection[collected] = checked.keyAt(i);
collected++;
}
}
intent.putExtra(EXTRA_SELECTED_ITEMS, selection);
setResult(RESULT_OK, intent);
finish();
}});
}
private List<String> getTitleList() {
List<String> result = new ArrayList<String>();
if (OpmlImportActivity.getReadElements() != null) {
for (OpmlElement element : OpmlImportActivity.getReadElements()) {
result.add(element.getText());
}
}
return result;
}
}

View File

@ -3,6 +3,7 @@ package de.danoeh.antennapod.activity;
import java.io.File;
import java.util.ArrayList;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
@ -16,6 +17,7 @@ import com.actionbarsherlock.view.MenuItem;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.asynctask.OpmlFeedQueuer;
import de.danoeh.antennapod.asynctask.OpmlImportWorker;
import de.danoeh.antennapod.opml.OpmlElement;
import de.danoeh.antennapod.util.StorageUtils;
@ -31,6 +33,8 @@ public class OpmlImportActivity extends SherlockActivity {
private OpmlImportWorker importWorker;
private static ArrayList<OpmlElement> readElements;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -105,12 +109,53 @@ public class OpmlImportActivity extends SherlockActivity {
@Override
protected void onPostExecute(ArrayList<OpmlElement> result) {
super.onPostExecute(result);
if (result != null) {
if (AppConfig.DEBUG) Log.d(TAG, "Parsing was successful");
readElements = result;
startActivityForResult(new Intent(
OpmlImportActivity.this,
OpmlFeedChooserActivity.class), 0);
} else {
if (AppConfig.DEBUG) Log.d(TAG, "Parser error occured");
}
}
};
importWorker.executeAsync();
} else {
Log.e(TAG, "Import directory is empty");
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (AppConfig.DEBUG) Log.d(TAG, "Received result");
if (resultCode == RESULT_CANCELED) {
if (AppConfig.DEBUG) Log.d(TAG, "Activity was cancelled");
} else {
int[] selected = data.getIntArrayExtra(OpmlFeedChooserActivity.EXTRA_SELECTED_ITEMS);
if (selected != null && selected.length > 0) {
OpmlFeedQueuer queuer = new OpmlFeedQueuer(this, selected){
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
finish();
}
};
queuer.executeAsync();
} else {
if (AppConfig.DEBUG) Log.d(TAG, "No items were selected");
}
}
}
public static ArrayList<OpmlElement> getReadElements() {
return readElements;
}
}

View File

@ -162,10 +162,16 @@ public class FeedImageLoader {
decodedBitmap = BitmapFactory.decodeFile(params[0]
.getFile_url());
}
if (decodedBitmap != null) {
bitmap = Bitmap.createScaledBitmap(decodedBitmap,
PREFERRED_LENGTH, PREFERRED_LENGTH, false);
addBitmapToCache(params[0].getId(), bitmap);
} else {
Log.w(TAG, "Could not load bitmap. Using default image.");
bitmap = BitmapFactory.decodeResource(target.getResources(),
R.drawable.default_cover);
}
if (AppConfig.DEBUG) Log.d(TAG, "Finished loading bitmaps");
} else {
Log.e(TAG,

View File

@ -0,0 +1,70 @@
package de.danoeh.antennapod.asynctask;
import java.util.Date;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.OpmlImportActivity;
import de.danoeh.antennapod.feed.Feed;
import de.danoeh.antennapod.opml.OpmlElement;
import de.danoeh.antennapod.storage.DownloadRequester;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
/** Queues items for download in the background. */
public class OpmlFeedQueuer extends AsyncTask<Void, Void, Void> {
private Context context;
private ProgressDialog progDialog;
private int[] selection;
public OpmlFeedQueuer(Context context, int[] selection) {
super();
this.context = context;
this.selection = selection;
}
@Override
protected void onPostExecute(Void result) {
progDialog.dismiss();
}
@Override
protected void onPreExecute() {
progDialog = new ProgressDialog(context);
progDialog.setMessage(context.getString(R.string.processing_label));
progDialog.setCancelable(false);
progDialog.setIndeterminate(true);
progDialog.show();
}
@Override
protected Void doInBackground(Void... params) {
DownloadRequester requester = DownloadRequester.getInstance();
for (int idx = 0; idx < selection.length; idx++) {
OpmlElement element = OpmlImportActivity.getReadElements().get(selection[idx]);
Feed feed = new Feed(element.getXmlUrl(), new Date());
feed.setTitle(element.getText());
requester.downloadFeed(context.getApplicationContext(), feed);
}
return null;
}
@SuppressLint("NewApi")
public void executeAsync() {
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
executeOnExecutor(THREAD_POOL_EXECUTOR);
} else {
execute();
}
}
}

View File

@ -13,6 +13,7 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.opml.OpmlElement;
import de.danoeh.antennapod.opml.OpmlReader;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.app.AlertDialog.Builder;
@ -100,5 +101,18 @@ public class OpmlImportWorker extends
progDialog.setCancelable(false);
progDialog.show();
}
public boolean wasSuccessful() {
return exception != null;
}
@SuppressLint("NewApi")
public void executeAsync() {
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
executeOnExecutor(THREAD_POOL_EXECUTOR);
} else {
execute();
}
}
}

View File

@ -16,7 +16,7 @@ import android.util.Log;
/** Reads OPML documents. */
public class OpmlReader {
private static final String TAG = "OpmlReader";
// TAGS
private static final String OPML = "opml";
private static final String BODY = "body";
@ -25,54 +25,69 @@ public class OpmlReader {
private static final String XMLURL = "xmlUrl";
private static final String HTMLURL = "htmlUrl";
private static final String TYPE = "type";
// ATTRIBUTES
private boolean isInOpml = false;
private boolean isInBody = false;
private ArrayList<OpmlElement> elementList;
/** Reads an Opml document and returns a list of all OPML elements it can find
/**
* Reads an Opml document and returns a list of all OPML elements it can
* find
*
* @throws IOException
* @throws XmlPullParserException*/
public ArrayList<OpmlElement> readDocument(Reader reader) throws XmlPullParserException, IOException {
* @throws XmlPullParserException
*/
public ArrayList<OpmlElement> readDocument(Reader reader)
throws XmlPullParserException, IOException {
elementList = new ArrayList<OpmlElement>();
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(reader);
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
if (AppConfig.DEBUG) Log.d(TAG, "Reached beginning of document");
break;
case XmlPullParser.START_TAG:
if (xpp.getName().equals(OPML)) {
isInOpml = true;
if (AppConfig.DEBUG) Log.d(TAG, "Reached beginning of OPML tree.");
} else if (isInOpml && xpp.getName().equals(BODY)) {
isInBody = true;
if (AppConfig.DEBUG) Log.d(TAG, "Reached beginning of body tree.");
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(reader);
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
if (AppConfig.DEBUG)
Log.d(TAG, "Reached beginning of document");
break;
case XmlPullParser.START_TAG:
if (xpp.getName().equals(OPML)) {
isInOpml = true;
if (AppConfig.DEBUG)
Log.d(TAG, "Reached beginning of OPML tree.");
} else if (isInOpml && xpp.getName().equals(BODY)) {
isInBody = true;
if (AppConfig.DEBUG)
Log.d(TAG, "Reached beginning of body tree.");
} else if (isInBody && xpp.getName().equals(OUTLINE)) {
if (AppConfig.DEBUG)
Log.d(TAG, "Found new Opml element");
OpmlElement element = new OpmlElement();
element.setText(xpp.getAttributeValue(null, TEXT));
element.setXmlUrl(xpp.getAttributeValue(null, XMLURL));
element.setHtmlUrl(xpp.getAttributeValue(null, HTMLURL));
element.setType(xpp.getAttributeValue(null, TYPE));
if (element.getXmlUrl() != null) {
elementList.add(element);
} else {
if (AppConfig.DEBUG)
Log.d(TAG,
"Skipping element because of missing xml url");
}
}
break;
}
eventType = xpp.next();
}
if (AppConfig.DEBUG)
Log.d(TAG, "Parsing finished.");
} else if (isInBody && xpp.getName().equals(OUTLINE)) {
if (AppConfig.DEBUG) Log.d(TAG, "Found new Opml element");
OpmlElement element = new OpmlElement();
element.setText(xpp.getAttributeValue(null, TEXT));
element.setXmlUrl(xpp.getAttributeValue(null, XMLURL));
element.setHtmlUrl(xpp.getAttributeValue(null, HTMLURL));
element.setType(xpp.getAttributeValue(null, TYPE));
elementList.add(element);
}
break;
}
eventType = xpp.next();
}
if (AppConfig.DEBUG) Log.d(TAG, "Parsing finished.");
return elementList;
}
}