diff --git a/android/res/layout/app_picker_list_item.xml b/android/res/layout/app_picker_list_item.xml new file mode 100644 index 000000000..3b7927cbe --- /dev/null +++ b/android/res/layout/app_picker_list_item.xml @@ -0,0 +1,21 @@ + + + + + + + + diff --git a/android/res/layout/bookmark_picker_list_item.xml b/android/res/layout/bookmark_picker_list_item.xml index 05c99ac2d..5122461c3 100644 --- a/android/res/layout/bookmark_picker_list_item.xml +++ b/android/res/layout/bookmark_picker_list_item.xml @@ -24,11 +24,13 @@ diff --git a/android/src/com/google/zxing/client/android/share/AppInfo.java b/android/src/com/google/zxing/client/android/share/AppInfo.java new file mode 100644 index 000000000..393408674 --- /dev/null +++ b/android/src/com/google/zxing/client/android/share/AppInfo.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2013 ZXing authors + * + * 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 com.google.zxing.client.android.share; + +import android.graphics.drawable.Drawable; + +final class AppInfo implements Comparable { + + private final String packageName; + private final String label; + private final Drawable icon; + + AppInfo(String packageName, String label, Drawable icon) { + this.packageName = packageName; + this.label = label; + this.icon = icon; + } + + String getPackageName() { + return packageName; + } + + String getLabel() { + return label; + } + + Drawable getIcon() { + return icon; + } + + @Override + public String toString() { + return label; + } + + @Override + public int compareTo(AppInfo another) { + return label.compareTo(another.label); + } + + @Override + public int hashCode() { + return label.hashCode(); + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof AppInfo)) { + return false; + } + AppInfo another = (AppInfo) other; + return label.equals(another.label); + } + +} diff --git a/android/src/com/google/zxing/client/android/share/AppPickerActivity.java b/android/src/com/google/zxing/client/android/share/AppPickerActivity.java index 0bfa89002..86ff9ce45 100644 --- a/android/src/com/google/zxing/client/android/share/AppPickerActivity.java +++ b/android/src/com/google/zxing/client/android/share/AppPickerActivity.java @@ -26,16 +26,17 @@ import com.google.zxing.client.android.common.executor.AsyncTaskExecInterface; import com.google.zxing.client.android.common.executor.AsyncTaskExecManager; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public final class AppPickerActivity extends ListActivity { - private final List labelsPackages; + private final List labelsPackages; private LoadPackagesAsyncTask backgroundTask; private final AsyncTaskExecInterface taskExec; public AppPickerActivity() { - labelsPackages = new ArrayList(); + labelsPackages = Collections.synchronizedList(new ArrayList()); taskExec = new AsyncTaskExecManager().build(); } @@ -60,13 +61,13 @@ public final class AppPickerActivity extends ListActivity { @Override protected void onListItemClick(ListView l, View view, int position, long id) { if (position >= 0 && position < labelsPackages.size()) { - String url = "market://details?id=" + labelsPackages.get(position)[1]; + String packageName = labelsPackages.get(position).getPackageName(); Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); - intent.putExtra(Browser.BookmarkColumns.URL, url); + intent.putExtra(Browser.BookmarkColumns.URL, "market://details?id=" + packageName); setResult(RESULT_OK, intent); } else { - setResult(RESULT_CANCELED); + setResult(RESULT_CANCELED); } finish(); } diff --git a/android/src/com/google/zxing/client/android/share/LoadPackagesAsyncTask.java b/android/src/com/google/zxing/client/android/share/LoadPackagesAsyncTask.java index 9f9850a18..d4a519b94 100644 --- a/android/src/com/google/zxing/client/android/share/LoadPackagesAsyncTask.java +++ b/android/src/com/google/zxing/client/android/share/LoadPackagesAsyncTask.java @@ -16,16 +16,19 @@ package com.google.zxing.client.android.share; +import android.app.ListActivity; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.graphics.drawable.Drawable; import android.os.AsyncTask; +import android.view.View; +import android.view.ViewGroup; import android.widget.ArrayAdapter; +import android.widget.ImageView; import android.widget.ListAdapter; +import com.google.zxing.client.android.R; -import java.io.Serializable; -import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.List; /** @@ -33,7 +36,7 @@ import java.util.List; * * @author Sean Owen */ -final class LoadPackagesAsyncTask extends AsyncTask,Object,List> { +final class LoadPackagesAsyncTask extends AsyncTask,Object,List> { private static final String[] PKG_PREFIX_WHITELIST = { "com.google.android.apps.", @@ -45,27 +48,30 @@ final class LoadPackagesAsyncTask extends AsyncTask,Object,List doInBackground(List... objects) { - List labelsPackages = objects[0]; + protected List doInBackground(List... objects) { + List labelsPackages = objects[0]; PackageManager packageManager = activity.getPackageManager(); List appInfos = packageManager.getInstalledApplications(0); for (ApplicationInfo appInfo : appInfos) { - CharSequence label = appInfo.loadLabel(packageManager); - if (label != null) { - String packageName = appInfo.packageName; - if (!isHidden(packageName)) { - labelsPackages.add(new String[]{label.toString(), packageName}); + String packageName = appInfo.packageName; + if (!isHidden(packageName)) { + CharSequence label = appInfo.loadLabel(packageManager); + Drawable icon = appInfo.loadIcon(packageManager); + if (label != null) { + labelsPackages.add(new AppInfo(packageName, label.toString(), icon)); } } } - Collections.sort(labelsPackages, new ByFirstStringComparator()); + synchronized (labelsPackages) { + Collections.sort(labelsPackages); + } return labelsPackages; } @@ -87,21 +93,22 @@ final class LoadPackagesAsyncTask extends AsyncTask,Object,List results) { - List labels = new ArrayList(results.size()); - for (String[] result : results) { - labels.add(result[0]); - } - ListAdapter listAdapter = new ArrayAdapter(activity, - android.R.layout.simple_list_item_1, labels); + protected void onPostExecute(final List results) { + ListAdapter listAdapter = new ArrayAdapter(activity, + R.layout.app_picker_list_item, + R.id.app_picker_list_item_label, + results) { + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View view = super.getView(position, convertView, parent); + Drawable icon = results.get(position).getIcon(); + if (icon != null) { + ((ImageView) view.findViewById(R.id.app_picker_list_item_icon)).setImageDrawable(icon); + } + return view; + } + }; activity.setListAdapter(listAdapter); } - private static final class ByFirstStringComparator implements Comparator, Serializable { - @Override - public int compare(String[] o1, String[] o2) { - return o1[0].compareTo(o2[0]); - } - } - }