[MUSIC] Welcome to part one in our lesson to Developing a Content Provider in Android. After completing this part of the lesson, you'll understand all the steps involved in developing a content provider. We focus on steps 1 through 3 in this part of the lesson. You'll also recognize how to apply these steps to implement the HobbitContentProvider to use as a case study throughout this module. Let's first start by talking about the Steps for Creating a Content Provider. >> So there's a number of steps involved in building a content provider. We're going to go through these steps in detail this is just an outline of the steps. First, we're going to talk about how to analyze your requirements to see if you really need a content provider in the first place. We'll then talk about designing the data model, defining the contracts class, which is really the embodiment of the data model. We'll talk about how to design the format of content URIs to access managed data. We'll talk about how to implement the provider as some classes which is going to involve subclassing the content provider to define the content and provider class. To define an interface between the provider and other application logic which could be another applications or the same application. We'll talk, briefly, about implementing this storage system. That was really the topic of last lecture on SQLLite, so I'm not going to go through that very much here, just referencing it. We'll talk about implementing change notifications and when you would want to do this. And then, finally, of course, declaring the content provider in the AndroidManifest file, so that it can be visible and accessible by either your application and or other applications. So let's first start by talking about whether or not you need a content provider at all. Obviously, we're looking at the description and the discussion form. Lot of people somewhat confused as to when should be using a content provider or if we even need one at all. So here are some considerations to think about which are a generalization of what's here on the Android site. To think about when you are wrestling with the question of whether to make a content provider or not. So here are some of the reasons why you would want to do one. So, one reason you might want to do it is that you want to offer complex data or files to other applications. So, a cache of recently downloaded images or acronyms, might be one example, or weather, as we've been doing in the various examples. Do you want to access and expose contact data or calendar events or SMS messages or email? All the kinds of things that Android typically does with their content providers, so that would be one reason to use one. Even if you're not trying to offer complex data or files to other applications, you might want to decouple the common data access API. Which is what the content provider gives you, from the underlying In data storage mechanisms use to implement that API. So, you might not want to have to hard coat in your program whether you are using SQLite or flat files or remote network storage or ConcurrentHashMap or whatever. You want to make those decision implementation decisions. Now obviously, there are other ways to do this besides using content providers. You can use patterns like the bridge pattern and so on, but the nice thing about using the content provider is it's a well understood interface that people have come to know and love. And so by doing it that way, you're following a common set of conventions and patterns that are part of Android's fundamental software architecture and component architecture. Another reason you might want to use the content provider is you want to provide custom search suggestions for your app. Many applications in Android provide this capability using Android's search framework. And you can read at this link for more information about the Android's search framework. But all the typical application, there's many typical applications like the browser, contacts, music player, YouTube, maps, books. All kinds of things will keep track of custom search suggestions based on your recent searches. And so the content providers are very, very natural way to do that. There's even framework built in to Android to make it easy to do. Another reason you might want to use a content provider as you want is synchronize local data at a local store. Like an SQL-like database with remote data which would be residing in a web service, on a web service somewhere. And this diagram kind of illustrates the overall architecture of such a thing using Android's sync adapter framework. So in this model, you have activities that go ahead and do various CRUD operations to insert things and query them and so on into a content provider. And then you have a SyncAdapter which periodically figures out which items to sync and when this thing starts up. It talks via REST mechanisms to services and those services do various kinds of things. And then when results come back from the web service, they can be inserted back into Content Provider. And then made accessible to the activity via CursorAdapter using ContentObserver notification and other means. You read more about SyncAdapters here. We'll cover SyncAdapters in the next MOOC. And then finally, you want to have your activities notified automatically when data changes via a ContentObserver. So if the answer to any of these questions is yes, then you probably want a Content Provider. If the answer to these questions is always no, then, you may not want a Content Provider. If you don't store data persistently, of course, then it may be overkill to use a Content Provider. Likewise, if you want to use some kind of object relation mapping tool, some kind of ORM tool, to access an SQLLite database directly, then you may not want to use a Content Provider. So it's not something you're forced to do, but If you look around in the Android source directory and packages apps. You'll find lots and lots of examples of content providers that are used for all kinds of interesting reasons in Android. Okay, next thing is let's talk about designing the data model. So a Content Provider typically presents its data via one or more cables. Here is a simple cable from the Hobbit content provider that stores the name of the characters, their race and an ID to keep track of where they are in the table. And so that's a simple example of a table. Each column represents a type of data such as the name or the race of a Hobbit character. Each row represents an instance of some type of data that the provider manages, such as the name and race of a particular Hobbit character like Gandalf, who's a Maia or wizard. And then each column in a row represents Is an individual piece of data collected for an instance. For example, Thorin, the race of Thorin is Dwarf and so, that's basically how you think about this. Really these are basically like objects, you can think of a database or a table as basically an object store where each row are the values of the object's fields. That's of course sort of an objection-relational mapping view of a table. The next thing you need to do is to find a contracts class, which is a public final class that contains a bunch of constant definitions and or static methods that do various things. And you can learn more about contract classes here in the content provider documentation. Some of the things you go in there are the authority,URIs,the column names,the MIME types and any other meta-data that pertain to a Content Provider. .So basically, the contract class is establishing a contract,easy to work mostly. Between the provider and other applications to ensure the provider can be accessed correctly even if the underlying implementations change, or the particular values change. So, the contracts class is exposing constants that are then going to be used by your application, even if the underlying names will change, the application won't change. Column names are typically identical to the SQL database column names. The Contracts class documents this kind of stuff so that the clients know how to read the data. Here's how you could use the Hobbit Content Provider to have some columns like name and race that we just looked at so that you could access those in your application code. You need to have an ID named _id with a constant _ID. That's an integer and that's the column that's the ID column and you get that trivially by implementing the base columns interface. And if you look at base columns you can see that it's got the public final static string under score ID in caps which is equal to the under score ID string. And that's what defines the ID field which every cable needs an ID column. This ultimately maps onto an integer that's a primary key in the table, and it's defined as being an auto increment. So it'll go ahead and automatically update itself and so that's basically how that would map into the table. You wanted to find the MIME types for items in directories. These are used to indicate to users at the contract provider what kinds of data, what type of data is stored. And if you recall the Hobbit's content provider example, it illustrated it had to do all this with some constants. Contents item type which is the directory or the group of rows or content item type which is the type of an individual row. ContentProvider.getType returns the String in MIME format and this basically describes the type of data that's returned by the content URI argument. For content URIs that point to row or rows of table data, getType() should return a MIME type. So here's the example from the Hobbit application where the get tight method that is defined on the content provider should figure out what the URI is requesting. And then return the appropriate type which is either items typed or item typed, depending on whether they're looking for multiple or individual entries. If your provider offers files, and ours doesn't, but if yours did then you want to implement the getStreamsType. And this returns a Strings array of MIME types for files that your provider can return for a given content URI. And so here's an example, let's assume you have a provider that offers photo images as files, in various formats. So if someone calls getStream with the filter string image* then you should give back all the different kinds of images that your content provider supports. If somebody calls with just "*/jpeg", then you just give back "image/jpeg". So this is just a way for the system to figure out what types of data your Content Provider supports. Oftentimes in practice, you don't need to use this information, because you already know, by virtue of the fact that you know what kind of content provider you're talking to. But there's ways of being able to do more sophisticated filtering and tooling that would query all the content providers to see which ones match. Such as the kind of thing that is done with Android intent filter resolution for providers. >> So this concludes part one of our lesson on developing a content provider in Android. [MUSIC]