Getting User Certificates with KeyStore.saw(String prefix) - android

There is described on this page how android is able to select all user certificates and show them in a spinner...
http://source-android.frandroid.com/packages/apps/Settings/src/com/android/settings/vpn2/VpnDialog.java
They use the Method:
private void loadCertificates(Spinner spinner, String prefix, int firstId, String selected) {
Context context = getContext();
String first = (firstId == 0) ? "" : context.getString(firstId);
String[] certificates = mKeyStore.saw(prefix);
if (certificates == null || certificates.length == 0) {
certificates = new String[] {first};
} else {
String[] array = new String[certificates.length + 1];
array[0] = first;
System.arraycopy(certificates, 0, array, 1, certificates.length);
certificates = array;
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
context, android.R.layout.simple_spinner_item, certificates);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
for (int i = 1; i < certificates.length; ++i) {
if (certificates[i].equals(selected)) {
spinner.setSelection(i);
break;
}
}
}
with this call:
loadCertificates(mIpsecUserCert, Credentials.USER_CERTIFICATE,
0, mProfile.ipsecUserCert);
now they use Credetials.USER_CERTIFICATE for the Method mKeyStore.saw(String prefix)
thats exactly what im looking for, but i cannot invoke the method saw and its also not mentioned in the android api...
so is there somehow a way of getting the same result for me?
the keystore library is not able of making a difference of user or system certs, and if i want to put all certs in a dropdown list it will cost me a lot of loading time. The other way of typing the subject name of the cert and looping through all certs till its the right one is not really practicable for a non-IT guy, so its crappy to handle for a normal user...
there are almost no references on this topic in the net, thats why im asking google android pro's on this post only.
thankyou

This is a private API, it cannot be used by third party applications. Why do you want to select a user certificate? You generally want the user's private key, and the KeyChain API supports letting the user select one of those.

Related

Howto retrieve all accounts availables for contacts? [duplicate]

