From: David A. Velasco Date: Mon, 19 Oct 2015 13:12:24 +0000 (+0200) Subject: Users and groups retrieved from server to fill search suggestions X-Git-Tag: oc-android-1.9^2~30^2~45 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/305536f8c249ae4ca528cf004fe71a26c7278ede Users and groups retrieved from server to fill search suggestions --- diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 93424a11..9f739085 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -118,6 +118,13 @@ android:label="@string/sync_string_files" android:syncable="true" /> + + + android:resource="@xml/users_and_groups_searchable"/> diff --git a/res/values/strings.xml b/res/values/strings.xml index b7c61557..5fbee3e9 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -375,5 +375,6 @@ (group) Search users and groups + %1$s (group) diff --git a/res/xml/searchable.xml b/res/xml/searchable.xml deleted file mode 100644 index e6703f00..00000000 --- a/res/xml/searchable.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/res/xml/users_and_groups_searchable.xml b/res/xml/users_and_groups_searchable.xml new file mode 100644 index 00000000..9eadd564 --- /dev/null +++ b/res/xml/users_and_groups_searchable.xml @@ -0,0 +1,28 @@ + + + + + + \ No newline at end of file diff --git a/src/com/owncloud/android/operations/GetUsersOrGroupsOperation.java b/src/com/owncloud/android/operations/GetUsersOrGroupsOperation.java index d7a60296..6ecd9303 100644 --- a/src/com/owncloud/android/operations/GetUsersOrGroupsOperation.java +++ b/src/com/owncloud/android/operations/GetUsersOrGroupsOperation.java @@ -56,7 +56,7 @@ public class GetUsersOrGroupsOperation extends SyncOperation{ protected RemoteOperationResult run(OwnCloudClient client) { GetRemoteShareesOperation operation = new GetRemoteShareesOperation(mSearchString, - mLimit, mOffset); + mOffset, mLimit); RemoteOperationResult result = operation.execute(client); return result; diff --git a/src/com/owncloud/android/providers/UsersAndGroupsSearchProvider.java b/src/com/owncloud/android/providers/UsersAndGroupsSearchProvider.java new file mode 100644 index 00000000..d642bfa2 --- /dev/null +++ b/src/com/owncloud/android/providers/UsersAndGroupsSearchProvider.java @@ -0,0 +1,189 @@ +/** + * ownCloud Android client application + * + * @author David A. Velasco + * Copyright (C) 2015 ownCloud Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +package com.owncloud.android.providers; + +import android.accounts.Account; +import android.app.SearchManager; +import android.content.ContentProvider; +import android.content.ContentValues; +import android.content.UriMatcher; +import android.database.Cursor; +import android.database.MatrixCursor; +import android.net.Uri; +import android.provider.BaseColumns; +import android.support.annotation.Nullable; +import android.util.Pair; + +import com.owncloud.android.R; +import com.owncloud.android.authentication.AccountUtils; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.lib.resources.shares.GetRemoteShareesOperation; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + + +/** + * Content provider for search suggestions, to search for users and groups existing in an ownCloud server. + */ +public class UsersAndGroupsSearchProvider extends ContentProvider { + + private static final String TAG = UsersAndGroupsSearchProvider.class.getSimpleName(); + + private static final String[] COLUMNS = { + BaseColumns._ID, + SearchManager.SUGGEST_COLUMN_TEXT_1, + SearchManager.SUGGEST_COLUMN_FLAGS, + SearchManager.SUGGEST_COLUMN_INTENT_DATA + }; + + private static final int SEARCH = 1; + + private static final int RESULTS_PER_PAGE = 50; + private static final int REQUESTED_PAGE = 1; + + public static final String AUTHORITY = UsersAndGroupsSearchProvider.class.getCanonicalName(); + public static final String ACTION_SHARE_WITH = AUTHORITY + ".action.SHARE_WITH"; + public static final String DATA_USER = AUTHORITY + ".data.user"; + public static final String DATA_GROUP = AUTHORITY + ".data.group"; + + private UriMatcher mUriMatcher; + + @Nullable + @Override + public String getType(Uri uri) { + // TODO implement + return null; + } + + @Override + public boolean onCreate() { + mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); + mUriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH); + return true; + } + + /** + * TODO description + * + * Reference: http://developer.android.com/guide/topics/search/adding-custom-suggestions.html#CustomContentProvider + * + * @param uri Content {@link Uri}, formattted as + * "content://com.owncloud.android.providers.UsersAndGroupsSearchProvider/" + + * {@link android.app.SearchManager#SUGGEST_URI_PATH_QUERY} + "/" + 'userQuery' + * @param projection Expected to be NULL. + * @param selection Expected to be NULL. + * @param selectionArgs Expected to be NULL. + * @param sortOrder Expected to be NULL. + * @return Cursor with users and groups in the ownCloud server that match 'userQuery'. + */ + @Nullable + @Override + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { + Log_OC.d(TAG, "query received in thread " + Thread.currentThread().getName()); + + int match = mUriMatcher.match(uri); + switch (match) { + case SEARCH: + return searchForUsersOrGroups(uri); + + default: + return null; + } + } + + private Cursor searchForUsersOrGroups(Uri uri) { + MatrixCursor response = null; + + + String userQuery = uri.getLastPathSegment().toLowerCase(); + + + /// need to trust on the AccountUtils to get the current account since the query in the client side is not + /// directly started by our code, but from SearchView implementation + Account account = AccountUtils.getCurrentOwnCloudAccount(getContext()); + + /// request to the OC server about users and groups matching userQuery + GetRemoteShareesOperation searchRequest = new GetRemoteShareesOperation( + userQuery, REQUESTED_PAGE, RESULTS_PER_PAGE + ); + RemoteOperationResult result = searchRequest.execute(account, getContext()); + List> names = new ArrayList>(); + if (result.isSuccess()) { + for (Object o : result.getData()) { + names.add((Pair) o); + } + } + + /// convert the responses from the OC server to the expected format + if (names.size() > 0) { + response = new MatrixCursor(COLUMNS); + Iterator> namesIt = names.iterator(); + int count = 0; + Pair item; + String displayName; + Uri dataUri; + Uri userBaseUri = new Uri.Builder().scheme("content").authority(DATA_USER).build(); + Uri groupBaseUri = new Uri.Builder().scheme("content").authority(DATA_GROUP).build(); + + while (namesIt.hasNext()) { + item = namesIt.next(); + if (GetRemoteShareesOperation.GROUP_TYPE.equals(item.second)) { + displayName = getContext().getString(R.string.share_group_clarification, item.first); + dataUri = Uri.withAppendedPath(groupBaseUri, item.first); + } else { + displayName = item.first; + dataUri = Uri.withAppendedPath(userBaseUri, item.first); + } + response.newRow() + .add(count++) // BaseColumns._ID + .add(displayName) // SearchManager.SUGGEST_COLUMN_TEXT_1 + .add(SearchManager.FLAG_QUERY_REFINEMENT) + .add(dataUri); + } + } + + return response; + } + + @Nullable + @Override + public Uri insert(Uri uri, ContentValues values) { + // TODO implementation + return null; + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + // TODO implementation + return 0; + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + // TODO implementation + return 0; + } + +} diff --git a/src/com/owncloud/android/ui/activity/ShareActivity.java b/src/com/owncloud/android/ui/activity/ShareActivity.java index 0cb8ee5d..17624300 100644 --- a/src/com/owncloud/android/ui/activity/ShareActivity.java +++ b/src/com/owncloud/android/ui/activity/ShareActivity.java @@ -34,6 +34,8 @@ import android.widget.Toast; import com.owncloud.android.R; import com.owncloud.android.datamodel.OCFile; +import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.providers.UsersAndGroupsSearchProvider; import com.owncloud.android.ui.dialog.LoadingDialog; import com.owncloud.android.ui.fragment.SearchFragment; import com.owncloud.android.ui.fragment.ShareFileFragment; @@ -46,6 +48,8 @@ public class ShareActivity extends AppCompatActivity implements ShareFileFragment.OnShareFragmentInteractionListener, SearchFragment.OnSearchFragmentInteractionListener { + private static final String TAG = ShareActivity.class.getSimpleName(); + private static final String TAG_SHARE_FRAGMENT = "SHARE_FRAGMENT"; private static final String TAG_SEARCH_FRAGMENT = "SEARCH_USER_AND_GROUPS_FRAGMENT"; @@ -113,14 +117,34 @@ public class ShareActivity extends AppCompatActivity if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); doMySearch(query); + + } else if (UsersAndGroupsSearchProvider.ACTION_SHARE_WITH.equals(intent.getAction())) { + Uri data = intent.getData(); + doShareWith( + data.getLastPathSegment(), + UsersAndGroupsSearchProvider.DATA_GROUP.equals(data.getAuthority()) + ); + + } else { + Log_OC.wtf(TAG, "Unexpected intent " + intent.toString()); } } private void doMySearch(String query) { - // TODO implement + // TODO implement , or prevent that search may be sent without choosing from the suggestions list Toast.makeText(this, "You want to search for [" + query + "]", Toast.LENGTH_SHORT).show(); } + private void doShareWith(String username, boolean isGroup) { + // TODO implement + if (isGroup) { + Toast.makeText(this, "You want to SHARE with GROUP [" + username + "]", Toast.LENGTH_SHORT).show(); + + } else { + Toast.makeText(this, "You want to SHARE with USER [" + username + "]", Toast.LENGTH_SHORT).show(); + } + } + @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState);