diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 97fa4d86a..e39145c3a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -26,10 +26,14 @@
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 0895ad430..680cd375d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -76,6 +76,8 @@
Getting application from
NFC is not enabled!
Go to NFC Settings…
+ No Bluetooth send method found, choose one!
+ Choose Bluetooth send method
Repository address
Fingerprint (optional)
@@ -92,6 +94,7 @@
Update Repos
Repositories
+ Bluetooth FDroid.apk…
Preferences
About
Search
diff --git a/src/org/fdroid/fdroid/FDroid.java b/src/org/fdroid/fdroid/FDroid.java
index eaf9db0ac..9156177b9 100644
--- a/src/org/fdroid/fdroid/FDroid.java
+++ b/src/org/fdroid/fdroid/FDroid.java
@@ -20,14 +20,18 @@
package org.fdroid.fdroid;
import android.annotation.TargetApi;
+import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.NotificationManager;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothManager;
import android.content.*;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.net.Uri;
@@ -44,6 +48,7 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
+import android.widget.Toast;
import org.fdroid.fdroid.compat.TabManager;
import org.fdroid.fdroid.data.AppProvider;
@@ -54,6 +59,7 @@ public class FDroid extends FragmentActivity {
public static final int REQUEST_APPDETAILS = 0;
public static final int REQUEST_MANAGEREPOS = 1;
public static final int REQUEST_PREFS = 2;
+ public static final int REQUEST_ENABLE_BLUETOOTH = 3;
public static final String EXTRA_TAB_UPDATE = "extraTab";
@@ -61,6 +67,10 @@ public class FDroid extends FragmentActivity {
private static final int PREFERENCES = Menu.FIRST + 1;
private static final int ABOUT = Menu.FIRST + 2;
private static final int SEARCH = Menu.FIRST + 3;
+ private static final int BLUETOOTH_APK = Menu.FIRST + 4;
+
+ /* request codes for Bluetooth flows */
+ private BluetoothAdapter mBluetoothAdapter = null;
private ViewPager viewPager;
@@ -101,6 +111,18 @@ public class FDroid extends FragmentActivity {
Uri uri = AppProvider.getContentUri();
getContentResolver().registerContentObserver(uri, true, new AppObserver());
+
+ getBluetoothAdapter();
+ }
+
+ @TargetApi(18)
+ private void getBluetoothAdapter() {
+ // to use the new, recommended way of getting the adapter
+ // http://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html
+ if (Build.VERSION.SDK_INT < 18)
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ else
+ mBluetoothAdapter = ((BluetoothManager) getSystemService(BLUETOOTH_SERVICE)).getAdapter();
}
@Override
@@ -125,6 +147,8 @@ public class FDroid extends FragmentActivity {
android.R.drawable.ic_menu_agenda);
MenuItem search = menu.add(Menu.NONE, SEARCH, 3, R.string.menu_search).setIcon(
android.R.drawable.ic_menu_search);
+ if (mBluetoothAdapter != null) // ignore on devices without Bluetooth
+ menu.add(Menu.NONE, BLUETOOTH_APK, 3, R.string.menu_send_apk_bt);
menu.add(Menu.NONE, PREFERENCES, 4, R.string.menu_preferences).setIcon(
android.R.drawable.ic_menu_preferences);
menu.add(Menu.NONE, ABOUT, 5, R.string.menu_about).setIcon(
@@ -152,6 +176,17 @@ public class FDroid extends FragmentActivity {
onSearchRequested();
return true;
+ case BLUETOOTH_APK:
+ /*
+ * If Bluetooth has not been enabled/turned on, then
+ * enabling device discoverability will automatically enable Bluetooth
+ */
+ Intent discoverBt = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
+ discoverBt.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 121);
+ startActivityForResult(discoverBt, REQUEST_ENABLE_BLUETOOTH);
+ // if this is successful, the Bluetooth transfer is started
+ return true;
+
case ABOUT:
View view = null;
if (Build.VERSION.SDK_INT >= 11) {
@@ -259,7 +294,47 @@ public class FDroid extends FragmentActivity {
overridePendingTransition(0, 0);
startActivity(intent);
}
-
+ break;
+ case REQUEST_ENABLE_BLUETOOTH:
+ if (resultCode == Activity.RESULT_CANCELED)
+ break;
+ String packageName = null;
+ String className = null;
+ boolean found = false;
+ Intent sendBt = null;
+ try {
+ PackageManager pm = getPackageManager();
+ ApplicationInfo appInfo = pm.getApplicationInfo("org.fdroid.fdroid",
+ PackageManager.GET_META_DATA);
+ sendBt = new Intent(Intent.ACTION_SEND);
+ // The APK type is blocked by stock Android, so use zip
+ // sendBt.setType("application/vnd.android.package-archive");
+ sendBt.setType("application/zip");
+ sendBt.putExtra(Intent.EXTRA_STREAM,
+ Uri.parse("file://" + appInfo.publicSourceDir));
+ // not all devices have the same Bluetooth Activities, so
+ // let's find it
+ for (ResolveInfo info : pm.queryIntentActivities(sendBt, 0)) {
+ packageName = info.activityInfo.packageName;
+ if (packageName.equals("com.android.bluetooth")
+ || packageName.equals("com.mediatek.bluetooth")) {
+ className = info.activityInfo.name;
+ found = true;
+ break;
+ }
+ }
+ } catch (NameNotFoundException e1) {
+ e1.printStackTrace();
+ found = false;
+ }
+ if (!found) {
+ Toast.makeText(this, R.string.bluetooth_activity_not_found,
+ Toast.LENGTH_SHORT).show();
+ startActivity(Intent.createChooser(sendBt, getString(R.string.choose_bt_send)));
+ } else {
+ sendBt.setClassName(packageName, className);
+ startActivity(sendBt);
+ }
break;
}
}