updates to sample plugin and PluginSDK

This commit is contained in:
Philipp Crocoll 2014-06-05 21:37:17 +02:00
parent e9d4c0d185
commit d0a4803de1
9 changed files with 146 additions and 31 deletions

View File

@ -2,6 +2,7 @@ package keepass2android.pluginsdk;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import org.json.JSONArray;
import org.json.JSONException;
@ -71,5 +72,40 @@ public class Kp2aControl {
i.putExtra(Strings.EXTRA_QUERY_STRING, searchText);
return i;
}
/**
* Creates an intent to query a password entry from KP2A, matching to the current app's package .
* The credentials are returned as Activity result.
* This requires SCOPE_QUERY_CREDENTIALS_FOR_OWN_PACKAGE.
* @return an Intent to start KP2A with
*/
public static Intent getQueryEntryIntentForOwnPackage()
{
return new Intent(Strings.ACTION_QUERY_CREDENTIALS_FOR_OWN_PACKAGE);
}
/**
* Converts the entry fields returned in an intent from a query to a hashmap.
* @param intent data received in onActivityResult after getQueryEntryIntent(ForOwnPackage)
* @return HashMap with keys = field names (see KeepassDefs for standard keys) and values = values
*/
public static HashMap<String, String> getEntryFieldsFromIntent(Intent intent)
{
HashMap<String, String> res = new HashMap<String, String>();
try {
JSONObject json = new JSONObject(intent.getStringExtra(Strings.EXTRA_ENTRY_OUTPUT_DATA));
for(Iterator<String> iter = json.keys();iter.hasNext();) {
String key = iter.next();
String value = json.get(key).toString();
res.put(key, value);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
return res;
}
}

View File

@ -28,7 +28,6 @@
<action android:name="keepass2android.ACTION_TRIGGER_REQUEST_ACCESS" />
<action android:name="keepass2android.ACTION_RECEIVE_ACCESS" />
<action android:name="keepass2android.ACTION_REVOKE_ACCESS" />
</intent-filter>
</receiver>

View File

@ -31,7 +31,9 @@ public final class R {
public static final int ic_launcher=0x7f020000;
}
public static final class id {
public static final int action_settings=0x7f080001;
public static final int action_settings=0x7f080003;
public static final int btnAdd=0x7f080001;
public static final int btnQuery=0x7f080002;
public static final int container=0x7f080000;
}
public static final class layout {

View File

@ -8,9 +8,18 @@
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="keepass2android.plugina.PlugInA$PlaceholderFragment" >
<TextView
<Button
android:id="@+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
android:text="add credentials to KP2A"/>
<Button
android:id="@+id/btnQuery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="query credentials for this package"
android:layout_below="@id/btnAdd"
/>
</RelativeLayout>

View File

@ -1,13 +1,21 @@
package keepass2android.plugina;
import java.util.ArrayList;
import java.util.HashMap;
import keepass2android.pluginsdk.KeepassDefs;
import keepass2android.pluginsdk.Kp2aControl;
import android.app.Activity;
import android.app.Fragment;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.os.Build;
import android.widget.Toast;
public class PlugInA extends Activity {
@ -47,6 +55,8 @@ public class PlugInA extends Activity {
*/
public static class PlaceholderFragment extends Fragment {
private static final String PLUGIN_A_PASSPHRASE = "PluginA passphrase";
public PlaceholderFragment() {
}
@ -55,8 +65,83 @@ public class PlugInA extends Activity {
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_plug_in,
container, false);
rootView.findViewById(R.id.btnQuery).setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
try {
PlaceholderFragment.this.startActivityForResult(
Kp2aControl
.getQueryEntryIntentForOwnPackage(),
1);
} catch (ActivityNotFoundException e) {
Toast.makeText(
PlaceholderFragment.this.getActivity(),
"no KP2A host app found",
Toast.LENGTH_SHORT).show();
}
}
});
rootView.findViewById(R.id.btnAdd).setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
try {
HashMap<String, String> fields = new HashMap<String, String>();
//standard fields
fields.put(KeepassDefs.TitleField, "plugin A");
fields.put(KeepassDefs.UserNameField, "John Doe");
fields.put(KeepassDefs.PasswordField, "top secret");
//associate entry with our app. If we would require the URL field for a web URL,
//this string could be added in any other (e.g. a custom) field
fields.put(KeepassDefs.UrlField, "androidapp://"+getActivity().getPackageName());
//custom field:
fields.put(PLUGIN_A_PASSPHRASE, "some long text");
//mark custom field as protected (i.e. display masked, enable memory protection in Keepass2)
ArrayList<String> protectedFields = new ArrayList<String>();
protectedFields.add(PLUGIN_A_PASSPHRASE);
//add to KP2A
PlaceholderFragment.this.startActivityForResult(
Kp2aControl
.getAddEntryIntent(fields, protectedFields),
2);
} catch (ActivityNotFoundException e) {
Toast.makeText(
PlaceholderFragment.this.getActivity(),
"no KP2A host app found",
Toast.LENGTH_SHORT).show();
}
}
});
return rootView;
}
@Override
public void onActivityResult(int requestCode, int resultCode,
Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((requestCode == 1) //queryEntry for own package
&& (resultCode == RESULT_OK)) // ensure user granted access and selected something
{
HashMap<String, String> credentials = Kp2aControl.getEntryFieldsFromIntent(data);
if (!credentials.isEmpty())
{
//here we go!
Toast.makeText(getActivity(), "retrieved credenitals! Username="+credentials.get(KeepassDefs.UserNameField), Toast.LENGTH_LONG).show();
}
}
}
}
}

