From e3a185f698c157dd330a4e8f238b8e3ef20fd9a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 24 Sep 2014 14:45:51 +0200 Subject: propose apps in apps list --- .../keychain/remote/ui/AppsListFragment.java | 167 +++++++++++++++++---- 1 file changed, 141 insertions(+), 26 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java index 61a991376..65ea9ec70 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java @@ -17,13 +17,14 @@ package org.sufficientlysecure.keychain.remote.ui; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.database.Cursor; +import android.database.CursorJoiner; import android.database.MatrixCursor; -import android.database.MergeCursor; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.ListFragment; @@ -56,11 +57,23 @@ public class AppsListFragment extends ListFragment implements getListView().setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView adapterView, View view, int position, long id) { + boolean isInstalled = mAdapter.getItemIsInstalled(position); String selectedPackageName = mAdapter.getItemPackageName(position); - // edit app settings - Intent intent = new Intent(getActivity(), AppSettingsActivity.class); - intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(selectedPackageName)); - startActivity(intent); + + if (isInstalled) { + // edit app settings + Intent intent = new Intent(getActivity(), AppSettingsActivity.class); + intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(selectedPackageName)); + startActivity(intent); + } else { + try { + startActivity(new Intent(Intent.ACTION_VIEW, + Uri.parse("market://details?id=" + selectedPackageName))); + } catch (ActivityNotFoundException anfe) { + startActivity(new Intent(Intent.ACTION_VIEW, + Uri.parse("http://play.google.com/store/apps/details?id=" + selectedPackageName))); + } + } } }); @@ -80,12 +93,22 @@ public class AppsListFragment extends ListFragment implements getLoaderManager().initLoader(0, null, this); } + private static final String TEMP_COLUMN_INSTALLED = "INSTALLED"; + private static final String TEMP_COLUMN_NAME = "NAME"; + // These are the Contacts rows that we will retrieve. static final String[] PROJECTION = new String[]{ ApiApps._ID, // 0 - ApiApps.PACKAGE_NAME // 1 + ApiApps.PACKAGE_NAME, // 1 + "0 as " + TEMP_COLUMN_INSTALLED, // changed later in cursor joiner + "null as " + TEMP_COLUMN_NAME // installed apps can retrieve app name from Android OS }; + private static final int INDEX_ID = 0; + private static final int INDEX_PACKAGE_NAME = 1; + private static final int INDEX_INSTALLED = 2; + private static final int INDEX_NAME = 3; + public Loader onCreateLoader(int id, Bundle args) { // This is called when a new Loader needs to be created. This // sample only has one Loader, so we don't care about the ID. @@ -100,18 +123,89 @@ public class AppsListFragment extends ListFragment implements } public void onLoadFinished(Loader loader, Cursor data) { - MatrixCursor matrixCursor = new MatrixCursor( - new String[]{ApiApps._ID, ApiApps.PACKAGE_NAME, ApiApps.PACKAGE_SIGNATURE} - ); - matrixCursor.addRow(new Object[]{200, "com.fsck.k9", new byte[]{}}); + MatrixCursor availableAppsCursor = new MatrixCursor(new String[]{ + ApiApps._ID, + ApiApps.PACKAGE_NAME, + TEMP_COLUMN_INSTALLED, + TEMP_COLUMN_NAME + }); + availableAppsCursor.addRow(new Object[]{1, "com.fsck.k9", 0, "K-9 Mail"}); + availableAppsCursor.addRow(new Object[]{1, "eu.siacs.conversations", 0, "Conversations (Instant Messaging)"}); +// availableAppsCursor.addRow(new Object[]{1, "org.sufficientlysecure.keychain.demo", 0, "API Example"}); + + MatrixCursor mergedCursor = new MatrixCursor(new String[]{ + ApiApps._ID, + ApiApps.PACKAGE_NAME, + TEMP_COLUMN_INSTALLED, + TEMP_COLUMN_NAME + }); + + CursorJoiner joiner = new CursorJoiner( + availableAppsCursor, + new String[]{ApiApps.PACKAGE_NAME}, + data, + new String[]{ApiApps.PACKAGE_NAME}); + for (CursorJoiner.Result joinerResult : joiner) { + switch (joinerResult) { + case LEFT: { + // handle case where a row in cursorA is unique + mergedCursor.addRow(new Object[]{ + availableAppsCursor.getLong(INDEX_ID), + availableAppsCursor.getString(INDEX_PACKAGE_NAME), + availableAppsCursor.getInt(INDEX_INSTALLED), + availableAppsCursor.getString(INDEX_NAME) + }); + break; + } + case RIGHT: { + // handle case where a row in cursorB is unique + String packageName = data.getString(INDEX_PACKAGE_NAME); + int installed; + try { + getActivity().getPackageManager().getApplicationInfo(packageName, 0); + installed = 1; + } catch (final PackageManager.NameNotFoundException e) { + installed = 0; + } + + mergedCursor.addRow(new Object[]{ + data.getLong(INDEX_ID), + packageName, + installed, + null + }); + break; + } + case BOTH: { + // handle case where a row with the same key is in both cursors + String packageName = data.getString(INDEX_PACKAGE_NAME); + String name; + int installed; + try { + getActivity().getPackageManager().getApplicationInfo(packageName, 0); + installed = 1; + name = data.getString(INDEX_NAME); + } catch (final PackageManager.NameNotFoundException e) { + installed = 0; + // if not installed take name from available apps list + name = availableAppsCursor.getString(INDEX_NAME); + } + + mergedCursor.addRow(new Object[]{ + data.getLong(INDEX_ID), + packageName, + installed, + name + }); + break; + } + } + } - MergeCursor mergeCursor = new MergeCursor( - new Cursor[]{matrixCursor, data} - ); // Swap the new cursor in. (The framework will take care of closing the // old cursor once we return.) - mAdapter.swapCursor(mergeCursor); + mAdapter.swapCursor(mergedCursor); } public void onLoaderReset(Loader loader) { @@ -143,7 +237,7 @@ public class AppsListFragment extends ListFragment implements public String getItemPackageName(int position) { if (mDataValid && mCursor != null) { if (mCursor.moveToPosition(position)) { - return mCursor.getString(1); + return mCursor.getString(INDEX_PACKAGE_NAME); } else { return null; } @@ -152,26 +246,47 @@ public class AppsListFragment extends ListFragment implements } } + public boolean getItemIsInstalled(int position) { + if (mDataValid && mCursor != null) { + if (mCursor.moveToPosition(position)) { + return (mCursor.getInt(INDEX_INSTALLED) == 1); + } else { + return false; + } + } else { + return false; + } + } + @Override public void bindView(View view, Context context, Cursor cursor) { TextView text = (TextView) view.findViewById(R.id.api_apps_adapter_item_name); ImageView icon = (ImageView) view.findViewById(R.id.api_apps_adapter_item_icon); + ImageView installIcon = (ImageView) view.findViewById(R.id.api_apps_adapter_install_icon); + + String packageName = cursor.getString(INDEX_PACKAGE_NAME); + int installed = cursor.getInt(INDEX_INSTALLED); + String name = cursor.getString(INDEX_NAME); - String packageName = cursor.getString(cursor.getColumnIndex(ApiApps.PACKAGE_NAME)); - if (packageName != null) { - // get application name - try { - ApplicationInfo ai = mPM.getApplicationInfo(packageName, 0); + // get application name and icon + try { + ApplicationInfo ai = mPM.getApplicationInfo(packageName, 0); - text.setText(mPM.getApplicationLabel(ai)); - icon.setImageDrawable(mPM.getApplicationIcon(ai)); - } catch (final PackageManager.NameNotFoundException e) { - // fallback + text.setText(mPM.getApplicationLabel(ai)); + icon.setImageDrawable(mPM.getApplicationIcon(ai)); + } catch (final PackageManager.NameNotFoundException e) { + // fallback + if (name == null) { text.setText(packageName); + } else { + text.setText(name); } + } + + if (installed == 1) { + installIcon.setVisibility(View.GONE); } else { - // fallback - text.setText("No Name"); + installIcon.setVisibility(View.VISIBLE); } } -- cgit v1.2.3