androidandroid-contentprovidergoogle-nexus

Content Provider not working on Nexus family devices


I'm developing an app with a ContentProvider to offer some inner files (binary files). When I deploy it on a Samsung Galaxy S, SII, or any other, it works perfectly, buy when I try it on a Galaxy Nexus or Nexus S, it doesn't work!

Scenario:

My ContentProvider can be accessed with two URIs. Depending on this URI, the provider creates a DataCursor (extending CrossProcessCursor) or ModelCursor (extending CrossProcessCursos also). The fact is that, in Nexus family, I access the first cursor (DataCursor) to retrieve an identifier, and it works perfectly, but when accessing the second one, it always throws "OutOfBoundsException" when trying

getBlob()

method.

Provider

@Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        Cursor cursor = null;

        // If the third app requieres DATA (phrase id, phrase string and phrase name)
        if(uri.toString().equalsIgnoreCase(ProviderConstants.DATA_URI.toString())) {
            // Build the DataHelper and the customized cursor
            DataHelper dataHelper = new DataHelper(getContext());
            cursor = new DataCursor(dataHelper);
        } else if(uri.toString().equalsIgnoreCase(ProviderConstants.MODEL_URI.toString())) {            
            // Let's take the model id from the selectionArgs...
            if (selectionArgs != null && selectionArgs.length > 0) {
                String modelId = selectionArgs[0];

                // Get an instance to the persistent storage service...
                File file = FileManager.getDirectory(getContext(), modelId);
                FileSystemPersistentStorageService clientPersistentStorageService = new FileSystemPersistentStorageService(file);

                cursor = new ModelCursor(clientPersistentStorageService);
            } else {
                Log.e("ContentProvider", "Query without model id on selectionArgs");
            }
        }

        return cursor;
    }

If you need some code or anything, just ask for it please!

Thanks a lot.


Solution

  • Finally I got the answer. It wasn't due to devices, but it was due to Android OS version.

    Earlier versions from 4.0.3 had the method fillWindow() of AbstarctCursor implemented one way, being not mandatory to set the cursor position to 0 for first item. After 4.0.3 (as seen here), this method was modified, resulting on not setting the cursor position to 0.

    The Exception thrown was:

    07-31 11:35:09.938: W/System.err(2760): android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
    07-31 11:35:09.985: W/System.err(2760):     at android.database.AbstractCursor.checkPosition(AbstractCursor.java:418)
    07-31 11:35:09.989: W/System.err(2760):     at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
    07-31 11:35:09.989: W/System.err(2760):     at android.database.AbstractWindowedCursor.getBlob(AbstractWindowedCursor.java:44)
    07-31 11:35:09.993: W/System.err(2760):     at android.database.CursorWrapper.getBlob(CursorWrapper.java:122)
    07-31 11:35:09.993: W/System.err(2760):     at es.agnitio.kivox.mobile.internal.ModelImporterAndroidImpl.importModelPackage(ModelImporterAndroidImpl.java:44)
    07-31 11:35:09.993: W/System.err(2760):     at es.agnitio.kivox.mobile.internal.KivoxMobileBasicCode.importModel(KivoxMobileBasicCode.java:159)
    07-31 11:35:09.997: W/System.err(2760):     at es.agnitio.kivox.mobile.internal.KivoxMobileBasicImpl.importModel(KivoxMobileBasicImpl.java:47)
    07-31 11:35:09.997: W/System.err(2760):     at es.agnitio.kivoxmobile.testing.KivoxMobileBasicTrial.onCreate(KivoxMobileBasicTrial.java:63)
    07-31 11:35:09.997: W/System.err(2760):     at android.app.Activity.performCreate(Activity.java:5008)
    07-31 11:35:10.001: W/System.err(2760):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
    07-31 11:35:10.001: W/System.err(2760):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
    07-31 11:35:10.001: W/System.err(2760):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
    07-31 11:35:10.004: W/System.err(2760):     at android.app.ActivityThread.access$600(ActivityThread.java:130)
    07-31 11:35:10.004: W/System.err(2760):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
    07-31 11:35:10.004: W/System.err(2760):     at android.os.Handler.dispatchMessage(Handler.java:99)
    07-31 11:35:10.008: W/System.err(2760):     at android.os.Looper.loop(Looper.java:137)
    07-31 11:35:10.008: W/System.err(2760):     at android.app.ActivityThread.main(ActivityThread.java:4745)
    07-31 11:35:10.008: W/System.err(2760):     at java.lang.reflect.Method.invokeNative(Native Method)
    07-31 11:35:10.012: W/System.err(2760):     at java.lang.reflect.Method.invoke(Method.java:511)
    07-31 11:35:10.012: W/System.err(2760):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
    07-31 11:35:10.012: W/System.err(2760):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    07-31 11:35:10.016: W/System.err(2760):     at dalvik.system.NativeStart.main(Native Method)
    

    Which shows (after deep research), that the cursor index is not being setted on fillWindow().

    SOLUTION

    To solve this "fragmentation" issue, just add moveToPosition(0) in methods like moveToFirst() or move() (with some app logic) of your custom cursor. This will make the cursor index to be setted to 0, avoiding the "-1" index request Exception.

    Hope it helps anybody =)