View File

@ -13,6 +13,7 @@ public class PluginAAccessReceiver
ArrayList<String> scopes = new ArrayList<String>();
scopes.add(Strings.SCOPE_DATABASE_ACTIONS);
scopes.add(Strings.SCOPE_CURRENT_ENTRY);
scopes.add(Strings.SCOPE_QUERY_CREDENTIALS_FOR_OWN_PACKAGE);
return scopes;
}

File diff suppressed because one or more lines are too long

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="keepass2android.plugin.qr"
android:versionCode="1"
android:versionName="1.0" >
android:versionCode="2"
android:versionName="1.0.1" >
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission
@ -10,10 +10,10 @@
android:permissionGroup="android.permission-group.HARDWARE_CONTROLS"
android:protectionLevel="normal" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<uses-feature android:name="android.hardware.camera.flash" android:required="false"/>
<uses-feature android:name="android.hardware.screen.portrait" android:required="false"/>
<uses-sdk
android:minSdkVersion="14"

View File

@ -12,6 +12,7 @@ import org.json.JSONObject;
import keepass2android.pluginsdk.AccessManager;
import keepass2android.pluginsdk.KeepassDefs;
import keepass2android.pluginsdk.Kp2aControl;
import keepass2android.pluginsdk.Strings;
import com.google.zxing.BarcodeFormat;
@ -65,8 +66,7 @@ public class QRActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if ((getIntent() != null) && (getIntent().getStringExtra(Strings.EXTRA_ENTRY_OUTPUT_DATA)!= null))
setContentView(R.layout.activity_qr);
setContentView(R.layout.activity_qr);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
@ -118,24 +118,7 @@ public class QRActivity extends Activity {
public PlaceholderFragment() {
}
protected HashMap<String, String> getEntryFieldsFromIntent(Intent intent)
{
HashMap<String, String> res = new HashMap<String, String>();
try {
JSONObject json = new JSONObject(intent.getStringExtra(Strings.EXTRA_ENTRY_OUTPUT_DATA));
for(Iterator<String> iter = json.keys();iter.hasNext();) {
String key = iter.next();
String value = json.get(key).toString();
res.put(key, value);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
return res;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
@ -145,7 +128,7 @@ public class QRActivity extends Activity {
mSpinner = (Spinner) rootView.findViewById(R.id.spinner);
mEntryOutput = getEntryFieldsFromIntent(getActivity().getIntent());
mEntryOutput = Kp2aControl.getEntryFieldsFromIntent(getActivity().getIntent());
mProtectedFieldsList = getProtectedFieldsList(getActivity().getIntent());
ArrayList<String> spinnerItems = new ArrayList<String>();