mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-27 19:22:14 -05:00
Merge branch 'master' of https://github.com/openpgp-keychain/openpgp-keychain
This commit is contained in:
commit
1e565ef872
@ -652,12 +652,18 @@ public class KeychainIntentService extends IntentService implements ProgressDial
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case TARGET_FILE: /* import key from file */
|
case TARGET_FILE: /* import key from file */
|
||||||
String inputFile = data.getString(IMPORT_FILENAME);
|
// dataUri!
|
||||||
|
|
||||||
|
try {
|
||||||
|
inStream = getContentResolver().openInputStream(dataUri);
|
||||||
|
inLength = inStream.available();
|
||||||
|
|
||||||
inStream = new FileInputStream(inputFile);
|
|
||||||
File file = new File(inputFile);
|
|
||||||
inLength = file.length();
|
|
||||||
inputData = new InputData(inStream, inLength);
|
inputData = new InputData(inStream, inLength);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
Log.e(Constants.TAG, "FileNotFoundException!", e);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(Constants.TAG, "IOException!", e);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -23,11 +23,10 @@ import java.util.Locale;
|
|||||||
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||||
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
|
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
|
||||||
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
|
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
|
||||||
import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment;
|
|
||||||
import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment;
|
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
@ -72,8 +71,9 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
|
|||||||
|
|
||||||
// only used by ACTION_IMPORT_KEY_FROM_KEYSERVER
|
// only used by ACTION_IMPORT_KEY_FROM_KEYSERVER
|
||||||
public static final String EXTRA_QUERY = "query";
|
public static final String EXTRA_QUERY = "query";
|
||||||
|
public static final String EXTRA_KEY_ID = "key_id";
|
||||||
protected boolean mDeleteAfterImport = false;
|
public static final String EXTRA_FINGERPRINT = "fingerprint";
|
||||||
|
// public static final String RESULT_EXTRA_TEXT = "text";
|
||||||
|
|
||||||
// view
|
// view
|
||||||
private ImportKeysListFragment mListFragment;
|
private ImportKeysListFragment mListFragment;
|
||||||
@ -143,17 +143,12 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
|
|||||||
* Keychain's own Actions
|
* Keychain's own Actions
|
||||||
*/
|
*/
|
||||||
if (ACTION_IMPORT_KEY.equals(action)) {
|
if (ACTION_IMPORT_KEY.equals(action)) {
|
||||||
if ("file".equals(intent.getScheme()) && intent.getDataString() != null) {
|
|
||||||
String importFilename = intent.getData().getPath();
|
|
||||||
|
|
||||||
// display selected filename
|
|
||||||
getSupportActionBar().setSelectedNavigationItem(1);
|
getSupportActionBar().setSelectedNavigationItem(1);
|
||||||
Bundle args = new Bundle();
|
loadFragment(ImportKeysFileFragment.class, null, mNavigationStrings[1]);
|
||||||
args.putString(ImportKeysFileFragment.ARG_PATH, importFilename);
|
|
||||||
loadFragment(ImportKeysFileFragment.class, args, mNavigationStrings[1]);
|
|
||||||
|
|
||||||
|
if (dataUri != null) {
|
||||||
// directly load data
|
// directly load data
|
||||||
startListFragment(savedInstanceState, null, importFilename);
|
startListFragment(savedInstanceState, null, dataUri);
|
||||||
} else if (extras.containsKey(EXTRA_KEY_BYTES)) {
|
} else if (extras.containsKey(EXTRA_KEY_BYTES)) {
|
||||||
byte[] importData = intent.getByteArrayExtra(EXTRA_KEY_BYTES);
|
byte[] importData = intent.getByteArrayExtra(EXTRA_KEY_BYTES);
|
||||||
|
|
||||||
@ -161,12 +156,29 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
|
|||||||
startListFragment(savedInstanceState, importData, null);
|
startListFragment(savedInstanceState, importData, null);
|
||||||
}
|
}
|
||||||
} else if (ACTION_IMPORT_KEY_FROM_KEYSERVER.equals(action)) {
|
} else if (ACTION_IMPORT_KEY_FROM_KEYSERVER.equals(action)) {
|
||||||
if (!extras.containsKey(EXTRA_QUERY)) {
|
String query = null;
|
||||||
Log.e(Constants.TAG, "IMPORT_KEY_FROM_KEYSERVER action needs to contain the 'query' extra!");
|
if (extras.containsKey(EXTRA_QUERY)) {
|
||||||
|
query = extras.getString(EXTRA_QUERY);
|
||||||
|
} else if (extras.containsKey(EXTRA_KEY_ID)) {
|
||||||
|
long keyId = intent.getLongExtra(EXTRA_KEY_ID, 0);
|
||||||
|
if (keyId != 0) {
|
||||||
|
query = "0x" + PgpKeyHelper.convertKeyToHex(keyId);
|
||||||
|
}
|
||||||
|
} else if (extras.containsKey(EXTRA_FINGERPRINT)) {
|
||||||
|
String fingerprint = intent.getStringExtra(EXTRA_FINGERPRINT);
|
||||||
|
if (fingerprint != null) {
|
||||||
|
query = "0x" + fingerprint;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.e(Constants.TAG, "IMPORT_KEY_FROM_KEYSERVER action needs to contain the 'query', 'key_id', or 'fingerprint' extra!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String query = extras.getString(EXTRA_QUERY);
|
// search directly
|
||||||
|
getSupportActionBar().setSelectedNavigationItem(0);
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putString(ImportKeysServerFragment.ARG_QUERY, query);
|
||||||
|
loadFragment(ImportKeysServerFragment.class, args, mNavigationStrings[0]);
|
||||||
|
|
||||||
// TODO: implement KEYSERVER!
|
// TODO: implement KEYSERVER!
|
||||||
|
|
||||||
@ -188,7 +200,7 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startListFragment(Bundle savedInstanceState, byte[] bytes, String filename) {
|
private void startListFragment(Bundle savedInstanceState, byte[] bytes, Uri dataUri) {
|
||||||
// Check that the activity is using the layout version with
|
// Check that the activity is using the layout version with
|
||||||
// the fragment_container FrameLayout
|
// the fragment_container FrameLayout
|
||||||
if (findViewById(R.id.import_keys_list_container) != null) {
|
if (findViewById(R.id.import_keys_list_container) != null) {
|
||||||
@ -201,7 +213,7 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create an instance of the fragment
|
// Create an instance of the fragment
|
||||||
mListFragment = ImportKeysListFragment.newInstance(bytes, filename);
|
mListFragment = ImportKeysListFragment.newInstance(bytes, dataUri, null);
|
||||||
|
|
||||||
// Add the fragment to the 'fragment_container' FrameLayout
|
// Add the fragment to the 'fragment_container' FrameLayout
|
||||||
// NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
|
// NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
|
||||||
@ -267,8 +279,8 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
|
|||||||
startActivity(queryIntent);
|
startActivity(queryIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadCallback(byte[] importData, String importFilename) {
|
public void loadCallback(byte[] importData, Uri dataUri, String serverQuery) {
|
||||||
mListFragment.loadNew(importData, importFilename);
|
mListFragment.loadNew(importData, dataUri, serverQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
// private void importAndSignOld(final long keyId, final String expectedFingerprint) {
|
// private void importAndSignOld(final long keyId, final String expectedFingerprint) {
|
||||||
@ -333,7 +345,7 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
|
|||||||
* Import keys with mImportData
|
* Import keys with mImportData
|
||||||
*/
|
*/
|
||||||
public void importKeys() {
|
public void importKeys() {
|
||||||
if (mListFragment.getKeyBytes() != null || mListFragment.getImportFilename() != null) {
|
if (mListFragment.getKeyBytes() != null || mListFragment.getDataUri() != null) {
|
||||||
Log.d(Constants.TAG, "importKeys started");
|
Log.d(Constants.TAG, "importKeys started");
|
||||||
|
|
||||||
// Send all information needed to service to import key in other thread
|
// Send all information needed to service to import key in other thread
|
||||||
@ -360,8 +372,7 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
|
|||||||
data.putByteArray(KeychainIntentService.IMPORT_BYTES, mListFragment.getKeyBytes());
|
data.putByteArray(KeychainIntentService.IMPORT_BYTES, mListFragment.getKeyBytes());
|
||||||
} else {
|
} else {
|
||||||
data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_FILE);
|
data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_FILE);
|
||||||
data.putString(KeychainIntentService.IMPORT_FILENAME,
|
intent.setData(mListFragment.getDataUri());
|
||||||
mListFragment.getImportFilename());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||||
@ -417,14 +428,11 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
|
|||||||
});
|
});
|
||||||
alert.setCancelable(true);
|
alert.setCancelable(true);
|
||||||
alert.create().show();
|
alert.create().show();
|
||||||
} else if (mDeleteAfterImport) {
|
|
||||||
// everything went well, so now delete, if that was turned on
|
|
||||||
DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment
|
|
||||||
.newInstance(mListFragment.getImportFilename());
|
|
||||||
deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create a new Messenger for the communication back
|
// Create a new Messenger for the communication back
|
||||||
|
@ -62,7 +62,7 @@ public class ImportKeysClipboardFragment extends Fragment {
|
|||||||
String sendText = "";
|
String sendText = "";
|
||||||
if (clipboardText != null)
|
if (clipboardText != null)
|
||||||
sendText = clipboardText.toString();
|
sendText = clipboardText.toString();
|
||||||
mImportActivity.loadCallback(sendText.getBytes(), null);
|
mImportActivity.loadCallback(sendText.getBytes(), null, null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ import org.sufficientlysecure.keychain.Constants;
|
|||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.helper.FileHelper;
|
import org.sufficientlysecure.keychain.helper.FileHelper;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -30,25 +29,20 @@ import android.support.v4.app.Fragment;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.EditText;
|
|
||||||
|
|
||||||
import com.beardedhen.androidbootstrap.BootstrapButton;
|
import com.beardedhen.androidbootstrap.BootstrapButton;
|
||||||
|
|
||||||
public class ImportKeysFileFragment extends Fragment {
|
public class ImportKeysFileFragment extends Fragment {
|
||||||
public static final String ARG_PATH = "path";
|
|
||||||
|
|
||||||
private ImportKeysActivity mImportActivity;
|
private ImportKeysActivity mImportActivity;
|
||||||
private EditText mFilename;
|
|
||||||
private BootstrapButton mBrowse;
|
private BootstrapButton mBrowse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new instance of this fragment
|
* Creates new instance of this fragment
|
||||||
*/
|
*/
|
||||||
public static ImportKeysFileFragment newInstance(String path) {
|
public static ImportKeysFileFragment newInstance() {
|
||||||
ImportKeysFileFragment frag = new ImportKeysFileFragment();
|
ImportKeysFileFragment frag = new ImportKeysFileFragment();
|
||||||
|
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putString(ARG_PATH, path);
|
|
||||||
|
|
||||||
frag.setArguments(args);
|
frag.setArguments(args);
|
||||||
return frag;
|
return frag;
|
||||||
@ -61,7 +55,6 @@ public class ImportKeysFileFragment extends Fragment {
|
|||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.import_keys_file_fragment, container, false);
|
View view = inflater.inflate(R.layout.import_keys_file_fragment, container, false);
|
||||||
|
|
||||||
mFilename = (EditText) view.findViewById(R.id.import_keys_file_input);
|
|
||||||
mBrowse = (BootstrapButton) view.findViewById(R.id.import_keys_file_browse);
|
mBrowse = (BootstrapButton) view.findViewById(R.id.import_keys_file_browse);
|
||||||
|
|
||||||
mBrowse.setOnClickListener(new View.OnClickListener() {
|
mBrowse.setOnClickListener(new View.OnClickListener() {
|
||||||
@ -69,7 +62,7 @@ public class ImportKeysFileFragment extends Fragment {
|
|||||||
// open .asc or .gpg files
|
// open .asc or .gpg files
|
||||||
// setting it to text/plain prevents Cynaogenmod's file manager from selecting asc
|
// setting it to text/plain prevents Cynaogenmod's file manager from selecting asc
|
||||||
// or gpg types!
|
// or gpg types!
|
||||||
FileHelper.openFile(ImportKeysFileFragment.this, mFilename.getText().toString(),
|
FileHelper.openFile(ImportKeysFileFragment.this, Constants.path.APP_DIR + "/",
|
||||||
"*/*", Id.request.filename);
|
"*/*", Id.request.filename);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -82,13 +75,6 @@ public class ImportKeysFileFragment extends Fragment {
|
|||||||
super.onActivityCreated(savedInstanceState);
|
super.onActivityCreated(savedInstanceState);
|
||||||
|
|
||||||
mImportActivity = (ImportKeysActivity) getActivity();
|
mImportActivity = (ImportKeysActivity) getActivity();
|
||||||
|
|
||||||
// set default path
|
|
||||||
String path = Constants.path.APP_DIR + "/";
|
|
||||||
if (getArguments() != null && getArguments().containsKey(ARG_PATH)) {
|
|
||||||
path = getArguments().getString(ARG_PATH);
|
|
||||||
}
|
|
||||||
mFilename.setText(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -96,19 +82,9 @@ public class ImportKeysFileFragment extends Fragment {
|
|||||||
switch (requestCode & 0xFFFF) {
|
switch (requestCode & 0xFFFF) {
|
||||||
case Id.request.filename: {
|
case Id.request.filename: {
|
||||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||||
String path = null;
|
|
||||||
try {
|
|
||||||
path = data.getData().getPath();
|
|
||||||
Log.d(Constants.TAG, "path=" + path);
|
|
||||||
|
|
||||||
// set filename to edittext
|
|
||||||
mFilename.setText(path);
|
|
||||||
} catch (NullPointerException e) {
|
|
||||||
Log.e(Constants.TAG, "Nullpointer while retrieving path!", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// load data
|
// load data
|
||||||
mImportActivity.loadCallback(null, path);
|
mImportActivity.loadCallback(null, data.getData(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
|
* Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||||
* Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* you may not use this file except in compliance with the License.
|
* it under the terms of the GNU General Public License as published by
|
||||||
* You may obtain a copy of the License at
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* You should have received a copy of the GNU General Public License
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* 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.sufficientlysecure.keychain.ui;
|
package org.sufficientlysecure.keychain.ui;
|
||||||
@ -20,6 +20,8 @@ package org.sufficientlysecure.keychain.ui;
|
|||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
@ -31,6 +33,7 @@ import org.sufficientlysecure.keychain.util.InputData;
|
|||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.LoaderManager;
|
import android.support.v4.app.LoaderManager;
|
||||||
import android.support.v4.content.Loader;
|
import android.support.v4.content.Loader;
|
||||||
@ -41,21 +44,26 @@ import com.actionbarsherlock.app.SherlockListFragment;
|
|||||||
|
|
||||||
public class ImportKeysListFragment extends SherlockListFragment implements
|
public class ImportKeysListFragment extends SherlockListFragment implements
|
||||||
LoaderManager.LoaderCallbacks<List<ImportKeysListEntry>> {
|
LoaderManager.LoaderCallbacks<List<ImportKeysListEntry>> {
|
||||||
private static final String ARG_FILENAME = "filename";
|
private static final String ARG_DATA_URI = "uri";
|
||||||
private static final String ARG_BYTES = "bytes";
|
private static final String ARG_BYTES = "bytes";
|
||||||
|
private static final String ARG_SERVER_QUERY = "query";
|
||||||
|
|
||||||
private Activity mActivity;
|
private Activity mActivity;
|
||||||
private ImportKeysAdapter mAdapter;
|
private ImportKeysAdapter mAdapter;
|
||||||
|
|
||||||
private byte[] mKeyBytes;
|
private byte[] mKeyBytes;
|
||||||
private String mImportFilename;
|
private Uri mDataUri;
|
||||||
|
private String mServerQuery;
|
||||||
|
|
||||||
|
private static final int LOADER_ID_BYTES = 0;
|
||||||
|
private static final int LOADER_ID_SERVER_QUERY = 1;
|
||||||
|
|
||||||
public byte[] getKeyBytes() {
|
public byte[] getKeyBytes() {
|
||||||
return mKeyBytes;
|
return mKeyBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getImportFilename() {
|
public Uri getDataUri() {
|
||||||
return mImportFilename;
|
return mDataUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ImportKeysListEntry> getData() {
|
public List<ImportKeysListEntry> getData() {
|
||||||
@ -65,12 +73,13 @@ public class ImportKeysListFragment extends SherlockListFragment implements
|
|||||||
/**
|
/**
|
||||||
* Creates new instance of this fragment
|
* Creates new instance of this fragment
|
||||||
*/
|
*/
|
||||||
public static ImportKeysListFragment newInstance(byte[] bytes, String filename) {
|
public static ImportKeysListFragment newInstance(byte[] bytes, Uri dataUri, String serverQuery) {
|
||||||
ImportKeysListFragment frag = new ImportKeysListFragment();
|
ImportKeysListFragment frag = new ImportKeysListFragment();
|
||||||
|
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putByteArray(ARG_BYTES, bytes);
|
args.putByteArray(ARG_BYTES, bytes);
|
||||||
args.putString(ARG_FILENAME, filename);
|
args.putParcelable(ARG_DATA_URI, dataUri);
|
||||||
|
args.putString(ARG_SERVER_QUERY, serverQuery);
|
||||||
|
|
||||||
frag.setArguments(args);
|
frag.setArguments(args);
|
||||||
|
|
||||||
@ -87,8 +96,9 @@ public class ImportKeysListFragment extends SherlockListFragment implements
|
|||||||
mActivity = getActivity();
|
mActivity = getActivity();
|
||||||
|
|
||||||
if (getArguments() != null) {
|
if (getArguments() != null) {
|
||||||
mImportFilename = getArguments().getString(ARG_FILENAME);
|
mDataUri = getArguments().getParcelable(ARG_DATA_URI);
|
||||||
mKeyBytes = getArguments().getByteArray(ARG_BYTES);
|
mKeyBytes = getArguments().getByteArray(ARG_BYTES);
|
||||||
|
mServerQuery = getArguments().getString(ARG_SERVER_QUERY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Give some text to display if there is no data. In a real
|
// Give some text to display if there is no data. In a real
|
||||||
@ -105,7 +115,8 @@ public class ImportKeysListFragment extends SherlockListFragment implements
|
|||||||
// Prepare the loader. Either re-connect with an existing one,
|
// Prepare the loader. Either re-connect with an existing one,
|
||||||
// or start a new one.
|
// or start a new one.
|
||||||
// give arguments to onCreateLoader()
|
// give arguments to onCreateLoader()
|
||||||
getLoaderManager().initLoader(0, null, this);
|
getLoaderManager().initLoader(LOADER_ID_BYTES, null, this);
|
||||||
|
getLoaderManager().initLoader(LOADER_ID_SERVER_QUERY, null, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -120,38 +131,42 @@ public class ImportKeysListFragment extends SherlockListFragment implements
|
|||||||
mAdapter.notifyDataSetChanged();
|
mAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadNew(byte[] importData, String importFilename) {
|
public void loadNew(byte[] importData, Uri dataUri, String serverQuery) {
|
||||||
this.mKeyBytes = importData;
|
mKeyBytes = importData;
|
||||||
this.mImportFilename = importFilename;
|
mDataUri = dataUri;
|
||||||
|
mServerQuery = serverQuery;
|
||||||
|
|
||||||
getLoaderManager().restartLoader(0, null, this);
|
if (mKeyBytes != null || mDataUri != null)
|
||||||
|
getLoaderManager().restartLoader(LOADER_ID_BYTES, null, this);
|
||||||
|
|
||||||
|
if (mServerQuery != null)
|
||||||
|
getLoaderManager().restartLoader(LOADER_ID_SERVER_QUERY, null, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Loader<List<ImportKeysListEntry>> onCreateLoader(int id, Bundle args) {
|
public Loader<List<ImportKeysListEntry>> onCreateLoader(int id, Bundle args) {
|
||||||
InputData inputData = getInputData(mKeyBytes, mImportFilename);
|
switch (id) {
|
||||||
|
case LOADER_ID_BYTES: {
|
||||||
|
InputData inputData = getInputData(mKeyBytes, mDataUri);
|
||||||
|
|
||||||
return new ImportKeysListLoader(mActivity, inputData);
|
return new ImportKeysListLoader(mActivity, inputData);
|
||||||
}
|
}
|
||||||
|
case LOADER_ID_SERVER_QUERY: {
|
||||||
|
|
||||||
private InputData getInputData(byte[] importBytes, String importFilename) {
|
|
||||||
InputData inputData = null;
|
|
||||||
if (importBytes != null) {
|
|
||||||
inputData = new InputData(new ByteArrayInputStream(importBytes), importBytes.length);
|
|
||||||
} else if (importFilename != null) {
|
|
||||||
try {
|
|
||||||
inputData = new InputData(new FileInputStream(importFilename),
|
|
||||||
importFilename.length());
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
Log.e(Constants.TAG, "Failed to init FileInputStream!", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return inputData;
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadFinished(Loader<List<ImportKeysListEntry>> loader,
|
public void onLoadFinished(Loader<List<ImportKeysListEntry>> loader,
|
||||||
List<ImportKeysListEntry> data) {
|
List<ImportKeysListEntry> data) {
|
||||||
|
// Swap the new cursor in. (The framework will take care of closing the
|
||||||
|
// old cursor once we return.)
|
||||||
|
switch (loader.getId()) {
|
||||||
|
case LOADER_ID_BYTES:
|
||||||
Log.d(Constants.TAG, "data: " + data);
|
Log.d(Constants.TAG, "data: " + data);
|
||||||
|
|
||||||
// swap in the real data!
|
// swap in the real data!
|
||||||
@ -166,12 +181,51 @@ public class ImportKeysListFragment extends SherlockListFragment implements
|
|||||||
} else {
|
} else {
|
||||||
setListShownNoAnimation(true);
|
setListShownNoAnimation(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LOADER_ID_SERVER_QUERY:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoaderReset(Loader<List<ImportKeysListEntry>> loader) {
|
public void onLoaderReset(Loader<List<ImportKeysListEntry>> loader) {
|
||||||
|
switch (loader.getId()) {
|
||||||
|
case LOADER_ID_BYTES:
|
||||||
// Clear the data in the adapter.
|
// Clear the data in the adapter.
|
||||||
mAdapter.clear();
|
mAdapter.clear();
|
||||||
|
break;
|
||||||
|
case LOADER_ID_SERVER_QUERY:
|
||||||
|
// Clear the data in the adapter.
|
||||||
|
mAdapter.clear();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private InputData getInputData(byte[] importBytes, Uri dataUri) {
|
||||||
|
InputData inputData = null;
|
||||||
|
if (importBytes != null) {
|
||||||
|
inputData = new InputData(new ByteArrayInputStream(importBytes), importBytes.length);
|
||||||
|
} else if (dataUri != null) {
|
||||||
|
try {
|
||||||
|
InputStream inputStream = getActivity().getContentResolver().openInputStream(dataUri);
|
||||||
|
int length = inputStream.available();
|
||||||
|
|
||||||
|
inputData = new InputData(inputStream, length);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
Log.e(Constants.TAG, "FileNotFoundException!", e);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(Constants.TAG, "IOException!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return inputData;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,7 @@ public class ImportKeysQrCodeFragment extends Fragment {
|
|||||||
for (String in : mScannedContent) {
|
for (String in : mScannedContent) {
|
||||||
result += in;
|
result += in;
|
||||||
}
|
}
|
||||||
mImportActivity.loadCallback(result.getBytes(), null);
|
mImportActivity.loadCallback(result.getBytes(), null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
|
* Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -17,22 +17,36 @@
|
|||||||
|
|
||||||
package org.sufficientlysecure.keychain.ui;
|
package org.sufficientlysecure.keychain.ui;
|
||||||
|
|
||||||
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
import org.sufficientlysecure.keychain.helper.Preferences;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.Spinner;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.beardedhen.androidbootstrap.BootstrapButton;
|
import com.beardedhen.androidbootstrap.BootstrapButton;
|
||||||
|
|
||||||
public class ImportKeysServerFragment extends Fragment {
|
public class ImportKeysServerFragment extends Fragment {
|
||||||
private BootstrapButton mButton;
|
public static final String ARG_QUERY = "query";
|
||||||
|
|
||||||
String mQuery;
|
private ImportKeysActivity mImportActivity;
|
||||||
|
|
||||||
|
private BootstrapButton mOldButton;
|
||||||
|
|
||||||
|
private BootstrapButton mSearchButton;
|
||||||
|
private EditText mQueryEditText;
|
||||||
|
private Spinner mServerSpinner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new instance of this fragment
|
* Creates new instance of this fragment
|
||||||
@ -41,6 +55,8 @@ public class ImportKeysServerFragment extends Fragment {
|
|||||||
ImportKeysServerFragment frag = new ImportKeysServerFragment();
|
ImportKeysServerFragment frag = new ImportKeysServerFragment();
|
||||||
|
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
|
args.putString(ARG_QUERY, query);
|
||||||
|
|
||||||
frag.setArguments(args);
|
frag.setArguments(args);
|
||||||
|
|
||||||
return frag;
|
return frag;
|
||||||
@ -51,14 +67,52 @@ public class ImportKeysServerFragment extends Fragment {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.import_keys_keyserver_fragment, container, false);
|
View view = inflater.inflate(R.layout.import_keys_server_fragment, container, false);
|
||||||
|
|
||||||
mButton = (BootstrapButton) view.findViewById(R.id.import_keyserver_button);
|
mSearchButton = (BootstrapButton) view.findViewById(R.id.import_server_button);
|
||||||
mButton.setOnClickListener(new OnClickListener() {
|
mQueryEditText = (EditText) view.findViewById(R.id.import_server_query);
|
||||||
|
mServerSpinner = (Spinner) view.findViewById(R.id.import_server_spinner);
|
||||||
|
|
||||||
|
// add keyservers to spinner
|
||||||
|
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
|
||||||
|
android.R.layout.simple_spinner_item, Preferences.getPreferences(getActivity())
|
||||||
|
.getKeyServers());
|
||||||
|
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
|
mServerSpinner.setAdapter(adapter);
|
||||||
|
if (adapter.getCount() > 0) {
|
||||||
|
mServerSpinner.setSelection(0);
|
||||||
|
} else {
|
||||||
|
mSearchButton.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
mSearchButton.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
String query = mQueryEditText.getText().toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// TODO: not supported by BootstrapButton
|
||||||
|
// mSearchButton.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||||
|
// @Override
|
||||||
|
// public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||||
|
// if (actionId == EditorInfo.IME_ACTION_SEARCH) {
|
||||||
|
// String query = mQueryEditText.getText().toString();
|
||||||
|
// search(query);
|
||||||
|
// // FIXME This is a hack to hide a keyboard after search
|
||||||
|
// // http://tinyurl.com/pwdc3q9
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// TODO: remove:
|
||||||
|
mOldButton = (BootstrapButton) view.findViewById(R.id.import_server_button);
|
||||||
|
mOldButton.setOnClickListener(new OnClickListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
// TODO: use fragment instead of activity, handle onresult here!
|
|
||||||
startActivityForResult(new Intent(getActivity(), KeyServerQueryActivity.class), 0);
|
startActivityForResult(new Intent(getActivity(), KeyServerQueryActivity.class), 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -66,4 +120,22 @@ public class ImportKeysServerFragment extends Fragment {
|
|||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityCreated(Bundle savedInstanceState) {
|
||||||
|
super.onActivityCreated(savedInstanceState);
|
||||||
|
|
||||||
|
mImportActivity = (ImportKeysActivity) getActivity();
|
||||||
|
|
||||||
|
// if query has been set on instantiation, search immediately!
|
||||||
|
if (getArguments() != null && getArguments().containsKey(ARG_QUERY)) {
|
||||||
|
String query = getArguments().getString(ARG_QUERY);
|
||||||
|
mQueryEditText.setText(query);
|
||||||
|
search(query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void search(String query) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -330,7 +330,7 @@ public class ViewKeyActivity extends SherlockFragmentActivity implements
|
|||||||
creationDate));
|
creationDate));
|
||||||
}
|
}
|
||||||
|
|
||||||
// get creation date from EXPIRY
|
// get expiry date from EXPIRY
|
||||||
if (data.isNull(KEYS_INDEX_EXPIRY)) {
|
if (data.isNull(KEYS_INDEX_EXPIRY)) {
|
||||||
mExpiry.setText(R.string.none);
|
mExpiry.setText(R.string.none);
|
||||||
} else {
|
} else {
|
||||||
@ -346,7 +346,7 @@ public class ViewKeyActivity extends SherlockFragmentActivity implements
|
|||||||
|
|
||||||
byte[] fingerprintBlob = data.getBlob(KEYS_INDEX_FINGERPRINT);
|
byte[] fingerprintBlob = data.getBlob(KEYS_INDEX_FINGERPRINT);
|
||||||
if (fingerprintBlob == null) {
|
if (fingerprintBlob == null) {
|
||||||
// FALLBACK for old databases
|
// FALLBACK for old database entries
|
||||||
fingerprintBlob = ProviderHelper.getFingerprint(this, mDataUri);
|
fingerprintBlob = ProviderHelper.getFingerprint(this, mDataUri);
|
||||||
}
|
}
|
||||||
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true);
|
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true);
|
||||||
|
@ -3,29 +3,16 @@
|
|||||||
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
|
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal" >
|
android:orientation="vertical">
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/import_keys_file_input"
|
|
||||||
android:layout_width="0dip"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:gravity="top|left"
|
|
||||||
android:inputType="textMultiLine|textUri"
|
|
||||||
android:lines="2"
|
|
||||||
android:maxLines="6"
|
|
||||||
android:minLines="2"
|
|
||||||
android:scrollbars="vertical" />
|
|
||||||
|
|
||||||
<com.beardedhen.androidbootstrap.BootstrapButton
|
<com.beardedhen.androidbootstrap.BootstrapButton
|
||||||
android:id="@+id/import_keys_file_browse"
|
android:id="@+id/import_keys_file_browse"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="70dp"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_margin="10dp"
|
||||||
android:layout_margin="4dp"
|
android:text="@string/filemanager_title_open"
|
||||||
android:contentDescription="@string/filemanager_title_open"
|
android:contentDescription="@string/filemanager_title_open"
|
||||||
bootstrapbutton:bb_icon_left="fa-folder-open"
|
bootstrapbutton:bb_icon_left="fa-folder-open"
|
||||||
bootstrapbutton:bb_roundedCorners="true"
|
|
||||||
bootstrapbutton:bb_size="default"
|
bootstrapbutton:bb_size="default"
|
||||||
bootstrapbutton:bb_type="default" />
|
bootstrapbutton:bb_type="default" />
|
||||||
|
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical" >
|
|
||||||
|
|
||||||
<com.beardedhen.androidbootstrap.BootstrapButton
|
|
||||||
android:id="@+id/import_keyserver_button"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="70dp"
|
|
||||||
android:layout_margin="10dp"
|
|
||||||
android:text="@string/menu_key_server"
|
|
||||||
bootstrapbutton:bb_size="default"
|
|
||||||
bootstrapbutton:bb_type="default" />
|
|
||||||
|
|
||||||
<!-- <Spinner -->
|
|
||||||
<!-- android:id="@+id/import_keys_server_key_server" -->
|
|
||||||
<!-- android:layout_width="fill_parent" -->
|
|
||||||
<!-- android:layout_height="wrap_content" /> -->
|
|
||||||
|
|
||||||
|
|
||||||
<!-- <LinearLayout -->
|
|
||||||
<!-- android:layout_width="fill_parent" -->
|
|
||||||
<!-- android:layout_height="wrap_content" -->
|
|
||||||
<!-- android:orientation="horizontal" > -->
|
|
||||||
|
|
||||||
|
|
||||||
<!-- <EditText -->
|
|
||||||
<!-- android:id="@+id/import_keys_server_query" -->
|
|
||||||
<!-- android:layout_width="0dip" -->
|
|
||||||
<!-- android:layout_height="wrap_content" -->
|
|
||||||
<!-- android:layout_weight="1" -->
|
|
||||||
<!-- android:inputType="textPersonName|textEmailAddress" /> -->
|
|
||||||
|
|
||||||
|
|
||||||
<!-- <Button -->
|
|
||||||
<!-- android:id="@+id/import_keys_server_search" -->
|
|
||||||
<!-- android:layout_width="wrap_content" -->
|
|
||||||
<!-- android:layout_height="wrap_content" -->
|
|
||||||
<!-- android:text="@string/btn_search" /> -->
|
|
||||||
<!-- </LinearLayout> -->
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
@ -0,0 +1,54 @@
|
|||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/import_server_spinner"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/import_server_query"
|
||||||
|
android:layout_width="0dip"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="top|left"
|
||||||
|
android:hint="@string/hint_public_keys"
|
||||||
|
android:imeOptions="actionSearch"
|
||||||
|
android:inputType="textNoSuggestions"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:lines="1"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:minLines="1"
|
||||||
|
android:layout_gravity="center_vertical" />
|
||||||
|
|
||||||
|
<com.beardedhen.androidbootstrap.BootstrapButton
|
||||||
|
android:id="@+id/import_server_search"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginLeft="10dp"
|
||||||
|
bootstrapbutton:bb_icon_left="fa-search"
|
||||||
|
bootstrapbutton:bb_roundedCorners="true"
|
||||||
|
bootstrapbutton:bb_size="default"
|
||||||
|
bootstrapbutton:bb_type="default" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.beardedhen.androidbootstrap.BootstrapButton
|
||||||
|
android:id="@+id/import_server_button"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="70dp"
|
||||||
|
android:layout_margin="10dp"
|
||||||
|
android:text="@string/menu_key_server"
|
||||||
|
bootstrapbutton:bb_size="default"
|
||||||
|
bootstrapbutton:bb_type="default" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
Loading…
Reference in New Issue
Block a user