Creating Your Own Content Provider Application (Part 1)

Jason Fedin
A free video tutorial from Jason Fedin
Instructor / Software Developer
4.4 instructor rating • 6 courses • 150,752 students

Learn more from the full course

The Essential Android O Developer Course (Java)

Learn everything in detail on how to write apps in Android O using Java

38:44:50 of on-demand video • Updated May 2020

  • Create and Run your first mobile application
  • Write Efficient and High Quality Android applications
  • Understand how to compile and test Android Applications using Android Studio
  • Learn all aspects of Android development from beginner topics to advanced
  • Learn how to Design and Implement Graphical User Interfaces in Android
  • Learn how to integrate databases into an android application to store persistent data
  • Learn how to submit apps to the Google Play Store and generate revenue with ads and in-app purchases
  • Learn about using Fragments for dynamic User Interfaces with multiple screen sizes
  • Understand how to implement mobile apps using the Java Programming Language
  • Learn Many more Android concepts!!!
English [Auto] Hello and welcome in this lecture I'd like to walk you through the implementation of creating your own content provider. So let's bring up Android studio. The first thing we're going to do is we're going to create a new project which will be our own content provider. So we're going to create a new project and we're going to name it my content provider. So let's close this one and start a new Android studio project. Let's call this my content provider since it's our own content provider that we're going to create. We're going to keep everything as the fault at the next bondmen API if teen if we're going to we're going to say add no activity because this is a content provider that accesses a database we don't need to have an activity for this. So we're going to say finish in it's going to create an empty project centrally our manifest file does not need to create any activities. And we don't need to have any layouts. All we need to have is a java source file. So we're going to go to our projects and we're going to go to source and we're going to create a new Java source file inside of a package. So we're going to name this my content provider or better yet my provider to say new or we're going to say new Java class and we're just going to say my provider and my provider is going to extend the content provider class because in order to create our own content provider we have to extend the content provider class right here. So we're off to a good start we're creating our new content provider our content provider is going to be wrapped. It's going to need we need to identify our data source the data source that we're going to need to communicate with his database. So before we implement the provider we have to implement the database. Let's create another class called database helper and this is going to be very similar to our database help or from our previous section so inside here we're going to name something database helper and the superclass for database help is going to be sequel IDE open helper and this class is going to be our interface to the database and it's going to be very very similar to our old section. So a lot of copying and pasting here this is extending our equal open helper. Remember from our last section that we have to create table and table columns and we have to create the database name and also the version. So let's add those as member variables and you'll see here that I'm creating my database schema I'm treating my table name employees I M-ID name and address for my columns my database name my employees the IDB and my version the other. The only other member variable we need is our database for sequel I don't the database. This is the instance that performs operations on the database operations. We then need to implement our constructor. Remember our constructor our sequel and open helper. It just it creates the new database. So when you create the database helper the database gets created if it hasn't been Kurri in the past. We also have to create our table query and then we know from the past that we in order to implement the sequel or the sequel I help or we have to implement two methods the concrete neon upgrade our sequel string Kuharich query to create the table. We're creating a Employees table and we're creating three columns are primary key id our name in our address we have to create the concrete in on upgrade. So we're going to add those are on concrete just creates the table an upgrade we'll drop the table and then call the uncreate to recreate the table because if we if we upgrade we're going to change the scheme on we have to recreate the table we're going to have opening close methods for our database the open method is going to get it right. The variable database calls method is going to close the database. We're also going to add our Cross operations we're going to add a Add method a query method update method and delete method so these methods will have to support the content provider. So you have to remember that for the answer method we're going to need to take a content values instance as a parameter for the query method we're going to need to take a projection a selection of selection ARGs in a sort order for the update we're going to take Qanta values selection and selection args. And for the dilly we're going to need to take selection selection arcs these Cross operations in our database. To be the same as the content provider Cross operations. They want to take the same parameters that those operations take. And if you remember from our previous lecture when we described these implementations in our content provider each one took specific parameters our Add method took content values instance. So when we implemented this database before our answer or add method took two parameters. The data that we wanted to insert now when our content provider calls this we just passed an account of values or content providers going to populate the conta values object and then call this method. So this method is pretty simple for our ad we just say database data and search and we insert the content value passed in his parameter the query method is also going to be somewhat simple because all the data are going to be popular and the content provider call. So he's going to take a projection a selection of selection ARGs in a sort order. We're then going to just say database query table name projects and selection selection and order. We're just passing in the data to the query method from what's passed into our database month and then we want to return the cursor. So again this is similar to our content provider our content provider has to return a cursor when it queries. So our database open helper is going to mimic that or update method is going to take content values a selection in the selection args and we're going to again pass those parameters into our update method on our database passing the data the table name and in all the other ones. And then we're going to return it. So these methods again are pretty simple because they're just wrappers the content provider is doing most of the work to populate the content values and the selection and the selection arcs. The last math we have to implement is the method to math it is going to take a selection and selection arcs and then call the methods on the database passing in those parameters and so the database portion is somewhat simple. We've already done this in a previous lecture and a previous exercise so we know what this is all about this. This instruction is all about implementing the content provider. So for now we're done with our database. Now we can go back to the provider. And so we've implemented the operations in our database but we haven't implemented the operations on our provider. Before we implement the crud operations our provider really should create a contracts class our contracts class to find exports all the data that clients can use the content you are by all the column names. So at this point I want to create another project a new Android project and let's make sure this one is saved. This new project is really just going to contain one class contracts a contract class. So let's say new project Let's call this one are my provider contract project. So my provider contract and we're going to leave the defaults same Apollo 15. We don't want to have an activity this is just a single class we're going to say finish. Now this class is going to be even simpler because it's going to contain one java file that contains static member variables. So we create a new java file inside of our package that I accidentally just want to make sure I didn't create a Leo. And inside here we're going to just say a new new Java class this class does not need to subclass anything. It's just my provider contract and this is going to define all our static member variables that can be accessed in other projects. So we have to define the authority the authority remember is our fully qualified class name or package name it has to be a static final variable. The reason to make a static final is we don't need an instance of this class to access it. And it's a it's never going to change. So we have all authority. Com example all user might provide a contact and actually this should be com example. J fed it. We then want to create our base path our base path as our table name or table name as employees. We then want to create our content you are I which includes the authority and the base path. So here we can just concatenate those two strings. Or you could call that nice method that we described in the lecture. Concatenation is just as easy. We can say constant you are equals you parse content colon slash class plus authority plus base path. Now remember that we also want to do updates and deletes in our content provider so we need to pass in an ID. What we're going to need to do is we're going to create need to create a content item type for that and a content type for our employees and we'll see how these become useful later on. So we're going to create a content type. And that's going to be pointing to our employees table. We then want to have a nother content item type that points to a single employee. And this will be used for the update and the delete. This is going to be used this content item type is going to be used when we want to pass in our ID as part of the path and that's it. This is our single class on our project. We don't need to do anything else with this project. This is a contract that exposes all our external data to our clients and our content provider is I want to make sure this is a library. I don't want it to be an Android app so if I go to my manifest file I can change this to be a library. Also when I created it I should have probably selected you can't select a library here. I could have created a new module here inside new module and then selected a library Android library. But since I didn't do that I can just convert it to a library by going to my cradle settings. So if I want to convert this right now this is an Android application because I want to use it in other Android applications. I want to change this to a library so I can go to my build Gretl module app settings and Word says apply plugin. I can change this to Android library. And then I also have to get rid of the application ID. And now this project will be a library so I can say sync now and when it builds this build us. Once it's done syncing with great will it will build a library. Sometimes besides this building if you want to generate an Android has libraries in it are the Java libraries a jar Nandor libraries a we can build the R and then link to it in another project. We go to View and we go to those windows when we go to great so we can select our app or module that we want to build as a library which is app and we can say assemble and when we say assemble this is going to generate an android archive file. You did it pretty quickly and that Android our car file is going to be located in our project directory. So if we go to my provider contract and I go to build or my provide a contract and I go to app and I go to build and I go to outputs we go to a car. We'll see that we have an ad or advocate that we can link to and other projects because remember this contract class needs to be seen in other activities. So now we're done we made this a library. We can use it in other projects so let's close this project and in our content provider Let's link to it. Well instead of linking to this project let's just import it because I may need to modify it. We could link to it as a or at iconv But if we want to import it we can just select file new and we can say import module and then we can go to our source directory of this module which is my provider contract. And the app module. So we'll have to rename the app module maybe my provider my provider contract and then say finish. So you notice that this will then be brought in as a app inside here. My provider contract we can modify and we can compile it if we just link to it we want to be able to modify it so we can see it. Now if we go back to our app when we go back to our my provider class or here we can import this package. We can say or better yet it can import automatically for us when we try to use it. So we know that the name of the class is my provider or my provider contract. So if we say my provider contract and then we say Authority we could be we should be able to import them so we can say Oh before we do that. So all we've done so far is we've included the project my provider contract we have an added dependency there yet. So we have the added dependency by selecting our project going to file project structure and then adding a dependency to our app which is my provider contract so we can Slyke the app we can say dependencies we can get the plus ball and we can say module dependency in here we can select my provider contract. Now we'll know to import it. So we hit okay there. Now we can use all those static member variables by saying my provider contract and accessing them like that. So now we have access to our contract. We can finish our implementation of our provider our providers implementation is we're going to need to date need a member variable for our database helper. So we want to add that that's private. We also need to create a match or object that you are matchers going to make sure that we only accept the request from valid content. Your eyes. So we're going to create a you are a match for instance and we're going to initially say no match we can use this you are a matcher to to make sure that our content you are that are being invoked by our clients our matches that we're only going to operate on two tables or one table the employees table or an employee that passes an ID. So we're going to create a static block here and we create a static lock here because we only want this to be called once. So in the static block here we're going to add the two most the two value our eyes to this class the two valid you are of the authority with the base path. This is our employees. And then the other valid you are that we're going to accept from clients our authority base path and then a slash number to slash number means an ID so we're going to add those to our you are matcher. And then in our quirky math in our methods we're going to make sure that if we get any requests from either of these two we can only we can only allow requests from either of these two and then we'll do something specific. So this is just a matter to make sure that our clients are calling the right content. And if we get requests from other eyes we're not going to do anything. We're trying to match the valid ones and remember we have to content you eyes for this class this provider we have our employees table and then we have our employees table with the number in I.D. in order to do updates and deletes. So we have to first implement the ice cream at that the ice cream method is just going to create the database. And I know it's sad that we don't want to do creation of databases on create what that really means is we don't want to we don't want to get the ridable database because that's an expensive operation. Creating the database by itself is fine and it only happens once when the content provider gets initialized. We want to do the get ridable database in our current operation so here in our and create We're just going to create our new database helper. We then have to implement the operations and then once we implement the operations our content provider has been completed. We then need to use it. So let's implement the well before we implement the current operations. The other method that we have to implement for a content provider is to get type and get type. Usually we'll check the mime type and then return the right content. You or I but we're not going to do that we only have to content your eyes. We're just going to return all we're not going to check any type. This would again return the correct type. This is more of a helper method. So we're not going to implement this our answer method or query method which will implement first the query method takes specific parameters that we're going to we have to override this method because remember we're a subclass of the content provider so we have to override insert update delete and query so the query method takes you by the projection selection selection Sargent's order the selection and selection of the WHERE clause and the projection is the tables that we want to look at the sort order is how you're going to sort the data. So inside here the first thing we have to do is we have to make sure we have to determine where are the queries coming from. Is the query meant to be for the all the employees or is it meant to be for a single table. Well we are not going to support queries for a single table. We're going to only return all the employees if you wanted to do a query that passed in an ID and return to one record we could support both of our content you ours but for Querrey we're just going to support the employees table. So we're going to have a switch statement that checks whether or not we have a match on that you are passed in. So the you are that's passed into the Korie method. This is the clients you are. This is what the clients you are calling now is the client calling the employee's content you are to retrieve all or is a calling an ID. So here the other important thing to notice is when we added Are you our eyes our last parameter is our code. We can put anything in here and then we can use that code to do our matching. So for our employees table used for the update or we use for the query in answer we're just going to say that's one for the update delete. We're going to say that's 2 in the Update Delete can actually handle both. You can update multiple records without a WHERE clause or you can update a single record with a where clause when you update a single record with a where clause you're going to look for you are too. So the query method we're only going to need to match our first content. You or I if we match our first Konting you we're good to go if they try to call a content if they try to call a client tries to call the query method and passes in an ID we're going to throw an exception because that's not valid for query. So now that we've checked that the UI is good. We then all we need to do is open the database and call the query method on the database so we can say my help are not open we could say cursor CT cursor call the query on our database. Passing in the parameters that were passed into the query month. Pretty simple last thing we want to do is we just want to make sure that our listeners are getting notified. So we're going to call set notification your. And then we're going to return the cursor up and we've implemented our query method for our content provider. The next method we're going to implement is the insert. The answer it's going to be similar to the query in that you can only call an insert method if the client's UI is asking for the employees table. So we're going to get our long Id equal to zero and we're going to see my help or not open and we're going to now check for case one member case one is our employees content you buy if they passed in case one we can just say my help or die ad ad in the content values that were passed in. So remember the client populates those content values we just added to the database. If they try to call this entire method with the content UI for a single employee We're going to throw an exception. Also let all the listeners all the clients know so we're going to call notify change and then remember that the answer math that we have to return to you are I. And what do we want to return for the insert method to the client. We're required to return the ID value of what was inserted. So we're going to have to return. Are you are I with an idea appended to it. And so we're going to have to return. You are not parse the base path which is our employees path and then slash and then we're going to pass in the ID in the ID remember was returned from the Add method. The database insert method returns the ID we're going to send the ID back to the client we're required to do that from the interface. So our daily method is going to take you a selection and during selection hours we want to check that you are I and before we checked to you I would just want to create a couple a local variable called rows deleted because this has to be returned on how many deleted rows when we want to open up the database first because we don't want to open it twice and have duplicate code for each match. We could support both. We're going to only allow deletes from a single user or a single single record. This is passing in the ID and we're going to match case to. This is when they pass the idea on for the content you are the client and if they pass the I.D. and we're going to simply update or call the delete method with that ID. So for Case 2 we're going to create a string I.D. because we need to first parse out the ID from the UI that was passed in because remember the client's going to pass in the ID that they want to update in the path. So we can say you are not get last pass segment. This will parse out the ID. We could then use that in the delete method. We're going to call database helper with the ID equal to the ID and we're going to say selection are equal to none. So text you Eutelsat MT is checking the selection so you can pass an ID with a where clause or you can just pass in a single ID so now that we've implemented that we want to also inform on the fall kids that will throw an exception if they try to call it different content you or I. We're not going to allow multiple deletes for deleting many rows unless they pass in selection. It's just not necessary we're going to only delete a single record. We want to notify our clients of a change and then return the rows deleted so we can just say return rows delete it. So now we have our tally method implemented the last method we have to implement is the update the update method is going to be similar to the delete. The update is going to take are you are a content value selection selection. We're going to create a local variable for rows of data and we're going to open the database. We're then going to need to match the appropriate time. And if we're going to support both cases here we're going to call 1. So for if the user passes in all the employees to update all the employees we're just going to call update with all the values. If the UI is only updating a single employee We're going to get out the I.D. passed in we're going to check if the selection is empty. If it is we don't need to set the selection. If it isn't we're going to set the selection arx selection Plus the selection Ark's member selection is the where clause where you have a column name equal to a question mark the selection is interpret the question mark. So we're calling up the values on our helper. And if we don't get passed in either one of those cases we're going to throw an exception. Last thing we need to do is we need to notify the change and then return the rows updated something like that. We're almost done. The last thing we need to do is we need to modify our manifest manifest file to identify this application as a provider. So if we go to manifest and we specify We want to add the permission label permission element with our name in our authorities. And we also want to set a couple of attributes for export it. So and the manifest after the inside of the application tag on to any application we can add the provider element we say provider. We set the name equal to my Dom my provider which is our class name. We have our authority set to the package name which is Khandaan example the fat in my content provider we set the Enabled property through export it is true and grant you our permissions to true. And then we want to add. And our application. So now we want to build make sure that we can build and then we want install in the emulator. And now we're done with our content provider we've implemented everything that we need to implement. So this is an application that will need to be installed on the device or the emulator. It doesn't have an activity. The last thing we really need to do is we need to change the configuration when we install the app so we can go to the run method and we can say edit configurations inside out of configurations for this app we can say we don't need a default activity so we can just say nothing. This will install our app and it will be running on the device without an activity. When we install it there will be installed that won't always be running but it will be installed. And now then when we put this on the emulator we can use it. So we should install this on the emulator I guess just to make sure we don't forget when we use our client so we covered a lot in this lecture. We've covered creating a contract class and exposing it so important as a module in another activity so we can access those static variables we create a large database helper class inside our content provider that was pretty basic. And then we created our own content provider by subclassed and the content provider and implementing the operations in the concrete in the GET type. The lectures run quite a bit long here. So we're going to have another lecture where we're going to use this content provider we're going to create the application that we create for a database helper our database example application to modify update and in and and delete records difference differences we're not going to access a sequel I don't and help A-class we're going to use our content provider so thank you.