Custom Content Providers and Files

Problems with WiFi, SQLite ,Bluetooth, WiMax, Proxies, etc...

Custom Content Providers and Files

Postby Davide » Mon Nov 30, 2009 5:31 am

I have a simply question for anyone who can answer...

I have created my own provider, I try to save a file with the openOutputStream, but it launch an exception saying that the provider doesn't support files, so the question is:

How can I make a custom provider support files?

Thank you.
Davide
Experienced Developer
Experienced Developer
 
Posts: 69
Joined: Mon Oct 19, 2009 12:05 pm
Location: Italy

Top

Postby padde » Mon Nov 30, 2009 7:06 am

Maybe my contentprovider could help. Its designed to store the sqlite DB on the SDcard... so some code
isn't needed for your solution. I store pictures with this contentprovider as files instead of blobs
as suggested by the android developer site.

CityGuideProvider.java
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. package de.padde.cityguide;
  3.  
  4.  
  5.  
  6. import java.io.File;
  7.  
  8. import java.io.FileNotFoundException;
  9.  
  10.  
  11.  
  12. import android.content.ContentProvider;
  13.  
  14. import android.content.ContentUris;
  15.  
  16. import android.content.ContentValues;
  17.  
  18. import android.content.Context;
  19.  
  20. import android.content.UriMatcher;
  21.  
  22. import android.database.Cursor;
  23.  
  24. import android.database.SQLException;
  25.  
  26. import android.database.sqlite.SQLiteDatabase;
  27.  
  28. import android.database.sqlite.SQLiteException;
  29.  
  30. import android.database.sqlite.SQLiteOpenHelper;
  31.  
  32. import android.database.sqlite.SQLiteQueryBuilder;
  33.  
  34. import android.net.Uri;
  35.  
  36. import android.os.Environment;
  37.  
  38. import android.os.ParcelFileDescriptor;
  39.  
  40. import android.text.TextUtils;
  41.  
  42. import android.util.Log;
  43.  
  44.  
  45.  
  46. public class CityGuideProvider extends ContentProvider {
  47.  
  48.     public static final String AUTHORITY = "de.padde.provider.cityguide";
  49.  
  50.     public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/poi");
  51.  
  52.     public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.padde.cityguide.poi";
  53.  
  54.     public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.padde.cityguide.poi";
  55.  
  56.    
  57.  
  58.     public static final String KEY_ID = "_id";
  59.  
  60.     public static final String KEY_DATA = "_data";
  61.  
  62.     public static final String KEY_LATITUDE = "latitude";
  63.  
  64.     public static final String KEY_LONGITUDE = "longitude";
  65.  
  66.     public static final String KEY_TYPE = "type";
  67.  
  68.     public static final String KEY_DESCRIPTION = "description";
  69.  
  70.    
  71.  
  72.     public static final int ID_COLUMN = 0;
  73.  
  74.     public static final int DATA_COLUMN = 1;
  75.  
  76.     public static final int LATITUDE_COLUMN = 2;
  77.  
  78.     public static final int LONGITUDE_COLUMN = 3;
  79.  
  80.     public static final int TYPE_COLUMN = 4;
  81.  
  82.     public static final int DESCRIPTION = 5;
  83.  
  84.    
  85.  
  86.     static final String DATABASE_PATH = "CityGuide";
  87.  
  88.     static final File EXTERNAL_STORAGE_DIRECTORY = Environment.getExternalStorageDirectory();
  89.  
  90.    
  91.  
  92.     private static final String DATABASE_NAME = "cache.db";
  93.  
  94.     private static final int DATABASE_VERSION = 1;
  95.  
  96.     private static final String POI_TABLE_NAME = "pois";
  97.  
  98.        
  99.  
  100.     private static final int SINGLE_POI = 1;
  101.  
  102.     private static final int MULTI_POI = 2;
  103.  
  104.    
  105.  
  106.     private static boolean mIsInitializing = false;
  107.  
  108.     private static boolean useLocal = false;
  109.  
  110.     private static String dbPath = EXTERNAL_STORAGE_DIRECTORY + File.separator + DATABASE_PATH + File.separator + DATABASE_NAME;
  111.  
  112.    
  113.  
  114.     private static final UriMatcher mUriMatcher;
  115.  
  116.    
  117.  
  118.     private static DatabaseHelper mDBOpenHelper;
  119.  
  120.     private static SQLiteDatabase mDB = null;
  121.  
  122.    
  123.  
  124.     static {
  125.  
  126.         mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
  127.  
  128.         mUriMatcher.addURI(AUTHORITY, "poi", MULTI_POI);
  129.  
  130.         mUriMatcher.addURI(AUTHORITY, "poi/#", SINGLE_POI);
  131.  
  132.     }
  133.  
  134.    
  135.  
  136.     private static class DatabaseHelper extends SQLiteOpenHelper {
  137.  
  138.         public DatabaseHelper(Context context) {
  139.  
  140.             super(context, DATABASE_NAME, null, DATABASE_VERSION);
  141.  
  142.             if(EXTERNAL_STORAGE_DIRECTORY.canWrite()) {
  143.  
  144.                 File destination = new File(EXTERNAL_STORAGE_DIRECTORY, DATABASE_PATH);
  145.  
  146.                 if(!destination.exists()) {
  147.  
  148.                     if(!destination.mkdirs()) {
  149.  
  150.                         useLocal = true;
  151.  
  152.                         dbPath = DATABASE_NAME;
  153.  
  154.                     }
  155.  
  156.                 }
  157.  
  158.             } else {
  159.  
  160.                 useLocal = true;
  161.  
  162.                 dbPath = DATABASE_NAME;
  163.  
  164.             }
  165.  
  166.         }
  167.  
  168.  
  169.  
  170.         public void onCreate(SQLiteDatabase db) {
  171.  
  172.             db.execSQL("CREATE TABLE " + POI_TABLE_NAME + " ("
  173.  
  174.                     + KEY_ID + " INTEGER PRIMARY KEY,"
  175.  
  176.                     + KEY_DATA + " TEXT,"
  177.  
  178.                     + KEY_LATITUDE + " INTEGER NOT NULL,"
  179.  
  180.                     + KEY_LONGITUDE + " INTEGER NOT NULL,"
  181.  
  182.                     + KEY_TYPE + " INTEGER NOT NULL,"
  183.  
  184.                     + KEY_DESCRIPTION + " TEXT"
  185.  
  186.                     + ");");
  187.  
  188.         }
  189.  
  190.  
  191.  
  192.         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  193.  
  194.             db.execSQL("DROP TABLE IF EXISTS " + POI_TABLE_NAME);
  195.  
  196.             onCreate(db);
  197.  
  198.         }
  199.  
  200.        
  201.  
  202.         public synchronized SQLiteDatabase getReadableDatabase() {
  203.  
  204.             if(useLocal) return super.getReadableDatabase();
  205.  
  206.             if (mDB != null && mDB.isOpen()) return mDB;
  207.  
  208.             if (mIsInitializing) throw new IllegalStateException("getReadableDatabase called recursively");
  209.  
  210.  
  211.  
  212.             try {
  213.  
  214.                 return getWritableDatabase();
  215.  
  216.             } catch (SQLiteException e) { Log.e("DatabaseHelper", "Couldn't open " + DATABASE_NAME + " for writing (will try read-only):", e); }
  217.  
  218.  
  219.  
  220.             SQLiteDatabase db = null;
  221.  
  222.            
  223.  
  224.             try {
  225.  
  226.                 mIsInitializing = true;
  227.  
  228.                 db = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READONLY);
  229.  
  230.                 if (db.getVersion() != DATABASE_VERSION) { throw new SQLiteException("Can't upgrade read-only database from version " + db.getVersion() + " to " + DATABASE_VERSION + ": " + dbPath); }
  231.  
  232.                 onOpen(db);
  233.  
  234.                 mDB = db;
  235.  
  236.                 return mDB;
  237.  
  238.             } finally {
  239.  
  240.                 mIsInitializing = false;
  241.  
  242.                 if (db != null && db != mDB) db.close();
  243.  
  244.             }
  245.  
  246.         }
  247.  
  248.  
  249.  
  250.         public synchronized SQLiteDatabase getWritableDatabase() {
  251.  
  252.             if(useLocal) return super.getWritableDatabase();
  253.  
  254.             if (mDB != null && mDB.isOpen() && !mDB.isReadOnly()) return mDB;
  255.  
  256.             if (mIsInitializing) throw new IllegalStateException("getWritableDatabase called recursively");
  257.  
  258.  
  259.  
  260.             boolean success = false;
  261.  
  262.             SQLiteDatabase db = null;
  263.  
  264.            
  265.  
  266.             try {
  267.  
  268.                 mIsInitializing = true;
  269.  
  270.                 db = SQLiteDatabase.openOrCreateDatabase(dbPath, null);
  271.  
  272.                 int version = db.getVersion();
  273.  
  274.                 if (version != DATABASE_VERSION) {
  275.  
  276.                     db.beginTransaction();
  277.  
  278.                     try {
  279.  
  280.                         if (version == 0) onCreate(db); else onUpgrade(db, version, DATABASE_VERSION);
  281.  
  282.                         db.setVersion(DATABASE_VERSION);
  283.  
  284.                         db.setTransactionSuccessful();
  285.  
  286.                     } finally {
  287.  
  288.                         db.endTransaction();
  289.  
  290.                     }
  291.  
  292.                 }
  293.  
  294.                 onOpen(db);
  295.  
  296.                 success = true;
  297.  
  298.                 return db;
  299.  
  300.             } finally {
  301.  
  302.                 mIsInitializing = false;
  303.  
  304.                 if (success) {
  305.  
  306.                     if (mDB != null) {
  307.  
  308.                         try {
  309.  
  310.                             mDB.close();
  311.  
  312.                         } catch (Exception e) {}
  313.  
  314.                     }
  315.  
  316.                     mDB = db;
  317.  
  318.                 } else if (db != null) db.close();
  319.  
  320.             }
  321.  
  322.         }        
  323.  
  324.     }
  325.  
  326.    
  327.  
  328.     public boolean onCreate() {
  329.  
  330.         mDBOpenHelper = new DatabaseHelper(getContext());
  331.  
  332.            mDB = mDBOpenHelper.getWritableDatabase();
  333.  
  334.            return (mDB == null) ? false : true;
  335.  
  336.     }
  337.  
  338.  
  339.  
  340.     public String getType(Uri uri) {
  341.  
  342.         switch (mUriMatcher.match(uri)) {
  343.  
  344.             case SINGLE_POI: return CONTENT_ITEM_TYPE;
  345.  
  346.             case MULTI_POI: return CONTENT_TYPE;
  347.  
  348.             default: throw new IllegalArgumentException("Unsupported URI: " + uri);
  349.  
  350.         }        
  351.  
  352.     }
  353.  
  354.    
  355.  
  356.     public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
  357.  
  358.         SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
  359.  
  360.         qb.setTables(POI_TABLE_NAME);
  361.  
  362.         if(mUriMatcher.match(uri) == SINGLE_POI) qb.appendWhere(KEY_ID + "=" + uri.getPathSegments().get(1));        
  363.  
  364.         String orderBy = sortOrder;
  365.  
  366.         if (TextUtils.isEmpty(sortOrder)) orderBy = KEY_TYPE;
  367.  
  368.         SQLiteDatabase db = mDBOpenHelper.getReadableDatabase();
  369.  
  370.         Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
  371.  
  372.         c.setNotificationUri(getContext().getContentResolver(), uri);
  373.  
  374.         return c;        
  375.  
  376.     }
  377.  
  378.  
  379.  
  380.     public Uri insert(Uri uri, ContentValues values) {
  381.  
  382.         if(values == null) throw new SQLException("Failed to insert row into " + uri + ": ContentValues is null");
  383.  
  384.         if(!isValid(values)) throw new SQLException("Failed to insert row into " + uri);
  385.  
  386.         SQLiteDatabase db = mDBOpenHelper.getWritableDatabase();
  387.  
  388.         long rowId = db.insert(POI_TABLE_NAME, "NULL", values);
  389.  
  390.         if (rowId > 0) {
  391.  
  392.             Uri newUri = ContentUris.withAppendedId(CONTENT_URI, rowId);
  393.  
  394.             getContext().getContentResolver().notifyChange(newUri, null);
  395.  
  396.             return newUri;
  397.  
  398.         }
  399.  
  400.         throw new SQLException("Failed to insert row into " + uri);
  401.  
  402.     }
  403.  
  404.    
  405.  
  406.     public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
  407.  
  408.         if(values == null) throw new SQLException("Failed to update row in " + uri + ": ContentValues is null");
  409.  
  410.         SQLiteDatabase db = mDBOpenHelper.getWritableDatabase();
  411.  
  412.         int count = 0;
  413.  
  414.         String id;
  415.  
  416.         switch (mUriMatcher.match(uri)) {
  417.  
  418.             case MULTI_POI:
  419.  
  420.                 count = db.update(POI_TABLE_NAME, values, selection, selectionArgs);
  421.  
  422.                 break;
  423.  
  424.             case SINGLE_POI:
  425.  
  426.                 id = uri.getPathSegments().get(1);
  427.  
  428.                 count = db.update(POI_TABLE_NAME, values, KEY_ID + "=" + id + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);                
  429.  
  430.                 break;
  431.  
  432.             default: throw new IllegalArgumentException("Unknown URI " + uri);
  433.  
  434.         }
  435.  
  436.         getContext().getContentResolver().notifyChange(uri, null);
  437.  
  438.         return count;
  439.  
  440.     }
  441.  
  442.    
  443.  
  444.     public int delete(Uri uri, String selection, String[] selectionArgs) {
  445.  
  446.         SQLiteDatabase db = mDBOpenHelper.getWritableDatabase();
  447.  
  448.         int count = 0;
  449.  
  450.         switch (mUriMatcher.match(uri)) {
  451.  
  452.             case MULTI_POI:
  453.  
  454.                 count = db.delete(POI_TABLE_NAME, selection, selectionArgs);                
  455.  
  456.                 break;
  457.  
  458.             case SINGLE_POI:
  459.  
  460.                 String id = uri.getPathSegments().get(1);
  461.  
  462.                 count = db.delete(POI_TABLE_NAME, KEY_ID + "=" + id + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);                
  463.  
  464.                 break;
  465.  
  466.             default: throw new IllegalArgumentException("Unknown URI " + uri);
  467.  
  468.         }
  469.  
  470.         getContext().getContentResolver().notifyChange(uri, null);
  471.  
  472.         return count;
  473.  
  474.     }
  475.  
  476.    
  477.  
  478.     public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
  479.  
  480.         if (mUriMatcher.match(uri) != SINGLE_POI) throw new IllegalArgumentException("openFile not supported for directories");
  481.  
  482.         try {
  483.  
  484.             String id = uri.getPathSegments().get(1);
  485.  
  486.             ContentValues values = new ContentValues();
  487.  
  488.             values.put(KEY_DATA, EXTERNAL_STORAGE_DIRECTORY + File.separator + DATABASE_PATH + File.separator + "img"+ id +".png");
  489.  
  490.             update(uri,values,new String(KEY_ID+"="+id),null);            
  491.  
  492.             return openFileHelper(uri, mode);
  493.  
  494.         } catch (FileNotFoundException e) { throw new FileNotFoundException(); }
  495.  
  496.     }
  497.  
  498.    
  499.  
  500.     private boolean isValid(ContentValues v) {
  501.  
  502.         String errorcode = "";
  503.  
  504.         if(!v.containsKey(KEY_LATITUDE)) errorcode += "Missing " + KEY_LATITUDE + " value in ContentValues";
  505.  
  506.         if(!v.containsKey(KEY_LONGITUDE)) errorcode += "Missing " + KEY_LONGITUDE + " value in ContentValues";
  507.  
  508.         if(!v.containsKey(KEY_TYPE))  errorcode += "Missing " + KEY_TYPE + " value in ContentValues";
  509.  
  510.         if(errorcode.length() != 0) Log.e("CityGuideProvider", errorcode);
  511.  
  512.         return (errorcode.length() == 0) ? true : false;
  513.  
  514.     }
  515.  
  516. }
  517.  
  518.  
