diff --git a/core/res/values/strings.xml b/core/res/values/strings.xml
index a3014d18..563fe83c 100644
--- a/core/res/values/strings.xml
+++ b/core/res/values/strings.xml
@@ -103,7 +103,8 @@
Torrent search
Search for torrents
- The Barcode Scanner could not be found. Would you like to install it from the Android Market?
+ The Barcode Scanner could not be found. Would you like to install it from the Play Store?
+ No compatible file manager could not be found. Would you like to install IO File Manager from the Play Store?
Servers
Add new server
diff --git a/core/src/org/transdroid/core/gui/TorrentsActivity.java b/core/src/org/transdroid/core/gui/TorrentsActivity.java
index 154ffd29..f9db7bad 100644
--- a/core/src/org/transdroid/core/gui/TorrentsActivity.java
+++ b/core/src/org/transdroid/core/gui/TorrentsActivity.java
@@ -1,5 +1,9 @@
package org.transdroid.core.gui;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
@@ -16,7 +20,6 @@ import org.androidannotations.annotations.SystemService;
import org.androidannotations.annotations.UiThread;
import org.androidannotations.annotations.ViewById;
import org.transdroid.core.R;
-import org.transdroid.core.app.search.BarcodeHelper;
import org.transdroid.core.app.settings.ApplicationSettings;
import org.transdroid.core.app.settings.ServerSetting;
import org.transdroid.core.gui.lists.LocalTorrent;
@@ -31,10 +34,15 @@ import org.transdroid.core.gui.navigation.Label;
import org.transdroid.core.gui.navigation.NavigationFilter;
import org.transdroid.core.gui.navigation.NavigationHelper;
import org.transdroid.core.gui.navigation.StatusType;
+import org.transdroid.core.gui.search.BarcodeHelper;
+import org.transdroid.core.gui.search.FilePickerHelper;
+import org.transdroid.core.gui.search.UrlEntryDialog;
import org.transdroid.core.gui.settings.MainSettingsActivity_;
import org.transdroid.daemon.Daemon;
import org.transdroid.daemon.IDaemonAdapter;
import org.transdroid.daemon.Torrent;
+import org.transdroid.daemon.task.AddByFileTask;
+import org.transdroid.daemon.task.AddByMagnetUrlTask;
import org.transdroid.daemon.task.AddByUrlTask;
import org.transdroid.daemon.task.DaemonTaskFailureResult;
import org.transdroid.daemon.task.DaemonTaskResult;
@@ -56,6 +64,7 @@ import org.transdroid.daemon.util.DLog;
import android.annotation.TargetApi;
import android.app.SearchManager;
+import android.content.ContentResolver;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
@@ -147,7 +156,7 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
getSupportActionBar().setSelectedNavigationItem(lastUsed.getOrder());
// Handle any start up intents
- if (firstStart) {
+ if (firstStart && getIntent() != null) {
handleStartIntent();
}
@@ -320,17 +329,69 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
* If required, add torrents, switch to a specific server, etc.
*/
protected void handleStartIntent() {
- // TODO: Handle start intent
+
+ Intent intent = getIntent();
+ Uri dataUri = intent.getData();
+ String data = intent.getDataString();
+ String action = intent.getAction();
+
+ if (action.equals("org.transdroid.ADD_MULTIPLE")) {
+ // Intent should have some extras pointing to possibly multiple torrents
+ String[] urls = intent.getStringArrayExtra("TORRENT_URLS");
+ String[] titles = intent.getStringArrayExtra("TORRENT_TITLES");
+ if (urls != null) {
+ for (int i = 0; i < urls.length; i++) {
+ addTorrentByUrl(urls[i], (titles != null && titles.length >= i? titles[i]: "Torrent"));
+ }
+ }
+ return;
+ }
+
+ if (dataUri.getScheme() != null && dataUri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
+ addTorrentFromDownloads(dataUri);
+ return;
+ }
+
+ if (dataUri.getScheme().equals("http") || dataUri.getScheme().equals("https")) {
+ String title = data.substring(data.lastIndexOf("/"));
+ if (intent.hasExtra("TORRENT_TITLE")) {
+ title = intent.getStringExtra("TORRENT_TITLE");
+ }
+ addTorrentByUrl(data, title);
+ return;
+ }
+
+ if (dataUri.getScheme().equals("magnet")) {
+ addTorrentByMagnetUrl(data);
+ return;
+ }
+
+ if (dataUri.getScheme().equals("file")) {
+ String title = data.substring(data.lastIndexOf("/"));
+ addTorrentByFile(data, title);
+ return;
+ }
+
}
@OptionsItem(resName = "action_add_fromurl")
protected void startUrlEntryDialog() {
- // TODO: Open URL input dialog
+ UrlEntryDialog.startUrlEntry(this);
}
@OptionsItem(resName = "action_add_fromfile")
protected void startFilePicker() {
- // TODO: Start file picker
+ FilePickerHelper.startFilePicker(this);
+ }
+
+ @Background
+ @OnActivityResult(FilePickerHelper.ACTIVITY_FILEPICKER)
+ public void onFilePicked(int resultCode, Intent data) {
+ // We should have received an Intent with a local torrent's Uri as data from the file picker
+ if (data != null && data.getData() != null && !data.getData().equals("")) {
+ String url = data.getData().getPath();
+ addTorrentByFile(data.getData().toString(), url.substring(url.lastIndexOf("/")));
+ }
}
@OptionsItem(resName = "action_add_frombarcode")
@@ -338,15 +399,17 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
BarcodeHelper.startBarcodeScanner(this);
}
+ @Background
@OnActivityResult(BarcodeHelper.ACTIVITY_BARCODE)
public void onBarcodeScanned(int resultCode, Intent data) {
- String query = BarcodeHelper.handleScanResult(this, resultCode, data);
+ // We receive from the helper either a URL (as string) or a query we can start a search for
+ String query = BarcodeHelper.handleScanResult(resultCode, data);
if (query.startsWith("http"))
addTorrentByUrl(query, "QR code result"); // No torrent title known
else
startSearch(query, false, null, false);
}
-
+
@OptionsItem(resName = "action_refresh")
protected void refreshScreen() {
fragmentTorrents.updateIsLoading(true);
@@ -412,7 +475,7 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
}
@Background
- public void addTorrentByUrl(String url, String title) {
+ protected void addTorrentByUrl(String url, String title) {
DaemonTaskResult result = AddByUrlTask.create(currentConnection, url, title).execute();
if (result instanceof DaemonTaskResult) {
onTaskSucceeded((DaemonTaskSuccessResult) result, R.string.result_added, title);
@@ -422,6 +485,65 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
}
}
+ @Background
+ protected void addTorrentByMagnetUrl(String url) {
+ DaemonTaskResult result = AddByMagnetUrlTask.create(currentConnection, url).execute();
+ if (result instanceof DaemonTaskResult) {
+ onTaskSucceeded((DaemonTaskSuccessResult) result, R.string.result_added, "Torrent");
+ refreshTorrents();
+ } else {
+ onCommunicationError((DaemonTaskFailureResult) result);
+ }
+ }
+
+ @Background
+ protected void addTorrentByFile(String localFile, String title) {
+ DaemonTaskResult result = AddByFileTask.create(currentConnection, localFile).execute();
+ if (result instanceof DaemonTaskResult) {
+ onTaskSucceeded((DaemonTaskSuccessResult) result, R.string.result_added, title);
+ refreshTorrents();
+ } else {
+ onCommunicationError((DaemonTaskFailureResult) result);
+ }
+ }
+
+ private void addTorrentFromDownloads(Uri contentUri) {
+
+ InputStream input = null;
+ try {
+ // Open the content uri as input stream
+ input = getContentResolver().openInputStream(contentUri);
+
+ // Write a temporary file with the torrent contents
+ File tempFile = File.createTempFile("transdroid_", ".torrent", getCacheDir());
+ FileOutputStream output = new FileOutputStream(tempFile);
+ try {
+ final byte[] buffer = new byte[1024];
+ int read;
+ while ((read = input.read(buffer)) != -1)
+ output.write(buffer, 0, read);
+ output.flush();
+ String fileName = Uri.fromFile(tempFile).toString();
+ addTorrentByFile(fileName, fileName.substring(fileName.lastIndexOf("/")));
+ } finally {
+ output.close();
+ }
+ } catch (SecurityException e) {
+ // No longer access to this file
+ Crouton.showText(this, R.string.error_torrentfile, navigationHelper.CROUTON_ERROR_STYLE);
+ } catch (IOException e1) {
+ // Can't write temporary file
+ Crouton.showText(this, R.string.error_torrentfile, navigationHelper.CROUTON_ERROR_STYLE);
+ } finally {
+ try {
+ if (input != null)
+ input.close();
+ } catch (IOException e) {
+ Crouton.showText(this, R.string.error_torrentfile, navigationHelper.CROUTON_ERROR_STYLE);
+ }
+ }
+ }
+
@Background
@Override
public void resumeTorrent(Torrent torrent) {
diff --git a/core/src/org/transdroid/core/app/search/BarcodeHelper.java b/core/src/org/transdroid/core/gui/search/BarcodeHelper.java
similarity index 91%
rename from core/src/org/transdroid/core/app/search/BarcodeHelper.java
rename to core/src/org/transdroid/core/gui/search/BarcodeHelper.java
index e504068d..ccf46913 100644
--- a/core/src/org/transdroid/core/app/search/BarcodeHelper.java
+++ b/core/src/org/transdroid/core/gui/search/BarcodeHelper.java
@@ -1,7 +1,7 @@
-package org.transdroid.core.app.search;
+package org.transdroid.core.gui.search;
import org.transdroid.core.R;
-import org.transdroid.core.gui.TorrentsActivity;
+import org.transdroid.core.app.search.GoogleWebSearchBarcodeResolver;
import android.app.AlertDialog;
import android.content.DialogInterface;
@@ -38,7 +38,8 @@ public class BarcodeHelper {
.setPositiveButton(android.R.string.yes, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- activity.startActivity(new Intent(Intent.ACTION_VIEW, SCANNER_MARKET_URI));
+ if (activity != null)
+ activity.startActivity(new Intent(Intent.ACTION_VIEW, SCANNER_MARKET_URI));
}
}).setNegativeButton(android.R.string.no, null).create();
};
@@ -54,7 +55,7 @@ public class BarcodeHelper {
* @return A String that can be used as new search query, or null if the bar code could not be scanned or no query
* can be constructed for it
*/
- public static String handleScanResult(TorrentsActivity activity, int resultCode, Intent data) {
+ public static String handleScanResult(int resultCode, Intent data) {
String contents = data.getStringExtra("SCAN_RESULT");
String formatName = data.getStringExtra("SCAN_RESULT_FORMAT");
if (formatName != null && formatName.equals("QR_CODE")) {
diff --git a/core/src/org/transdroid/core/gui/search/FilePickerHelper.java b/core/src/org/transdroid/core/gui/search/FilePickerHelper.java
new file mode 100644
index 00000000..de463505
--- /dev/null
+++ b/core/src/org/transdroid/core/gui/search/FilePickerHelper.java
@@ -0,0 +1,47 @@
+package org.transdroid.core.gui.search;
+
+import org.transdroid.core.R;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.net.Uri;
+import android.support.v4.app.DialogFragment;
+
+import com.actionbarsherlock.app.SherlockFragmentActivity;
+
+public class FilePickerHelper {
+
+ public static final int ACTIVITY_FILEPICKER = 0x0000c0df; // A 'random' ID to identify file picker intents
+ public static final Uri FILEMANAGER_MARKET_URI = Uri.parse("market://search?q=pname:org.openintents.filemanager");
+
+ /**
+ * Call this to start a file picker intent. The calling activity will receive an Intent result with ID
+ * {@link #ACTIVITY_FILEPICKER} with an Intent that contains the selected local file as data Intent.
+ * @param activity The calling activity, to which the result is returned or a dialog is bound that asks to install
+ * the file picker
+ */
+ public static void startFilePicker(final SherlockFragmentActivity activity) {
+ try {
+ // Start a file manager that can handle the PICK_FILE intent (specifically IO File Manager)
+ activity.startActivityForResult(new Intent("org.openintents.action.PICK_FILE"), ACTIVITY_FILEPICKER);
+ } catch (Exception e) {
+ // Can't start the file manager, for example with a SecurityException or when IO File Manager is not present
+ new DialogFragment() {
+ public android.app.Dialog onCreateDialog(android.os.Bundle savedInstanceState) {
+ return new AlertDialog.Builder(activity).setIcon(android.R.drawable.ic_dialog_alert)
+ .setMessage(activity.getString(R.string.search_filemanagernotfound))
+ .setPositiveButton(android.R.string.yes, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (activity != null)
+ activity.startActivity(new Intent(Intent.ACTION_VIEW, FILEMANAGER_MARKET_URI));
+ }
+ }).setNegativeButton(android.R.string.no, null).create();
+ };
+ }.show(activity.getSupportFragmentManager(), "installfilemanager");
+ }
+ }
+
+}
diff --git a/core/src/org/transdroid/core/gui/search/UrlEntryDialog.java b/core/src/org/transdroid/core/gui/search/UrlEntryDialog.java
new file mode 100644
index 00000000..db0f7eb4
--- /dev/null
+++ b/core/src/org/transdroid/core/gui/search/UrlEntryDialog.java
@@ -0,0 +1,39 @@
+package org.transdroid.core.gui.search;
+
+import org.transdroid.core.gui.TorrentsActivity;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.support.v4.app.DialogFragment;
+import android.text.InputType;
+import android.text.TextUtils;
+import android.widget.EditText;
+
+public class UrlEntryDialog {
+
+ /**
+ * Opens a dialog that allows entry of a single URL string, which (on confirmation) will be supplied to the calling
+ * activity's {@link TorrentsActivity#addTorrentByUrl(String, String) method}.
+ * @param activity The activity that opens (and owns) this dialog
+ */
+ public static void startUrlEntry(final TorrentsActivity activity) {
+ new DialogFragment() {
+ public android.app.Dialog onCreateDialog(android.os.Bundle savedInstanceState) {
+ final EditText urlInput = new EditText(activity);
+ urlInput.setInputType(InputType.TYPE_TEXT_VARIATION_URI);
+ return new AlertDialog.Builder(activity).setView(urlInput)
+ .setPositiveButton(android.R.string.ok, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // Assume text entry box input as URL and treat the filename (after the last /) as title
+ String url = urlInput.getText().toString();
+ if (activity != null && !TextUtils.isEmpty(url))
+ activity.addTorrentByUrl(url, url.substring(url.lastIndexOf("/")));
+ }
+ }).setNegativeButton(android.R.string.cancel, null).create();
+ };
+ }.show(activity.getSupportFragmentManager(), "urlentry");
+ }
+
+}