2012-04-25 12 views
8

Ho un progetto di libreria che fornisce il codice di base per un numero di app che richiede tutte la stessa struttura e funzionalità del database e sto cercando il modo migliore per implementarlo. La mia preoccupazione principale è in realtà su come fornire un'autorità non statica, così posso sostituirla con il nome del pacchetto dell'app che utilizza la libreria.Android, provider di contenuti nel progetto di libreria

Così, nel progetto di libreria stavo pensando che potrei cambiare le seguenti costanti per i metodi statici che accetteranno un contesto che mi permetterà di ottenere l'autorità da una stringa di risorsa o dal metodo context.getPackageName

biblioteca modello di progetto

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"; 
} 

progetto di libreria fornitore di contenuti

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) io non capisco la STATI c {URI_MATCHER.addUR} dichiarazione e sto lottando per capire come posso convertirlo?

2) È questo l'approccio migliore per poter riutilizzare l'intera funzionalità in qualsiasi app? Se no, cosa sarebbe meglio?

+0

Per coloro che cercano la stessa domanda, sì, come indicato in questo [commento StackOverflow] (http://stackoverflow.com/questions/16268119/dynamically-set-the-authority-of-a- ContentProvider # comment23303216_16270100). – Sufian

risposta

0

ho sottoclassato UriMatcher con qualcosa di simile:

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

L'applicazione che usa la libreria dovrebbe dichiarare il fornitore nel manifesto con il proprio stringa di autorità.

È inoltre possibile sostituire gli oggetti Uri statici pubblici nelle classi modello con una funzione getUri(Context c) che crea l'Uri appropriata per tale applicazione.

Problemi correlati