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; } }