aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2014-09-24 14:45:51 +0200
committerDominik Schürmann <dominik@dominikschuermann.de>2014-09-24 14:45:51 +0200
commite3a185f698c157dd330a4e8f238b8e3ef20fd9a6 (patch)
treea1aea7c9cc161dc796a108380365db7a105435ea /OpenKeychain
parent5b0cc1fab4300faa2aab84c1f7a636462fa37a43 (diff)
downloadopen-keychain-e3a185f698c157dd330a4e8f238b8e3ef20fd9a6.tar.gz
open-keychain-e3a185f698c157dd330a4e8f238b8e3ef20fd9a6.tar.bz2
open-keychain-e3a185f698c157dd330a4e8f238b8e3ef20fd9a6.zip
propose apps in apps list
Diffstat (limited to 'OpenKeychain')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java167
-rw-r--r--OpenKeychain/src/main/res/layout/api_apps_adapter_list_item.xml11
-rw-r--r--OpenKeychain/src/main/res/raw/help_nfc_beam.html2
-rw-r--r--OpenKeychain/src/main/res/raw/help_start.html10
4 files changed, 155 insertions, 35 deletions
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<Cursor> 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<Cursor> 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<Cursor> 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);
}
}
diff --git a/OpenKeychain/src/main/res/layout/api_apps_adapter_list_item.xml b/OpenKeychain/src/main/res/layout/api_apps_adapter_list_item.xml
index 543f7d675..b67da13a6 100644
--- a/OpenKeychain/src/main/res/layout/api_apps_adapter_list_item.xml
+++ b/OpenKeychain/src/main/res/layout/api_apps_adapter_list_item.xml
@@ -23,4 +23,15 @@
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/api_apps_adapter_item_icon" />
+ <ImageView
+ android:id="@+id/api_apps_adapter_install_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_action_download"
+ android:layout_centerVertical="true"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentEnd="true"
+ android:padding="8dp" />
+
+
</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/raw/help_nfc_beam.html b/OpenKeychain/src/main/res/raw/help_nfc_beam.html
index f3bb9d16e..30060a897 100644
--- a/OpenKeychain/src/main/res/raw/help_nfc_beam.html
+++ b/OpenKeychain/src/main/res/raw/help_nfc_beam.html
@@ -7,7 +7,7 @@ And don't add newlines before or after p tags because of transifex -->
<body>
<h2>How to receive keys</h2>
<ol>
-<li>Go to your partners contacts and open the contact you want to share.</li>
+<li>Go to your partners keys and open the key you want to share.</li>
<li>Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.</li>
<li>After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.</li>
<li>Tap the card and the content will then load on the your device.</li>
diff --git a/OpenKeychain/src/main/res/raw/help_start.html b/OpenKeychain/src/main/res/raw/help_start.html
index 58d1340c9..d54780491 100644
--- a/OpenKeychain/src/main/res/raw/help_start.html
+++ b/OpenKeychain/src/main/res/raw/help_start.html
@@ -6,15 +6,9 @@ And don't add newlines before or after p tags because of transifex -->
</head>
<body>
<h2>Getting started</h2>
-<p>First you need a personal secret key. Create one via the option menus in "Keys" or import existing secret keys. Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
+<p>First you need a personal key. Create one via the menu in "Keys" or import existing secret keys. Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
-<p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
-
-<h2>Applications</h2>
-<p>Several applications support OpenKeychain to encrypt/sign your private communication:
-<br/><img src="apps_k9"/><br/>K-9 Mail: OpenKeychain support available in current <a href="https://github.com/k9mail/k-9/releases/tag/4.904">alpha build</a>!
-<br/><a href="market://details?id=eu.siacs.conversations"><img src="apps_conversations"/><br/>Conversations</a>: Jabber/XMPP client
-<br/><a href="market://details?id=org.lf_net.pgpunlocker"><img src="apps_pgpauth"/><br/>PGPAuth</a>: App to send a PGP-signed request to a server to open or close something, e.g. a door</p>
+<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection. To share via QR Codes install <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
<h2>I found a bug in OpenKeychain!</h2>
<p>Please report the bug using the <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">issue tracker of OpenKeychain</a>.</p>