Parsed in 0.083 seconds, using GeSHi 1.0.8.4
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Postby Davide » Mon Nov 30, 2009 10:02 am

Thanks Padde for the reply, I'm trying to translate it to my content provider.
I'm trying to save a file in the database inside the android file system.

This is my content provider (You will see that's basically the same of yours):

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. package com.polimi.cp.it;
  3.  
  4.  
  5.  
  6. import java.io.FileNotFoundException;
  7.  
  8.  
  9.  
  10. import android.content.ContentProvider;
  11.  
  12. import android.content.ContentUris;
  13.  
  14. import android.content.ContentValues;
  15.  
  16. import android.content.Context;
  17.  
  18. import android.content.UriMatcher;
  19.  
  20. import android.database.Cursor;
  21.  
  22. import android.database.SQLException;
  23.  
  24. import android.database.sqlite.SQLiteDatabase;
  25.  
  26. import android.database.sqlite.SQLiteOpenHelper;
  27.  
  28. import android.database.sqlite.SQLiteQueryBuilder;
  29.  
  30. import android.database.sqlite.SQLiteDatabase.CursorFactory;
  31.  
  32. import android.net.Uri;
  33.  
  34. import android.os.ParcelFileDescriptor;
  35.  
  36. import android.text.TextUtils;
  37.  
  38. import android.util.Log;
  39.  
  40.  
  41.  
  42. public class LibreriaCP extends ContentProvider {
  43.  
  44.         private static final String myURI = "content://com.polimi.provider.filecp/files";
  45.  
  46.         public static final Uri CONTENT_URI = Uri.parse(myURI);
  47.  
  48.         public static boolean giaLetto;
  49.  
  50.        
  51.  
  52.         // The underlying database
  53.  
  54.         private SQLiteDatabase filesDB;
  55.  
  56.         private static final String TAG = "FileProvider";
  57.  
  58.         private static final String DATABASE_NAME = "files.db";
  59.  
  60.         private static final int DATABASE_VERSION = 1;
  61.  
  62.         private static final String FILE_TABLE = "files";
  63.  
  64.         // Column Names
  65.  
  66.         public static final String KEY_ID = "_id";
  67.  
  68.         public static final String KEY_DATE = "date";
  69.  
  70.         public static final String KEY_DESCRIPTION = "description";
  71.  
  72.         public static final String KEY_NAME = "name";
  73.  
  74.        
  75.  
  76.        
  77.  
  78.        
  79.  
  80.         // Column indexes
  81.  
  82.        
  83.  
  84.         public static final int ID_COLUMN = 0;
  85.  
  86.         public static final int DATE_COLUMN = 1;
  87.  
  88.         public static final int DESCRIPTION_COLUMN = 2;
  89.  
  90.         public static final int NAME_COLUMN = 3;
  91.  
  92.        
  93.  
  94.        
  95.  
  96.        
  97.  
  98.         // Helper class for opening, creating, and managing
  99.  
  100.         // database version control
  101.  
  102.         private static class fileDatabaseHelper extends SQLiteOpenHelper {
  103.  
  104.         private static final String DATABASE_CREATE =
  105.  
  106.                 "create table " + FILE_TABLE + " ("
  107.  
  108.                 + KEY_ID + " integer primary key autoincrement, "
  109.  
  110.                 + KEY_DATE + " INTEGER, "
  111.  
  112.                 + KEY_DESCRIPTION + " TEXT, "
  113.  
  114.                 + KEY_NAME + " TEXT);";
  115.  
  116.         public fileDatabaseHelper(Context context, String name,CursorFactory factory, int version) {
  117.  
  118.                 super(context, name, factory, version);
  119.  
  120.         }
  121.  
  122.         @Override
  123.  
  124.         public void onCreate(SQLiteDatabase db) {
  125.  
  126.                 db.execSQL(DATABASE_CREATE);
  127.  
  128.         }
  129.  
  130.         @Override
  131.  
  132.         public void onUpgrade(SQLiteDatabase db, int oldVersion,int newVersion) {
  133.  
  134.                 Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
  135.  
  136.                                 + newVersion + ", which will destroy all old data");
  137.  
  138.                                 db.execSQL("DROP TABLE IF EXISTS " + FILE_TABLE);
  139.  
  140.                                 onCreate(db);
  141.  
  142.                                 }
  143.  
  144.         }
  145.  
  146.        
  147.  
  148.         // Prepare the costants for the Uri matcher
  149.  
  150.         private static final int ALLROWS = 1;
  151.  
  152.         private static final int SINGLE_ROW = 2;
  153.  
  154.         private static final UriMatcher uriMatcher;
  155.  
  156.         // Populate the UriMatcher object, where a URI ending in ‘items’ will
  157.  
  158.         // correspond to a request for all items, and ‘items/[rowID]’
  159.  
  160.         // represents a single row.
  161.  
  162.         static {
  163.  
  164.                 uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
  165.  
  166.                 uriMatcher.addURI("com.polimi.provider.filecp", "files", ALLROWS);
  167.  
  168.                 uriMatcher.addURI("com.polimi.provider.filecp", "files/#",SINGLE_ROW);
  169.  
  170.         }
  171.  
  172.        
  173.  
  174.         @Override
  175.  
  176.         public int delete(Uri uri, String where, String[] whereArgs) {
  177.  
  178.                 int count;
  179.  
  180.                 switch (uriMatcher.match(uri)) {
  181.  
  182.                         case ALLROWS:
  183.  
  184.                                 count = filesDB.delete(FILE_TABLE, where, whereArgs);
  185.  
  186.                                 break;
  187.  
  188.                         case SINGLE_ROW:
  189.  
  190.                                 String segment = uri.getPathSegments().get(1);
  191.  
  192.                                 count = filesDB.delete(FILE_TABLE, KEY_ID + "="
  193.  
  194.                                                 + segment
  195.  
  196.                                                 + (!TextUtils.isEmpty(where) ? " AND ("
  197.  
  198.                                                                 + where + ')' : ""), whereArgs);
  199.  
  200.                                 break;
  201.  
  202.                         default: throw new IllegalArgumentException("Unsupported URI: " +
  203.  
  204.                                         uri);
  205.  
  206.                 }
  207.  
  208.                 getContext().getContentResolver().notifyChange(uri, null);
  209.  
  210.                 return count;
  211.  
  212.         }
  213.  
  214.  
  215.  
  216.         @Override
  217.  
  218.         public String getType(Uri _uri) {
  219.  
  220.                 switch (uriMatcher.match(_uri)) {
  221.  
  222.                 case ALLROWS: return "vnd.polimi.cursor.dir/file";
  223.  
  224.                 case SINGLE_ROW: return "vnd.polimi.cursor.item/file";
  225.  
  226.                 default: throw new IllegalArgumentException("Unsupported URI: " +
  227.  
  228.                 _uri);
  229.  
  230.                 }
  231.  
  232.         }
  233.  
  234.  
  235.  
  236.         @Override
  237.  
  238.         public Uri insert(Uri _uri, ContentValues values) {
  239.  
  240.                 // Insert the new row, will return the row number if
  241.  
  242.                 // successful.
  243.  
  244.                 long rowID = filesDB.insert(FILE_TABLE, "quake",
  245.  
  246.                 values);
  247.  
  248.                 // Return a URI to the newly inserted row on success.
  249.  
  250.                 if (rowID > 0) {
  251.  
  252.                 Uri uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
  253.  
  254.                 getContext().getContentResolver().notifyChange(uri, null);
  255.  
  256.                 return uri;
  257.  
  258.                 }
  259.  
  260.                 throw new SQLException("Failed to insert row into " + _uri);
  261.  
  262.         }
  263.  
  264.  
  265.  
  266.         @Override
  267.  
  268.         public boolean onCreate() {
  269.  
  270.                 Context context = getContext();
  271.  
  272.                 fileDatabaseHelper dbhelper;
  273.  
  274.                 dbhelper = new fileDatabaseHelper(context, DATABASE_NAME, null,
  275.  
  276.                                 DATABASE_VERSION);
  277.  
  278.                 filesDB = dbhelper.getWritableDatabase();
  279.  
  280.                 return (filesDB == null) ? false : true;
  281.  
  282.         }
  283.  
  284.  
  285.  
  286.         @Override
  287.  
  288.         public Cursor query(Uri uri, String[] projection, String selection,
  289.  
  290.                         String[] selectionArgs, String sort) {
  291.  
  292.                 SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
  293.  
  294.                 qb.setTables(FILE_TABLE);
  295.  
  296.                 // If this is a row query, limit the result set to the passed in row.
  297.  
  298.                 switch (uriMatcher.match(uri)) {
  299.  
  300.                 case SINGLE_ROW:
  301.  
  302.                 qb.appendWhere(KEY_ID + "=" + uri.getPathSegments().get(1));
  303.  
  304.                 break;
  305.  
  306.                 default: break;
  307.  
  308.                 }
  309.  
  310.                 // If no sort order is specified sort by date / time
  311.  
  312.                 String orderBy;
  313.  
  314.                 if (TextUtils.isEmpty(sort)) {
  315.  
  316.                 orderBy = KEY_DATE;
  317.  
  318.                 } else {
  319.  
  320.                 orderBy = sort;
  321.  
  322.                 }
  323.  
  324.                 // Apply the query to the underlying database.
  325.  
  326.                 Cursor c = qb.query(filesDB,
  327.  
  328.                 projection,
  329.  
  330.                 selection, selectionArgs,
  331.  
  332.                 null, null,
  333.  
  334.                 orderBy);
  335.  
  336.                 // Register the contexts ContentResolver to be notified if
  337.  
  338.                 // the cursor result set changes.
  339.  
  340.                 c.setNotificationUri(getContext().getContentResolver(), uri);
  341.  
  342.                 // Return a cursor to the query result.
  343.  
  344.                 return c;
  345.  
  346.         }
  347.  
  348.  
  349.  
  350.         @Override
  351.  
  352.         public int update(Uri uri, ContentValues values, String where,
  353.  
  354.                         String[] whereArgs) {
  355.  
  356.                         int count;
  357.  
  358.                         switch (uriMatcher.match(uri)) {
  359.  
  360.                         case ALLROWS:
  361.  
  362.                         count = filesDB.update(FILE_TABLE, values,
  363.  
  364.                         where, whereArgs);
  365.  
  366.                         break;
  367.  
  368.                         case SINGLE_ROW:
  369.  
  370.                         String segment = uri.getPathSegments().get(1);
  371.  
  372.                         count = filesDB.update(FILE_TABLE, values, KEY_ID
  373.  
  374.                         + "=" + segment
  375.  
  376.                         + (!TextUtils.isEmpty(where) ? " AND ("
  377.  
  378.                                         + where + ')' : ""), whereArgs);
  379.  
  380.                         break;
  381.  
  382.                         default: throw new IllegalArgumentException("Unknown URI " + uri);
  383.  
  384.                         }
  385.  
  386.                         getContext().getContentResolver().notifyChange(uri, null);
  387.  
  388.                         return count;
  389.  
  390.                 }
  391.  
  392.    
  393.  
  394.         public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
  395.  
  396.        
  397.  
  398.                 if (uriMatcher.match(uri) != SINGLE_ROW) throw new IllegalArgumentException("openFile not supported for directories");
  399.  
  400.         try {
  401.  
  402.             /*String id = uri.getPathSegments().get(1);
  403.  
  404.             ContentValues values = new ContentValues();
  405.  
  406.             values.put(KEY_DATA, EXTERNAL_STORAGE_DIRECTORY + File.separator + DATABASE_PATH + File.separator + "img"+ id +".png");
  407.  
  408.             update(uri,values,new String(KEY_ID+"="+id),null);   */        
  409.  
  410.             return openFile(uri, mode);
  411.  
  412.         } catch (FileNotFoundException e) { throw new FileNotFoundException(); }
  413.  
  414.                
  415.  
  416.     }
  417.  
  418.        
  419.  
  420. }
