Content Provider not working on Nexus family devices
Asked Answered
F

2

11

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.

Formicary answered 2/8, 2012 at 9:4 Comment(3)
For starters: 1. What are exact SDK versions present on your Android devices? 2. What are the exact SQLite versions on each device (adb shell sqlite3 --version) 3. Does the code work correctly in emulator? 4. What is the full call stack, when you get OutOfBoundsException? 5. How is ModelCursor implemented? 6. What is you database model? 7. How do you use your content provider (code)?Aconcagua
1. From 2.3.3 to 4.0 (wide range of devices) 2. Does it matter? I can check them, but ModelCursor does not get data from SQLite, just from internal file storage.3. [To be tested, thanks]. 4. link. 5. Just mehotd getBlob and the other ones required link. 6. No database needed. 7. Cursor modelCursor = getContentResolver().query(Uri.parse("content://" + PROVIDER_NAME + "/model"), null, null, new String[] {modelId}, null); - modelCursor.getBlob(0);Formicary
Have you tried to move the cursor to the first entry ? (modelCursor.moveToFirst())Neoteny
F
1

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 =)

Formicary answered 28/8, 2012 at 12:11 Comment(0)
C
0

I'm a bit in need of a crystal ball for this one, but...you could try two things:

  • Move the cursor to the first entry, as SteveR suggested.

  • Secondly, I encountered a similar problem while working on a Dell Streak 7" tablet. It was supposedly part of a list of devices with a particular exception in regard to accessing its internal storage. It was tricky to find, but was sorted with an if statement. It could be something similar, though I doubt it, especially since the Nexus is supposed to be the developer's device.

Maybe you should try to run the simplest possible ContentProvider test-app and see how it behaves on those devices.

Caswell answered 14/8, 2012 at 7:3 Comment(1)
Sorry for late answer. I've already tested all of that. The point is that moveToFirst() returns false. It's like the system is not able to find the provider, weird, because in other devices it finds it.Formicary

© 2022 - 2024 — McMap. All rights reserved.