Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android, content provider in library project

I have a library project providing the base code for a number of apps that all needs the same database structure and functionality and I'm looking for the best way to implement this. My main concern is really about how to provide a non static authority so I can override it with the package name of the app that uses the library.

So in the library project I was thinking I could change the following constants to static methods that will accept a context that will allow me to get the authority from a resource string or from the context.getPackageName method

library project model

    public static final class Questions implements BaseColumns {
//      public static final Uri CONTENT_URI =
//          Uri.parse("content://" + Config.AUTHORITY + "/questions");
//  use getAuthority instead which in turn will just get the package ae. Will this work?
        public static Uri getContentUri(Context c){
            return Uri.parse("content://" + getAuthority(c) + "/questions");
        }
    ...
    }

public static String getAuthority(Context c){
    return c.getPackageName + ".QuizProvider";
}

library project content provider

public class QuizProvider extends ContentProvider {

//    private SQLiteDatabase mDB;

    private static final String TAG = "MyLog";

    private static final String DATABASE_NAME = "quiz.db";

    private static final int DATABASE_VERSION = 1;

    private static final int QUESTIONS = 1;
    private static final int QUESTION_ID = 2;

    private static final UriMatcher URI_MATCHER = new UriMatcher(
        UriMatcher.NO_MATCH);

    private static Map<String, String> QUESTION_LIST_PROJECTION_MAP = null;

    private DatabaseHelper mOpenHelper;

    /**
     * This class helps open, create, and upgrade the database file.
     */

    private static class DatabaseHelper extends SQLiteOpenHelper {

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        int match = URI_MATCHER.match(uri);
        switch (match) {
        case QUESTIONS:
            return insertQuestion(values);
        ...
        }

...
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

        switch (URI_MATCHER.match(uri)) {
        case QUESTIONS:
            qb.setTables(QuizModel.Questions.TABLE_NAME);
            qb.setProjectionMap(QUESTION_LIST_PROJECTION_MAP);
            break;
...
        }

//How do I change this?    
        static {
            URI_MATCHER.addURI(Config.AUTHORITY, QuizModel.Questions.TABLE_NAME, QUESTIONS);
    ...
            QUESTION_LIST_PROJECTION_MAP = new HashMap<String, String>();
    ...
        }

1) I don't really understand the static { URI_MATCHER.addUR } declaration and am struggling to understand how I can convert this?

2) Is this the best approach to be able to reuse the whole functionality in whatever app? If not what would be better?

like image 607
jamesc Avatar asked Apr 25 '12 17:04

jamesc


People also ask

What is a content provider Android?

A content provider manages access to a central repository of data. A provider is part of an Android application, which often provides its own UI for working with the data. However, content providers are primarily intended to be used by other applications, which access the provider using a provider client object.

What are content providers how do you create your own content provider in Android?

Create Content Provider First of all you need to create a Content Provider class that extends the ContentProviderbaseclass. Second, you need to define your content provider URI address which will be used to access the content. Next you will need to create your own database to keep the content.

What is the use of content provider in Android Studio?

Content providers are one of the primary building blocks of Android applications, providing content to applications. They encapsulate data and provide it to applications through the single ContentResolver interface. A content provider is only required if you need to share data between multiple applications.

What is content provider in Android and how is it implemented?

A content provider manages access to a central repository of data. You implement a provider as one or more classes in an Android application, along with elements in the manifest file. One of your classes implements a subclass ContentProvider , which is the interface between your provider and other applications.


1 Answers

I subclassed UriMatcher with something like this :

private static final UriMatcher sUriMatcher
        = new UriMatcher(UriMatcher.NO_MATCH){
    @Override
    public int match(Uri uri) {
        return super.match(uri.buildUpon().authority(AUTHORITY).build());
    }       
};

The app which uses the library should declare the provider in the manifest with it's own authority string.

You can also replace the public static Uri objects in your model classes with a getUri(Context c) function which creates the Uri appropriate for THAT application.

like image 120
Ridhish Guhan Avatar answered Sep 30 '22 15:09

Ridhish Guhan