Merge branch 'ligi-better_ompl_import' into develop

This commit is contained in:
daniel oeh 2013-02-23 12:12:37 +01:00
commit 64591fa050
11 changed files with 442 additions and 263 deletions

View File

@ -162,10 +162,105 @@
android:label="@string/about_pref" >
</activity>
<activity
android:name=".activity.OpmlImportActivity"
android:name=".activity.OpmlImportFromPathActivity"
android:configChanges="keyboardHidden|orientation"
android:label="@string/opml_import_label" >
</activity>
<activity
android:name=".activity.OpmlImportFromIntentActivity"
android:configChanges="keyboardHidden|orientation"
android:label="@string/opml_import_label" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="*"
android:pathPattern=".*\\.xml"
android:scheme="https" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="*"
android:pathPattern=".*\\.xml"
android:scheme="http" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:pathPattern=".*\\.xml"
android:scheme="file" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:mimeType="application/xml" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:mimeType="text/xml" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="*"
android:pathPattern=".*\\.opml"
android:scheme="https" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="*"
android:pathPattern=".*\\.opml"
android:scheme="http" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="*"
android:mimeType="*/*"
android:pathPattern=".*\\.opml"
android:scheme="file" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:mimeType="text/x-opml" />
</intent-filter>
</activity>
<activity
android:name=".activity.OpmlFeedChooserActivity"
android:label="@string/opml_import_label" >

View File

@ -13,7 +13,7 @@ import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.preference.PreferenceManager;
import android.util.Log;
import de.danoeh.antennapod.activity.OpmlImportActivity;
import de.danoeh.antennapod.activity.OpmlImportFromPathActivity;
import de.danoeh.antennapod.asynctask.FeedImageLoader;
import de.danoeh.antennapod.feed.FeedManager;
import de.danoeh.antennapod.feed.FeedMedia;
@ -93,7 +93,7 @@ public class PodcastApp extends Application implements
* available
*/
private void createImportDirectory() {
File importDir = getDataFolder(this, OpmlImportActivity.IMPORT_DIR);
File importDir = getDataFolder(this, OpmlImportFromPathActivity.IMPORT_DIR);
if (importDir != null) {
if (importDir.exists()) {
if (AppConfig.DEBUG)

View File

@ -73,7 +73,7 @@ public class AddFeedActivity extends SherlockActivity {
@Override
public void onClick(View v) {
startActivity(new Intent(AddFeedActivity.this,
OpmlImportActivity.class));
OpmlImportFromPathActivity.class));
}
});

View File

@ -90,8 +90,8 @@ public class OpmlFeedChooserActivity extends SherlockActivity {
private List<String> getTitleList() {
List<String> result = new ArrayList<String>();
if (OpmlImportActivity.getReadElements() != null) {
for (OpmlElement element : OpmlImportActivity.getReadElements()) {
if (OpmlImportHolder.getReadElements() != null) {
for (OpmlElement element : OpmlImportHolder.getReadElements()) {
result.add(element.getText());
}

View File

@ -1,233 +0,0 @@
package de.danoeh.antennapod.activity;
import java.io.File;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.PodcastApp;
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;
/** Lets the user start the OPML-import process. */
public class OpmlImportActivity extends SherlockActivity {
private static final String TAG = "OpmlImportActivity";
public static final String IMPORT_DIR = "import/";
private TextView txtvPath;
private Button butStart;
private String importPath;
private OpmlImportWorker importWorker;
private static ArrayList<OpmlElement> readElements;
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(PodcastApp.getThemeResourceId());
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setContentView(R.layout.opml_import);
txtvPath = (TextView) findViewById(R.id.txtvPath);
butStart = (Button) findViewById(R.id.butStartImport);
butStart.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
checkFolderForFiles();
}
});
}
@Override
protected void onResume() {
super.onResume();
StorageUtils.checkStorageAvailability(this);
setImportPath();
}
/**
* Sets the importPath variable and makes txtvPath display the import
* directory.
*/
private void setImportPath() {
File importDir = PodcastApp.getDataFolder(this, IMPORT_DIR);
boolean success = true;
if (!importDir.exists()) {
if (AppConfig.DEBUG)
Log.d(TAG, "Import directory doesn't exist. Creating...");
success = importDir.mkdir();
if (!success) {
Log.e(TAG, "Could not create directory");
}
}
if (success) {
txtvPath.setText(importDir.toString());
importPath = importDir.toString();
} else {
txtvPath.setText(R.string.opml_directory_error);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
default:
return false;
}
}
/**
* Looks at the contents of the import directory and decides what to do. If
* more than one file is in the directory, a dialog will be created to let
* the user choose which item to import
* */
private void checkFolderForFiles() {
File dir = new File(importPath);
if (dir.isDirectory()) {
File[] fileList = dir.listFiles();
if (fileList.length == 1) {
if (AppConfig.DEBUG)
Log.d(TAG, "Found one file, choosing that one.");
startImport(fileList[0]);
} else if (fileList.length > 1) {
Log.w(TAG, "Import directory contains more than one file.");
askForFile(dir);
} else {
Log.e(TAG, "Import directory is empty");
Toast toast = Toast
.makeText(this, R.string.opml_import_error_dir_empty,
Toast.LENGTH_LONG);
toast.show();
}
}
}
/** Starts the import process. */
private void startImport(File file) {
if (file != null) {
importWorker = new OpmlImportWorker(this, file) {
@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();
}
}
/**
* Asks the user to choose from a list of files in a directory and returns
* his choice.
*/
private void askForFile(File dir) {
final File[] fileList = dir.listFiles();
String[] fileNames = dir.list();
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle(R.string.choose_file_to_import_label);
dialog.setNeutralButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (AppConfig.DEBUG)
Log.d(TAG, "Dialog was cancelled");
dialog.dismiss();
}
});
dialog.setItems(fileNames, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (AppConfig.DEBUG)
Log.d(TAG, "File at index " + which + " was chosen");
dialog.dismiss();
startImport(fileList[which]);
}
});
dialog.create().show();
}
/**
* Handles the choices made by the user in the OpmlFeedChooserActivity and
* starts the OpmlFeedQueuer if necessary.
*/
@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);
Intent intent = new Intent(OpmlImportActivity.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
};
queuer.executeAsync();
} else {
if (AppConfig.DEBUG)
Log.d(TAG, "No items were selected");
}
}
}
public static ArrayList<OpmlElement> getReadElements() {
return readElements;
}
}