Parsed in 0.061 seconds, using GeSHi 1.0.8.4


I think that the key to get my answer stay in the openFile method.
I commented out the part that fill the _data column that I don't use.
If I try this code I got a stuck overflow, because the program call several times this method.

Here is the code where I "call" to save or read the file:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. // loadFile()
  3.  
  4. private void caricaFile(){
  5.  
  6.                 String[] proj = new String[]{LibreriaCP.KEY_ID};
  7.  
  8.                 String where = LibreriaCP.KEY_NAME + " = 'prova.txt'";
  9.  
  10.                 String data = "";
  11.  
  12.                 Cursor cercaFile = getContentResolver().query(LibreriaCP.CONTENT_URI, proj, where, null, null);
  13.  
  14.                 startManagingCursor(cercaFile);
  15.  
  16.                 if (cercaFile.moveToFirst()){
  17.  
  18.                 Uri uri = Uri.withAppendedPath(LibreriaCP.CONTENT_URI, Integer.toString(cercaFile.getInt(cercaFile.getColumnIndexOrThrow(LibreriaCP.KEY_ID))));
  19.  
  20.                 BufferedReader br = null;
  21.  
  22.                 InputStream is;
  23.  
  24.                 try {
  25.  
  26.                         is = getContentResolver().openInputStream(uri);
  27.  
  28.                         br = new BufferedReader(new InputStreamReader(is));
  29.  
  30.                 } catch (FileNotFoundException e) {
  31.  
  32.                        
  33.  
  34.                         errore(e.getMessage());
  35.  
  36.                 }
  37.  
  38.                 try {
  39.  
  40.                
  41.  
  42.                         String l;
  43.  
  44.                         while ((l = br.readLine()) != null){
  45.  
  46.                                 data += l;
  47.  
  48.                         }
  49.  
  50.                
  51.  
  52.                
  53.  
  54.                 mostra.setText(data);
  55.  
  56.                
  57.  
  58.                 }catch (Exception er){
  59.  
  60.                         errore(er.getMessage());
  61.  
  62.                 }
  63.  
  64.                 } else {
  65.  
  66.  
  67.  
  68.                         errore("Non è stato trovato nulla nel Content Provider"); // Nothing were found in the CP
  69.  
  70.                 }
  71.  
  72.         }
  73.  
  74.        
  75.  
  76.  
  77.  
  78. // Save file
  79.  
  80.         private void salvaFile() {
  81.  
  82.                 ContentResolver cr = getContentResolver();
  83.  
  84.                 ContentValues values = new ContentValues();
  85.  
  86.                 Uri rowUri;
  87.  
  88.                
  89.  
  90.                 values.put(LibreriaCP.KEY_DATE, new GregorianCalendar(0,0,0).getTime().toGMTString());
  91.  
  92.                 values.put(LibreriaCP.KEY_DESCRIPTION, "File di prova"); // Test file
  93.  
  94.                 values.put(LibreriaCP.KEY_NAME, "prova.txt");
  95.  
  96.                
  97.  
  98.                 rowUri = cr.insert(LibreriaCP.CONTENT_URI, values);
  99.  
  100.                
  101.  
  102.                 try{
  103.  
  104.                         OutputStream os = getContentResolver().openOutputStream(rowUri);
  105.  
  106.                         PrintStream ps = new PrintStream(os);
  107.  
  108.                        
  109.  
  110.                         ps.print(mostra.getText());
  111.  
  112.                         ps.close();
  113.  
  114.                         os.close();
  115.  
  116.                 } catch (Exception ioe){
  117.  
  118.                         errore(ioe.getMessage());
  119.  
  120.                 }
  121.  
  122.                
  123.  
  124.         }
  125.  
  126.  
