I am buidling a uriPatternMatcher for my content provider.
My uri is like content://com.example.wordapp/wordlist?flashid=1 which I got using Logger statement.
What should be my pattern matcher?
I tried
public static final String CONTENT_AUTHORITY ="com.example.wordapp";
public static final Uri BASE_CONTENT_URI =Uri.parse("content://"+CONTENT_AUTHORITY);
public static final String PATH_WORD ="wordlist";
public static final String FLASHCARD_ID="flashid";
matcher.addURI(authority, WordContractClass.PATH_WORD + "?"+ WordContractClass.WordListEntry.FLASHCARD_ID+"=#", WORD_WITH_FLASH_LIST);
The matcher is showing output as No Match Found.
You are adding the pattern incorrectly. From the documentation of UriMatcher(http://developer.android.com/reference/android/content/UriMatcher.html), you see that your second argument should be the path and third one should be the code against which your uri should be matched.
I am not sure what exactly you are trying to match but yours should look something like:
// assuming pathWord is the path to the list and WORDS_WITH_FLASH_LIST is the code that will be returned on a successful match
matcher.addURI(authority, pathWord + "/#", WORDS_WITH_FLASH_LIST);
The "#" implies that there are multiple entries within this path. You do not need the "?" that you currently have.
Related
I am developing a Weather app ,in that trying to build Uri that looks like
Content://com.example.weather.app/Location/locationName?Date=12012017
The documentation says Uri reference has pattern as ://?#
trying to understand this following code
public static Uri buildWeatherLocation(String locationSetting) {
return CONTENT_URI.buildUpon().appendPath(locationSetting).build();
}
public static Uri buildWeatherLocationWithStartDate(
String locationSetting, long startDate) {
long normalizedDate = normalizeDate(startDate);
return CONTENT_URI.buildUpon().appendPath(locationSetting)
.appendQueryParameter(COLUMN_DATE,Long.toString(normalizedDate)).build();
}
what is the actual difference and when we use appendPath() and appendQueryParameter() methods?
why can't we use appendQueryParameter() for locationSetting ,bit confusing suggestions plz
appendPath() is for path segments and appendQueryParameter() for query params with key value (in your example Date=12012017).
Check this link for more info and examples:
Use URI builder in Android or create URL with variables
appendQueryParameter is for query string parameters and appendPath is for site path
Implementation of Content Provider with a complicated queries required a complex uri patterns, and i don't understand how can i handle this.
Can i use Regular Expression in my patterns? example: /user/:[a-zA-Z]/timeline/ if the user must contain only letters.
Which symbols tells the UriMather what the parameters example: /user/:userId/timeline/year/:yearNumber, i would get userId and yearNumber as parameters , so how do i should get the values ? should i use getPathSegments() and get the parameters manually?
or if i used /user/#/timeline/year/# how do i extract the # values
By using the format /user/#/timeline/year/# you can call:
uri.getPathSegments().get(1); // To get the first #
uri.getPathSegments().get(4); // to get the second #
// 0 -> user, 1 -> first #, 2 -> timeline, 3 -> year, 4 -> second #
So in your content provider you would have something like this:
private static final int USER_TIMELINE_YEAR = 1;
// ...
private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static
{
uriMatcher.addURI(PROVIDER_NAME, "user/#/timeline/year/#", USER_TIMELINE_YEAR);
}
// Usually a ContentProvider method like query, insert, delete and update
public void someMethod(Uri uri) {
if(uriMatcher.match(uri) == USER_TIMELINE_YEAR) {
String userId = uri.getPathSegments().get(1);
String timelineYear = uri.getPathSegments().get(4);
}
}
Check https://developer.android.com/guide/topics/providers/content-provider-creating.html and https://developer.android.com/reference/android/content/UriMatcher.html
Can anyone tell how can I create a ContentProvider which can query multiple database/ContentProviders for search suggestions provided by SearchView.
With ContentProviders, you are querying for data using a ContentUrl which would look something like this
content://<authority>/<data_type>/<id>
authority is the content provider name, e.g. contacts or for custom one will be com.xxxxx.yyy.
data_type and id are to specify what data you need from the provide and, if needed, a specific value for the key.
So, if you are building your custom content provider you need to parse the content uri which you get as a parameter in the query function and decide what data you need to return as Cursor. UriMatcher class is very good choice for this case. Here is an example
static final String URL = "content://com.mycompany.myapp/students";
static final Uri CONTENT_URI = Uri.parse(URL);
static final UriMatcher uriMatcher;
static{
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI("com.mycompany.myapp", "students", 1);
uriMatcher.addURI("com.mycompany.myapp", "students/#", 2);
}
then in your query function, you would have something like this:
switch (uriMatcher.match(uri)) {
case 1:
// we are querying for all students
// return a cursor all students e.g. "SELECT * FROM students"
break;
case 2:
// we are querying for all students
// return a cursor for the student matching the given id (the last portion of uri)
// e.g. "SELECT * FROM students WHERE _id = n"
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
I hope this answers your question and direct you to the right track.
You can see a good article with full example about how to use them, here
http://www.tutorialspoint.com/android/android_content_providers.htm
I would like to read your thoughts on how to solve the following problem. Here are the basic requirements of the application I am working on.
Display multiple locations one city on a map.
Support for multiple cities.
Display the properties of a location on a separate details view.
Location properties of each city differ.
I would like to implement a flexible decision logic that switches between cities based on the location that the map is at. That means, the initial information I rely on, is the map center. Here is the theoretical workflow.
Get the current center location from the map.
Translate the location into a city url and uri.
Download locations via HTTP using the url.
Store the locations in local database. One table for each city since location properties differ.
Load cached or downloaded data from a content resolver using the uri.
Create overlay items and include the uri reference and a unique id.
Open a details view when tapping on a location.
The details view should render the city specific location properties.
The location properties again are loaded via a content resolver based on the passed uri and unique id.
Questions:
I am particular interested on how you would switch cities, query parameters such as column names using the UriMatcher class.
Would you prepare one details view for each city? Or do you see any practical solution to swap text fields, label, .. based on the available property information?
To illustrate the different properties, here are two example cities and a content provider.
Example:
public class DatabaseParis {
public static final class Contract {
public static final String COLUMN_LATITUDE = "latitude";
public static final String COLUMN_LONGITUDE = "longitude";
public static final String COLUMN_NAME = "name";
}
And another city ...
public class DatabaseDenver {
public static final class Contract {
public static final String COLUMN_LATITUDE = "lat";
public static final String COLUMN_LONGITUDE = "lon";
public static final String COLUMN_HEIGHT = "height";
public static final String COLUMN_DIAMETER = "diameter";
}
And a content provider ...
public class CustomContentProvider extends ContentProvider {
public static final class Contract {
public static final Uri URI_PARIS = Uri.parse("content://" + AUTHORITY + "/cities/paris");
}
private static final String AUTHORITY = "com.example.cities.locations";
private static final int URI_CODE_PARIS = 0;
private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
static {
URI_MATCHER.addURI(AUTHORITY, "cities/paris", URI_CODE_PARIS);
}
I am unsure about using one or multiple content provider since I read putting all database references into one can be a problem when the data should be synced in the future.
I guess one who deals with such a scenario should consume the following information sources.
Developing Android REST client applications, Virgil Dobjanschi, Google I/O San Francisco, 2010
ContentProvider and REST API, Benjamin Brombach, Android UserGroup Berlin, 2012
I am just wondering what is the format in Zxing.
String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
Do you think I can delete this line of code?
According to the latest version in the trunk:
/**
* Call intent.getStringExtra(RESULT_FORMAT) to determine which barcode format was found.
* See Contents.Format for possible values.
*/
public static final String RESULT_FORMAT = "SCAN_RESULT_FORMAT";
Contents.Format actually doesn't exist (anymore), but browsing through the code it seems fair to assume the "formats" have been replaced by "types". Contents.Type defines the following possibilities:
public static final String TEXT = "TEXT_TYPE";
public static final String EMAIL = "EMAIL_TYPE";
public static final String PHONE = "PHONE_TYPE";
public static final String SMS = "SMS_TYPE";
public static final String CONTACT = "CONTACT_TYPE";
public static final String LOCATION = "LOCATION_TYPE";
In other words: it gives you information about the type of data that is encoded by the scanned barcode. If you don't care about the type, you can simply ignore it.
This is a string naming the format of the barcode scanned, like "QR_CODE" or "UPC_A". Values come from the class BarcodeFormat. Can you remove it? sure, don't write this line of code if you don't need it!
Are you talking about using the intent integrator? If so, this is the kind of barcode that you just scanned. I don't know what your purposes are, but if you want to support more barcodes, you might want to consider this line more important.