View File

@ -0,0 +1,89 @@
package de.danoeh.antennapod.activity;
import android.content.Intent;
import android.util.Log;
import com.actionbarsherlock.app.SherlockActivity;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.asynctask.OpmlFeedQueuer;
import de.danoeh.antennapod.asynctask.OpmlImportWorker;
import de.danoeh.antennapod.opml.OpmlElement;
import java.io.Reader;
import java.util.ArrayList;
/**
* Base activity for Opml Import - e.g. with code what to do afterwards
* */
public class OpmlImportBaseActivity extends SherlockActivity {
private static final String TAG = "OpmlImportBaseActivity";
private OpmlImportWorker importWorker;
/**
* Handles the choices made by the user in the OpmlFeedChooserActivity and
* starts the OpmlFeedQueuer if necessary.
*/
@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");
if (finishWhenCanceled())
finish();
} 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);
Intent intent = new Intent(OpmlImportBaseActivity.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
};
queuer.executeAsync();
} else {
if (AppConfig.DEBUG)
Log.d(TAG, "No items were selected");
}
}
}
/** Starts the import process. */
protected void startImport(Reader reader) {
if (reader != null) {
importWorker = new OpmlImportWorker(this, reader) {
@Override
protected void onPostExecute(ArrayList<OpmlElement> result) {
super.onPostExecute(result);
if (result != null) {
if (AppConfig.DEBUG)
Log.d(TAG, "Parsing was successful");
OpmlImportHolder.setReadElements(result);
startActivityForResult(new Intent(
OpmlImportBaseActivity.this,
OpmlFeedChooserActivity.class), 0);
} else {
if (AppConfig.DEBUG)
Log.d(TAG, "Parser error occurred");
}
}
};
importWorker.executeAsync();
}
}
protected boolean finishWhenCanceled() {
return false;
}
}

View File

@ -0,0 +1,34 @@
package de.danoeh.antennapod.activity;
import android.app.AlertDialog;
import android.os.Bundle;
import de.danoeh.antennapod.PodcastApp;
import java.io.*;
import java.net.URL;
/** Lets the user start the OPML-import process. */
public class OpmlImportFromIntentActivity extends OpmlImportBaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(PodcastApp.getThemeResourceId());
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
try {
URL mOpmlURL = new URL(getIntent().getData().toString());
BufferedReader in = new BufferedReader(new InputStreamReader(mOpmlURL.openStream()));
startImport(in);
} catch (Exception e) {
new AlertDialog.Builder(this).setMessage("Cannot open XML - Reason: " + e.getMessage()).show();
}
}
@Override
protected boolean finishWhenCanceled() {
return true;
}
}

View File