Parsed in 0.042 seconds, using GeSHi 1.0.8.4
Davide
Experienced Developer
Experienced Developer
 
Posts: 69
Joined: Mon Oct 19, 2009 12:05 pm
Location: Italy

Postby padde » Mon Nov 30, 2009 2:15 pm

You have to use the "_data" column. This is a "special" column like the _id column in the android system.
In the end the uri to the file is stored to the "_data" column and functions like openOutputStream or
openInputStream of the contentresolver class looking for this column and open the uri stored in there.
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Postby Davide » Mon Nov 30, 2009 4:22 pm

Oh ok! But for the line:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. values.put(KEY_DATA, EXTERNAL_STORAGE_DIRECTORY + File.separator + DATABASE_PATH + File.separator + "img"+ id +".png");
  3.  
  4.  
Parsed in 0.036 seconds, using GeSHi 1.0.8.4


What I have to put in the value field? Have I to put the uri of the row that refer to the file I want to use?

I mean in this way:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.  public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
  3.  
  4.      
  5.  
  6.           if (uriMatcher.match(uri) != SINGLE_ROW) throw new IllegalArgumentException("openFile not supported for directories");
  7.  
  8.         try {
  9.  
  10.             String id = uri.getPathSegments().get(1);
  11.  
  12.             ContentValues values = new ContentValues();
  13.  
  14.             values.put(KEY_DATA, uri);
  15.  
  16.             update(uri,values,new String(KEY_ID+"="+id),null);        
  17.  
  18.             return openFile(uri, mode);
  19.  
  20.         } catch (FileNotFoundException e) { throw new FileNotFoundException(); }
  21.  
  22.          
  23.  
  24.     }
  25.  
  26.  
