Example 1 – one-to-many relation ContentProvider

With the commercial version of the developer tool you can create Android ContentProvider implementations from the meta model. The system generates the create/read/update/delete methods and the neccessary UriMatcher for accessing the data. The notification API is implemented for all operations. For efficient bulk operations an interface without notifications is provided as well.
The example shows how the ContentProvider-API is used by the generated code. The required SQL parameters for the primary keys are of course created in accordance to the data model. This secures the interface consistency for bigger datamodels.

The system creates as many DataProvider implementations as required and groups the desired business objects within the providers. This includes the definition of content URI matching the schemas. The notifyinterface of the ContentResolver is implemented, but need not to be used to avoid frequent events during batch updates.

  • package com.uc_mobileapps.seifesample01.provider;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteQueryBuilder;
    
    import com.uc_mobileapps.seifesample01.db.CustomerDB;
    import android.content.ContentProvider;
    import android.content.ContentResolver;
    import android.content.ContentUris;
    import android.content.ContentValues;
    import android.content.UriMatcher;
    import android.database.Cursor;
    import android.net.Uri;
    
    import com.uc_mobileapps.seifesample01.bo.Customer;
    import com.uc_mobileapps.seifesample01.bo.schema.CustomerSchema;
    
    /**
     * Content provider implementation for the list of shortcuts
     */
    public class CustomerProvider extends ContentProvider {
    
      /**
       * Pass a query limit to the provider
       */
      public static final String QUERY_PARAMETER_LIMIT = "_limit";
    
      /**
       * Pass a having clause to the provider
       */
      public static final String QUERY_PARAMETER_HAVING = "_having";
    
      /**
       * Pass a group by to the provider
       */
      public static final String QUERY_PARAMETER_GROUP_BY = "_groupby";
    
    
      /* (non-Javadoc)
       * @see android.content.ContentProvider#onCreate()
       */
      @Override
      public boolean onCreate() {
        if (!seifeCreate()) {
          return false;
        }
        return true;
      }
    
      //{{@begin seife autogenerated
      
      /**
       * Content-Provider Authority for Uris (is in the demo package for historical reasons)
       */
      public static final String AUTHORITY = "com.uc_mobileapps.seifesample01.provider";
    
      /**
       * Better don't use this directly, use {@link #getContentUriCustomer()} instead
       */
      public static Uri CONTENT_URI_CUSTOMER = Uri.parse("content://" + AUTHORITY + "/" + CustomerSchema.TBL_CUSTOMER);
    
      /**
       * Uri for shortcut
       */
      public static Uri getContentUriCustomer() {
        return CONTENT_URI_CUSTOMER;
      }
      
      /**
       * Explicit URI configuration
       */
      public static void setContentUriCustomer(Uri uri) {
        CONTENT_URI_CUSTOMER = uri;
      }
    
    
      /**
       * Code for urimatcher of the content provider
       */
      protected static final int URI_CODE_CUSTOMER = 0;
      /**
       * Customer by id uri
       */
      protected static final int URI_CODE_CUSTOMER_ID = 1;
    
      /**
       * Customer for batch updates
       */
      protected static final int URI_CODE_CUSTOMER_NO_NOTIFY_ID = 2;
    
      
    
      /**
       * The database helper class where the table definitions reside
       */
      private com.uc_mobileapps.seifesample01.db.CustomerDB dbHelper;
    
      /**
       * Autogenerated provider onCreate
       * @see CustomerProvider#onCreate()
       */
      public boolean seifeCreate() {
        dbHelper = new com.uc_mobileapps.seifesample01.db.CustomerDB(getContext());
        return true;
      }
    
      /**
       * Uri Matcher of the content provider
       */
      private UriMatcher uriMatcher;
    
      /**
       * @return
       */
      protected UriMatcher getUriMatcher() {
        if (uriMatcher == null) {
          uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    
          uriMatcher.addURI(AUTHORITY, CustomerSchema.TBL_CUSTOMER, URI_CODE_CUSTOMER);
          uriMatcher.addURI(AUTHORITY, CustomerSchema.TBL_CUSTOMER + "/#", URI_CODE_CUSTOMER_ID);
          uriMatcher.addURI(AUTHORITY, CustomerSchema.TBL_CUSTOMER + "/batch/#", URI_CODE_CUSTOMER_NO_NOTIFY_ID);
        }
        return uriMatcher;
      }
      
      /**
       * (non-Javadoc)
       */
      @Override
      public String getType(Uri uri) {
        switch (getUriMatcher().match(uri)) {
     
        case URI_CODE_CUSTOMER:
          return ContentResolver.CURSOR_DIR_BASE_TYPE + "/vnd." + Customer.class.getPackage() + "." + CustomerSchema.TBL_CUSTOMER;
        case URI_CODE_CUSTOMER_ID:
          return ContentResolver.CURSOR_ITEM_BASE_TYPE + "/vnd." + Customer.class.getPackage() + "." + CustomerSchema.TBL_CUSTOMER;
        case URI_CODE_CUSTOMER_NO_NOTIFY_ID:
          return ContentResolver.CURSOR_ITEM_BASE_TYPE + "/vnd." + Customer.class.getPackage() + "." + CustomerSchema.TBL_CUSTOMER;
        }
        return null;
      }
    }
    

  •   /**
       * Inserts a new object to the database
       * @return the uri of the created object, null if the mandatory check failed 
       * @see android.content.ContentProvider\#insert(android.net.Uri, android.content.ContentValues)
       */
      @Override
      public Uri insert(Uri uri, ContentValues values) {
        
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        long rowId;
        switch (getUriMatcher().match(uri))
        {
        case URI_CODE_CUSTOMER:
          if (!CustomerSchema.instance().checkConstraints(values)) {
            return null;
          }
          rowId = db.insert(CustomerSchema.TBL_CUSTOMER, null, values);
          if (rowId > 0) {
            Uri resUri = ContentUris.withAppendedId(uri, rowId);
            getContext().getContentResolver().notifyChange(resUri, null);
            return resUri;
          }
          break;
        case URI_CODE_CUSTOMER_ID: //unimplemented since id is generated
          break;
        }
        return null;
      }
      // [ CRUD Operationen ]
    }
    

  •   /* (non-Javadoc)
       * @see android.content.ContentProvider\#query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String)
       */
      @Override
      public Cursor query(Uri uri, String[] projection, String selectionParam,
          String[] selectionParamArgs, String sortOrder) {
        StringBuilder selection = new StringBuilder();;
        List<String> selectionArgs = new ArrayList<String>();
        
        String groupBy = uri.getQueryParameter(QUERY_PARAMETER_GROUP_BY);
        String having = uri.getQueryParameter(QUERY_PARAMETER_HAVING);
        String limit = uri.getQueryParameter(QUERY_PARAMETER_LIMIT);
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
    
        int matchId = getUriMatcher().match(uri);
        switch (matchId)
        {
        case URI_CODE_CUSTOMER:
          qb.setTables(CustomerSchema.TBL_CUSTOMER);
          selection.append(selectionParam);
          selectionArgs = Arrays.asList(selectionParamArgs);
        break;
        case URI_CODE_CUSTOMER_ID:
        case URI_CODE_CUSTOMER_NO_NOTIFY_ID:
          qb.setTables(CustomerSchema.TBL_CUSTOMER);
          selection
          .append(CustomerSchema.COL_ID + " = ?");			
                selectionArgs.add(uri.getQueryParameter(CustomerSchema.COL_ID));
        break;
        default:
          return null;
        }
    
        Cursor c = qb.query(dbHelper.getReadableDatabase(), projection, selection.toString(), selectionArgs.toArray(new String[selectionArgs.size()]), groupBy, having, sortOrder, limit);
    
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;
      }

  •   /* (non-Javadoc)
       * @see android.content.ContentProvider\#update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[])
       */
      @Override
      public int update(Uri uri, ContentValues values, String selection,
          String[] selectionArgs) 
      {
        int rowsAffected = 0;
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int matchId = getUriMatcher().match(uri);
        String[] primaryKey;
        switch (matchId)
        {
        case URI_CODE_CUSTOMER_ID:
        case URI_CODE_CUSTOMER_NO_NOTIFY_ID:
          primaryKey = new String[] { uri.getQueryParameter(CustomerSchema.COL_ID) };
          rowsAffected = db.update(CustomerSchema.TBL_CUSTOMER, values,  CustomerSchema.COL_ID + " = ?" , primaryKey);
          break;
        default:
          break;
        }
        if (rowsAffected > 0) {
          switch (matchId) {
          case URI_CODE_CUSTOMER_ID:
            getContext().getContentResolver().notifyChange(uri, null);			
            break;
          default: 
            break;
          }
        }
        
        return rowsAffected;
      }
    

  • /* (non-Javadoc)
       * @see android.content.ContentProvider\#delete(android.net.Uri, java.lang.String, java.lang.String[])
       */
      @Override
      public int delete(Uri uri, String selection, String[] selectionArgs) {
    
        int rowsAffected = 0;
    
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        String[] primaryKey;
        int matchId = getUriMatcher().match(uri);
        switch (matchId)
        {
        case URI_CODE_CUSTOMER_ID:
        case URI_CODE_CUSTOMER_NO_NOTIFY_ID:
          primaryKey = new String[] { uri.getQueryParameter(CustomerSchema.COL_ID) };
          rowsAffected = db.delete(CustomerSchema.TBL_CUSTOMER,CustomerSchema.COL_ID + " = ?" , primaryKey);
          if (rowsAffected > 0) {
            getContext().getContentResolver().notifyChange(uri, null);			
          }
          break;
        default:
          break;
        }
    
        if (rowsAffected > 0) {
          switch (matchId) {
          case URI_CODE_CUSTOMER_ID:
            getContext().getContentResolver().notifyChange(uri, null);			
            break;
          default: 
            break;
          }
        }
        return rowsAffected;
      }