@ -0,0 +1,171 @@
package de.danoeh.antennapod.activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.PodcastApp;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.util.StorageUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.Reader;
/**
* Lets the user start the OPML-import process from a path
*/
public class OpmlImportFromPathActivity extends OpmlImportBaseActivity {
public static final String IMPORT_DIR = "import/";
private static final String TAG = "OpmlImportFromPathActivity";
private TextView txtvPath;
private Button butStart;
private String importPath;
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(PodcastApp.getThemeResourceId());
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setContentView(R.layout.opml_import);
txtvPath = (TextView) findViewById(R.id.txtvPath);
butStart = (Button) findViewById(R.id.butStartImport);
butStart.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
checkFolderForFiles();
}
});
}
@Override
protected void onResume() {
super.onResume();
StorageUtils.checkStorageAvailability(this);
setImportPath();
}
/**
* Sets the importPath variable and makes txtvPath display the import
* directory.
*/
private void setImportPath() {
File importDir = PodcastApp.getDataFolder(this, IMPORT_DIR);
boolean success = true;
if (!importDir.exists()) {
if (AppConfig.DEBUG)
Log.d(TAG, "Import directory doesn't exist. Creating...");
success = importDir.mkdir();
if (!success) {
Log.e(TAG, "Could not create directory");
}
}
if (success) {
txtvPath.setText(importDir.toString());
importPath = importDir.toString();
} else {
txtvPath.setText(R.string.opml_directory_error);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
default:
return false;
}
}
/**
* Looks at the contents of the import directory and decides what to do. If
* more than one file is in the directory, a dialog will be created to let
* the user choose which item to import
*/
private void checkFolderForFiles() {
File dir = new File(importPath);
if (dir.isDirectory()) {
File[] fileList = dir.listFiles();
if (fileList.length == 1) {
if (AppConfig.DEBUG)
Log.d(TAG, "Found one file, choosing that one.");
startImport(fileList[0]);
} else if (fileList.length > 1) {
Log.w(TAG, "Import directory contains more than one file.");
askForFile(dir);
} else {
Log.e(TAG, "Import directory is empty");
Toast toast = Toast
.makeText(this, R.string.opml_import_error_dir_empty,
Toast.LENGTH_LONG);
toast.show();
}
}
}
private void startImport(File file) {
try {
Reader mReader = new FileReader(file);
if (AppConfig.DEBUG) Log.d(TAG, "Parsing " + file.toString());
startImport(mReader);
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found which really should be there");
// this should never happen as it is a file we have just chosen
}
}
/**
* Asks the user to choose from a list of files in a directory and returns
* his choice.
*/
private void askForFile(File dir) {
final File[] fileList = dir.listFiles();
String[] fileNames = dir.list();
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle(R.string.choose_file_to_import_label);
dialog.setNeutralButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (AppConfig.DEBUG)
Log.d(TAG, "Dialog was cancelled");
dialog.dismiss();
}
});
dialog.setItems(fileNames, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (AppConfig.DEBUG)
Log.d(TAG, "File at index " + which + " was chosen");
dialog.dismiss();
startImport(fileList[which]);
}
});
dialog.create().show();
}
}

View File

@ -0,0 +1,29 @@
package de.danoeh.antennapod.activity;
import de.danoeh.antennapod.opml.OpmlElement;
import java.util.ArrayList;
/**
* Hold infos gathered by Ompl-Import
* <p/>
* Created with IntelliJ IDEA.
* User: ligi
* Date: 1/23/13
* Time: 2:15 PM
*/
public class OpmlImportHolder {
private static ArrayList<OpmlElement> readElements;
public static ArrayList<OpmlElement> getReadElements() {
return readElements;
}
public static void setReadElements(ArrayList<OpmlElement> _readElements) {
readElements = _readElements;
}
}

View File

@ -7,7 +7,8 @@ import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.OpmlImportActivity;
import de.danoeh.antennapod.activity.OpmlImportFromPathActivity;
import de.danoeh.antennapod.activity.OpmlImportHolder;
import de.danoeh.antennapod.feed.Feed;
import de.danoeh.antennapod.opml.OpmlElement;
import de.danoeh.antennapod.storage.DownloadRequestException;
@ -43,7 +44,7 @@ public class OpmlFeedQueuer extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
DownloadRequester requester = DownloadRequester.getInstance();
for (int idx = 0; idx < selection.length; idx++) {
OpmlElement element = OpmlImportActivity.getReadElements().get(
OpmlElement element = OpmlImportHolder.getReadElements().get(
selection[idx]);
Feed feed = new Feed(element.getXmlUrl(), new Date(),
element.getText());

View File

@ -1,9 +1,6 @@
package de.danoeh.antennapod.asynctask;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.*;
import java.util.ArrayList;
import org.xmlpull.v1.XmlPullParserException;
@ -26,35 +23,31 @@ public class OpmlImportWorker extends
private static final String TAG = "OpmlImportWorker";
private Context context;
private File file; // path to opml file
private Exception exception;
private ProgressDialog progDialog;
public OpmlImportWorker(Context context, File file) {
super();
this.context = context;
this.file = file;
}
private Reader mReader;
public OpmlImportWorker(Context context, Reader reader) {
super();
this.context = context;
this.mReader=reader;
}
@Override
protected ArrayList<OpmlElement> doInBackground(Void... params) {
if (AppConfig.DEBUG)
Log.d(TAG, "Starting background work");
FileReader reader = null;
// Create reader
try {
reader = new FileReader(file);
if (AppConfig.DEBUG) Log.d(TAG, "Parsing " + file.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
exception = e;
return null;
}
if (mReader==null) {
return null;
}
OpmlReader opmlReader = new OpmlReader();
try {
ArrayList<OpmlElement> result = opmlReader.readDocument(reader);
reader.close();
ArrayList<OpmlElement> result = opmlReader.readDocument(mReader);
mReader.close();
return result;
} catch (XmlPullParserException e) {
e.printStackTrace();