Parsed in 0.038 seconds, using GeSHi 1.0.8.4


If you have to loose time for helping me for this post, don't do it. I ask you this one more question because I haven't the time right now to try it by myself, but I will do anyway, if you will not. :)
Davide
Experienced Developer
Experienced Developer
 
Posts: 69
Joined: Mon Oct 19, 2009 12:05 pm
Location: Italy

Postby padde » Mon Nov 30, 2009 6:01 pm

Well.. the function gets called by the system with a uri. The uri contains an ID of the row
it belongs to. The important part in this method is that it stores a Uri into the "_data" column of
the specified row.
The actual file gets created by the system.. you just have to store the path and name you want to
be used by the system.
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Top

Postby Davide » Tue Dec 01, 2009 10:36 am

The path could be somewhere in the file system? Or there is absolutely no ways to save files in there?

This is why I'm using a Content Provider, I was thinking that using a provider I could save a file inside the file system, obviously in a DMZ, avoiding the use of a SDCard that could be present and could be not.
The specification of the project I have to realize tell me that I "have to" use a XML file to keep a configuration (text size, back and foreground colors), I know that for these things there's the shared preference, but who give me the specification tells me that I cannot use that.
Last edited by Davide on Tue Dec 01, 2009 11:11 am, edited 1 time in total.
Davide
Experienced Developer
Experienced Developer
 