This question already has answers here:
What is the default Account Type / Name for contacts on Android Contact Application?
(3 answers)
Closed 5 years ago.
I would like to programmatically retrieve all accounts on a android phone/tablet that are able to be used for contacts, without any previous knowledge of the existents accounts.
I used AccountManager to retrieve all accounts, but this give me other accounts too (for example email accounts).
So I added AccountManager.hasFeatures() to select the only accounts that have the "service_contacts" feature, but in this way I only find the Google account and not others (for example on my phone I use Davdroid account for my contacts, and my program don't select this account).
So, where I'm wrong? Are there others API that I should use?
Can someone suggest me (maybe with some code as example) a way to the goal?
Thanks for any help
EDITED:
Sorry for my not perfect knowledge of english language, but I thought I explained well myself.
I don't want to retrieve an account that I already know, or by a type that I already know (getAccountsByType).
I want to deploy an Application on a phone that I don't know, that can have whatever account (maybe none Google account) with no any previous knowledge, and retrieve only that accounts able to be used for contacts (they are the accounts that you can select in the Contacts application when you add a new contact).
Maybe I'm wrong and I ask forgiviness for that, but I can't see this as a duplicated question, and I'm not able to understand how to use your answers to solve my very specific problem.
Thanks again for your answers
SOLUTION:
I used ContentResolver.getSyncAdapterTypes() to select all sync adapters related to "com.android.contacts", so the code is (I used an EditText for display):
private void getAccountsForContacts() {
// Constants
final String SYNC_AUTHORITY = "com.android.contacts";
// Variables
List<SyncAdapterType> okSyncs;
SyncAdapterType[] mySyncTypes;
AccountManager accountManager;
Account[] tempAccounts;
List<Account> allAccounts;
String textAccounts;
int i;
int j;
// Clear the text
EditText editListAccounts = (EditText) findViewById(R.id.editListAccounts);
editListAccounts.setText("");
// Initialize all variables
okSyncs = new ArrayList<SyncAdapterType>();
allAccounts = new ArrayList<Account>();
textAccounts = "";
// Get all sync adapters
mySyncTypes = ContentResolver.getSyncAdapterTypes();
if (mySyncTypes.length > 0) {
for (i = 0; i < mySyncTypes.length; i++) {
// Select the only adapters for contacts
if (mySyncTypes[i].authority.equals(SYNC_AUTHORITY)) {
okSyncs.add(mySyncTypes[i]);
}
}
}
if (okSyncs.size() > 0) {
accountManager = AccountManager.get(this);
// From sync get all related accounts
for (i = 0; i < okSyncs.size(); i++) {
tempAccounts = accountManager.getAccountsByType(okSyncs.get(i).accountType);
if (tempAccounts.length > 0) {
for (j = 0; j < tempAccounts.length; j++) {
allAccounts.add(tempAccounts[j]);
}
}
}
}
if (allAccounts.size() > 0) {
for (i=0; i<allAccounts.size(); i++) {
textAccounts += allAccounts.get(i).toString();
}
} else {
textAccounts = getResources().getString(R.string.main_accounts_not_found);
}
editListAccounts.setText(textAccounts);
}
I hope it can be useful for someone.
Thanks anyway.
I guess this one could help you solving it by yourself and learning things that way
AccountManager.getAccountsByType(java.lang.String)

Realm on Android - How to select multiple objects by list of ids (#PrimaryKey)?

I'm building an Android app with the Realm database.
I have a RealmObject subclass called Article which has an id field (it's and int and also a #PrimaryKey). I would like to pass to a query a list of ints (a Set, int[], or whatever) of article id's and retrieve only those articles.
In SQL would be like this:
SELECT *
FROM `table`
where ID in (5263, 5625, 5628, 5621)
I've seen it's possible to do this in iOS in this StackOverflow question.
How can I do this in Android? Thanks!
Edit: Just to inform, I also asked this on the GitHub repo here.
Update:
Realm 1.2.0 has added RealmQuery.in() for a comparison against multiple values. The documentation details all the available overloads. This one is the method we can use if our ids are Integers:
public RealmQuery<E> in(String fieldName, Integer[] values)
Original answer:
The answer from #ChristianMelchior returns all articles if the list of ids is empty. I want it to return an empty RealmResults<Article>. That's what I've ended up doing:
Set<Integer> articleIds = this.getArticleIds();
RealmQuery<Article> query = realm.where(Article.class);
if (articleIds.size() == 0) {
// We want to return an empty list if the list of ids is empty.
// Just use alwaysFalse
query = query.alwaysFalse();
} else {
int i = 0;
for (int id : articleIds) {
// The or() operator requires left hand and right hand elements.
// If articleIds had only one element then it would crash with
// "Missing right-hand side of OR"
if (i++ > 0) {
query = query.or();
}
query = query.equalTo("id", id);
}
}
return query.findAll();
Now realm v 1.2.0 support RealmQuery.in() for a comparison against multiple values.
The Realm Java API's doesn't support this yet unfortunately. You can follow the feature request here https://github.com/realm/realm-java/issues/841
The current work-around would be to build up the query yourself in a for-loop:
RealmResults<Article> articles = realm.allObjects(Article.class);
RealmQuery q = articles.where();
for (int id : ids) {
q = q.equalTo("id", id);
}
RealmResults<Article> filteredArticles = q.findAll();
This is the way Realm does it since 1.2.0:
public RealmQuery<E> in(String fieldName, String[] values) {
if (values == null || values.length == 0) {
throw new IllegalArgumentException(EMPTY_VALUES);
}
beginGroup().equalTo(fieldName, values[0]);
for (int i = 1; i < values.length; i++) {
or().equalTo(fieldName, values[i]);
}
return endGroup();
}
Previously this is how I did it
I just came across this post and I thought I could throw in my 2 cents on this. As much as I appreciate Christian Melchior and his answers I think in this case his answer is not working (at least in the current version).
I prefer to do it like this - I personally think it's more readable than Albert Vila's answer:
List<String> listOfIds = [..];
RealmQuery<SomeClass> query = realm.where(SomeClass.class);
boolean first = true;
for (String id : listOfIds) {
if (!first) {
query.or();
} else {
first = false;
}
query.equalTo("id", id);
}
RealmResults<SomeClass> results = query.findAll();

Alphabet Indexed ListView Without a cursor

I receive data from a server using JSON and I want to order them alphabetically with alphabet indexed section and store them in a ListView.
Maybe something that will happen in :
for(int i=0;i<jArray.length();i++){
// here
}
I read that you can order elements like that only using a cursor. In my case would be very inefficient to store the elements from the server in the database and read them again. Waste of time and memory.
So, I am asking you if there could be any solution for my problem : order alphabetically with alphabet indexed section string received from JSON .
EDIT: I want my listview to look like this http://eshyu.wordpress.com/2010/08/15/cursoradapter-with-alphabet-indexed-section-headers/ . I mean with those sections . All tutorials I found said that you need to fetch information with a cursor. My question was if I could't do this wihout a cursor, because it would be a waste of memory to store them in the local database too.
You may need to parse the JSON Array :
List<Project> list = new ArrayList<Project>();
for (int i = 0; i < jArray.length(); i++) {
JSONObject obj = (JSONObject) jArray.get(i);
project = new Project();
project.setId( Long.parseLong(obj.get("id").toString()));
project.setKey(obj.get("key").toString());
project.setName(obj.get("name").toString());
list.add(project);
}
You can use the comparator class like this to sort them :
Collections.sort(list), new Comparator<Project>() {
public int compare(Project p1, Project p2) {
return p1.getKey().compareToIgnoreCase(p2.getKey());
}
});
You can also have Project class and implements Comparable:
public class Project implements Comparable<Project> {
private long id;
private String key;
private String name;
public int compareTo(Project p) {
if (this.key > p.key)
return -1;
else if (this.key < p.key)
return 1;
return 0;
}
}
And then sort the list by Collections.sort(list);
My suggestion is try to sort the data in the Server-side, because the memory of the phone is limited and it may make you application time consuming to show the data, but you do not have memory limitation problem in the Server-side.
use a comparator to sort the arraylist as described here . And then use an ArrayAdapter to show the items in Listview

How to check if an Array contains specific term - Android

I currently have a statement which reads
if(Arrays.asList(results).contains("Word"));
and I want to add at least several more terms to the .contains parameter however I am under the impression that it is bad programming practice to have a large number of terms on one line..
My question is, is there a more suitable way to store all the values I want to have in the .contains parameters?
Thanks
You can use intersection of two lists:
String[] terms = {"Word", "Foo", "Bar"};
List<String> resultList = Arrays.asList(results);
resultList.retainAll(Arrays.asList(terms))
if(resultList.size() > 0)
{
/// Do something
}
To improve performance though, it's better to use the intersection of two HashSets:
String[] terms = {"Word", "Foo", "Bar"};
Set<String> termSet = new HashSet<String>(Arrays.asList(terms));
Set<String> resultsSet = new HashSet<String>(Arrays.asList(results));
resultsSet.retainAll(termSet);
if(resultsSet.size() > 0)
{
/// Do something
}
As a side note, the above code checks whether ANY of the terms appear in results. To check that ALL the terms appear in results, you simply make sure the intersection is the same size as your term list:
resultsSet.retainAll(termSet);
if(resultSet.size() == termSet.size())
You can utilize Android's java.util.Collections
class to help you with this. In particular, disjoint will be useful:
Returns whether the specified collections have no elements in common.
Here's a code sample that should get you started.
In your Activity or wherever you are checking to see if your results contain a word that you are looking for:
String[] results = {"dog", "cat"};
String[] wordsWeAreLookingFor = {"foo", "dog"};
boolean foundWordInResults = this.checkIfArrayContainsAnyStringsInAnotherArray(results, wordsWeAreLookingFor);
Log.d("MyActivity", "foundWordInResults:" + foundWordInResults);
Also in your the same class, or perhaps a utility class:
private boolean checkIfArrayContainsAnyStringsInAnotherArray(String[] results, String[] wordsWeAreLookingFor) {
List<String> resultsList = Arrays.asList(results);
List<String> wordsWeAreLookingForList = Arrays.asList(wordsWeAreLookingFor);
return !Collections.disjoint(resultsList, wordsWeAreLookingForList);
}
Note that this particular code sample will have contain true in foundWordInResults since "dog" is in both results and wordsWeAreLookingFor.
Why don't you just store your results in a HashSet? With a HashSet, you can benefit from hashing of the keys, and it will make your assertion much faster.
Arrays.asList(results).contains("Word") creates a temporary List object each time just to do linear search, it is not efficient use of memory and it's slow.
There's HashSet.containsAll(Collection collection) method you can use to do what you want, but again, it's not efficient use of memory if you want to create a temporary List of the parameters just to do an assertion.
I suggest the following:
HashSet hashSet = ....
public assertSomething(String[] params) {
for(String s : params) {
if(hashSet.contains(s)) {
// do something
break;
}
}
}

Selecting multiple contacts in Android

Is there a way similar to ACTION_PICK to select multiple contacts from the address book and then return to previous activity?
Not a full answer, but maybe helpful anyway:
// Let user select (multiple) from a list of contacts with email addresses
Intent i = new Intent(Intent.ACTION_GET_CONTENT, Email.CONTENT_URI);
startActivityForResult(Intent.createChooser(i, ""), MY_RESULT_1);
In onActivityResult, you'll apparently just get a Uri (in data.getData()) that represents the entire set of contacts. Great.
On HTC Desire/Froyo, data.getExtras() contain three ArrayLists, one of which seems to hold the Id's of the records the user selected.
Set<String> keys = data.getExtras().keySet();
ArrayList<Integer> ids = null;
for (String s : keys) {
Object o = data.getExtras().get(s);
if (o instanceof ArrayList) {
ArrayList a = (ArrayList) o;
if (a.size() > 0 && a.get(0) instanceof Integer) {
ids = a;
}
}
}
You can use these to filter the result from querying the data.getData() Uri.
Not pretty, and possibly HTC specific. You mileage may vary.
If someone can point out a smarter way, I'm a happy listener :)

Categories

Resources