diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 9c9a599c4..61014ce33 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -197,6 +197,14 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/menu/select_local_apps_action_mode.xml b/res/menu/select_local_apps_action_mode.xml
new file mode 100644
index 000000000..2550ebcfe
--- /dev/null
+++ b/res/menu/select_local_apps_action_mode.xml
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/res/menu/select_local_apps_activity.xml b/res/menu/select_local_apps_activity.xml
new file mode 100644
index 000000000..0d2d96089
--- /dev/null
+++ b/res/menu/select_local_apps_activity.xml
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index bc21277de..ae4f18a66 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -157,12 +157,15 @@
Setup Local Repo
Touch to setup your local repo.
Updating…
+ Update Repo
Deleting current repo…
Adding %s to repo…
Writing raw index file (index.xml)…
Linking APKs into the repo…
Copying app icons into the repo…
Finished updating local repo
+ No applications found
+ icon
Fingerprint:
WiFi Network:
Enable WiFi
diff --git a/src/org/fdroid/fdroid/FDroidApp.java b/src/org/fdroid/fdroid/FDroidApp.java
index 1b5bfcf35..d88aae18c 100644
--- a/src/org/fdroid/fdroid/FDroidApp.java
+++ b/src/org/fdroid/fdroid/FDroidApp.java
@@ -85,7 +85,7 @@ public class FDroidApp extends Application {
public static String bssid = "";
public static Repo repo = new Repo();
public static LocalRepoManager localRepo = null;
- static Set selectedApps = new HashSet();
+ public static Set selectedApps = new HashSet();
private static Messenger localRepoServiceMessenger = null;
private static boolean localRepoServiceIsBound = false;
diff --git a/src/org/fdroid/fdroid/views/LocalRepoActivity.java b/src/org/fdroid/fdroid/views/LocalRepoActivity.java
index 498fd000d..4b87f4d39 100644
--- a/src/org/fdroid/fdroid/views/LocalRepoActivity.java
+++ b/src/org/fdroid/fdroid/views/LocalRepoActivity.java
@@ -36,6 +36,7 @@ public class LocalRepoActivity extends Activity {
private ToggleButton repoSwitch;
private int SET_IP_ADDRESS = 7345;
+ private int UPDATE_REPO = 7346;
/** Called when the activity is first created. */
@Override
@@ -106,11 +107,7 @@ public class LocalRepoActivity extends Activity {
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_setup_repo:
- setUIFromWifi();
- String[] packages = new String[2];
- packages[0] = getPackageName();
- packages[1] = "com.android.bluetooth";
- new UpdateAsyncTask(this, packages).execute();
+ startActivityForResult(new Intent(this, SelectLocalAppsActivity.class), UPDATE_REPO);
return true;
case R.id.menu_send_fdroid_via_wifi:
startActivity(new Intent(this, QrWizardWifiNetworkActivity.class));
@@ -128,6 +125,10 @@ public class LocalRepoActivity extends Activity {
return;
if (requestCode == SET_IP_ADDRESS) {
setUIFromWifi();
+ } else if (requestCode == UPDATE_REPO) {
+ setUIFromWifi();
+ new UpdateAsyncTask(this, FDroidApp.selectedApps.toArray(new String[0]))
+ .execute();
}
}
diff --git a/src/org/fdroid/fdroid/views/SelectLocalAppsActivity.java b/src/org/fdroid/fdroid/views/SelectLocalAppsActivity.java
new file mode 100644
index 000000000..ff0ad5445
--- /dev/null
+++ b/src/org/fdroid/fdroid/views/SelectLocalAppsActivity.java
@@ -0,0 +1,89 @@
+
+package org.fdroid.fdroid.views;
+
+import android.annotation.TargetApi;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.view.ActionMode;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+import org.fdroid.fdroid.PreferencesActivity;
+import org.fdroid.fdroid.R;
+import org.fdroid.fdroid.views.fragments.SelectLocalAppsFragment;
+
+@TargetApi(11)
+// TODO replace with appcompat-v7
+public class SelectLocalAppsActivity extends FragmentActivity {
+ private static final String TAG = "SelectLocalAppsActivity";
+ private SelectLocalAppsFragment selectLocalAppsFragment = null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.select_local_apps_activity);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ if (selectLocalAppsFragment == null)
+ selectLocalAppsFragment = (SelectLocalAppsFragment) getSupportFragmentManager().findFragmentById(
+ R.id.fragment_app_list);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.select_local_apps_activity, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ setResult(RESULT_CANCELED);
+ finish();
+ return true;
+ case R.id.action_settings:
+ startActivity(new Intent(this, PreferencesActivity.class));
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ public ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
+
+ @Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ MenuInflater inflater = mode.getMenuInflater();
+ inflater.inflate(R.menu.select_local_apps_action_mode, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ return false; // Return false if nothing is done
+ }
+
+ @Override
+ public boolean onActionItemClicked(final ActionMode mode, MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.action_update_repo:
+ setResult(RESULT_OK);
+ finish();
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ public void onDestroyActionMode(ActionMode mode) {
+ setResult(RESULT_CANCELED);
+ finish();
+ }
+ };
+}
diff --git a/src/org/fdroid/fdroid/views/fragments/SelectLocalAppsFragment.java b/src/org/fdroid/fdroid/views/fragments/SelectLocalAppsFragment.java
new file mode 100644
index 000000000..9eff92157
--- /dev/null
+++ b/src/org/fdroid/fdroid/views/fragments/SelectLocalAppsFragment.java
@@ -0,0 +1,134 @@
+/*
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.fdroid.fdroid.views.fragments;
+
+import android.annotation.TargetApi;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.support.v4.app.ListFragment;
+import android.support.v4.app.LoaderManager.LoaderCallbacks;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
+import android.support.v4.widget.SimpleCursorAdapter;
+import android.text.TextUtils;
+import android.view.ActionMode;
+import android.view.View;
+import android.widget.ListView;
+
+import org.fdroid.fdroid.FDroidApp;
+import org.fdroid.fdroid.R;
+import org.fdroid.fdroid.data.InstalledAppProvider;
+import org.fdroid.fdroid.data.InstalledAppProvider.DataColumns;
+import org.fdroid.fdroid.views.SelectLocalAppsActivity;
+
+public class SelectLocalAppsFragment extends ListFragment implements LoaderCallbacks {
+
+ private SelectLocalAppsActivity selectLocalAppsActivity;
+ private ActionMode mActionMode = null;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @TargetApi(11)
+ // TODO replace with appcompat-v7
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ setEmptyText(getString(R.string.no_applications_found));
+
+ selectLocalAppsActivity = (SelectLocalAppsActivity) getActivity();
+ ListView listView = getListView();
+ listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+ SimpleCursorAdapter adapter = new SimpleCursorAdapter(getActivity(),
+ android.R.layout.simple_list_item_activated_1,
+ null,
+ new String[] {
+ InstalledAppProvider.DataColumns.APP_ID,
+ },
+ new int[] {
+ android.R.id.text1,
+ },
+ 0);
+ setListAdapter(adapter);
+ setListShown(false);
+
+ // either reconnect with an existing loader or start a new one
+ getLoaderManager().initLoader(0, null, this);
+ }
+
+ @TargetApi(11)
+ // TODO replace with appcompat-v7
+ @Override
+ public void onListItemClick(ListView l, View v, int position, long id) {
+ if (mActionMode == null)
+ mActionMode = selectLocalAppsActivity
+ .startActionMode(selectLocalAppsActivity.mActionModeCallback);
+ Cursor cursor = (Cursor) l.getAdapter().getItem(position);
+ String packageName = cursor.getString(1);
+ if (FDroidApp.selectedApps.contains(packageName)) {
+ FDroidApp.selectedApps.remove(packageName);
+ } else {
+ FDroidApp.selectedApps.add(packageName);
+ }
+ }
+
+ @Override
+ public CursorLoader onCreateLoader(int id, Bundle args) {
+ CursorLoader loader = new CursorLoader(
+ this.getActivity(),
+ InstalledAppProvider.getContentUri(),
+ InstalledAppProvider.DataColumns.ALL,
+ null,
+ null,
+ InstalledAppProvider.DataColumns.APP_ID);
+ return loader;
+ }
+
+ @Override
+ public void onLoadFinished(Loader loader, Cursor cursor) {
+ ((SimpleCursorAdapter) this.getListAdapter()).swapCursor(cursor);
+
+ ListView listView = getListView();
+ int count = listView.getCount();
+ String fdroid = loader.getContext().getPackageName();
+ for (int i = 0; i < count; i++) {
+ Cursor c = ((Cursor) listView.getItemAtPosition(i));
+ String packageName = c.getString(c.getColumnIndex(DataColumns.APP_ID));
+ if (TextUtils.equals(packageName, fdroid)) {
+ listView.setItemChecked(i, true);
+ } else {
+ for (String selected : FDroidApp.selectedApps) {
+ if (TextUtils.equals(packageName, selected)) {
+ listView.setItemChecked(i, true);
+ }
+ }
+ }
+ }
+
+ if (isResumed()) {
+ setListShown(true);
+ } else {
+ setListShownNoAnimation(true);
+ }
+ }
+
+ @Override
+ public void onLoaderReset(Loader loader) {
+ ((SimpleCursorAdapter) this.getListAdapter()).swapCursor(null);
+ }
+}