Posts: 69
Joined: Mon Oct 19, 2009 12:05 pm
Location: Italy

Postby padde » Tue Dec 01, 2009 10:53 am

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. values.put(KEY_DATA, uri.toString() + File.separator + c.getString(0));
  3.  
  4.  
Parsed in 0.036 seconds, using GeSHi 1.0.8.4


That line doesn't look right to me.. check if "uri.toString() + File.separator + c.getString(0)" is really what you want.
for me it looks like the result in the data column will be something like "content://something/path/1//name".. an example out of my provider is "/sdcard/cityguide/img1.png".. hope this helps.
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Postby Davide » Tue Dec 01, 2009 11:14 am

Yes I noticed that and it's not right. :) In fact I have changed the previous message.
Now I try the "content://..." thing.
Davide
Experienced Developer
Experienced Developer
 
Posts: 69
Joined: Mon Oct 19, 2009 12:05 pm
Location: Italy

Postby padde » Tue Dec 01, 2009 11:24 am

If you want to avoid storing the files on the sdcard then try a path like "myfiles/myf.ile".
It should be created in you application directory "/data/data/yourpackage/myfiles/myf.ile".
Maybe you need the absolute path so you will have to include the /data/data.. etc. in the filename.
You will have to test this .. but generally you can store own files in your application directory or
on the sdcard.
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Postby Davide » Tue Dec 01, 2009 1:08 pm

It works! I've used the "data/data/MyPackage//filename" path. Thank you for the help and patience! 8)

EDIT: How can I set this topic solved?
Davide
Experienced Developer
Experienced Developer
 
Posts: 69
Joined: Mon Oct 19, 2009 12:05 pm
Location: Italy

Top

Return to Networking & Database Problems

Who is online

Users browsing this forum: No registered users and 3 guests