无法从android中的其他应用程序访问自定义内容提供商

nuypyhwy  于 2021-06-29  发布在  Java
关注(0)|答案(0)|浏览(223)

这个问题在这里已经有答案了

java.lang.nullpointerexception:尝试对空对象引用[duplicate]调用接口方法'boolean android.database.cursor.movetofirst()'(1个答案)
什么是nullpointerexception,如何修复它(12个答案)
11天前关门了。
所有人!我在androidstudio4.1.1中有一个应用程序(refugio2),它有一个小数据库(只有一个表)。我已经添加了一个内容提供商。
这是应用程序树:

└── com
    └── example
        └── refugio2
            ├── data
            │   ├── RefugioContract.java
            │   ├── RefugioDbHelper.java
            │   └── RefugioProvider.java
            ├── MainActivity.java
            ├── NuevoFragment.java
            └── PrimerFragment.java

这是我的清单文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.refugio2">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Refugio2">
        <provider
            android:name="com.example.refugio2.data.RefugioProvider"
            android:authorities="com.example.refugio2"
            android:exported="true"/>
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/Theme.Refugio2.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

这是合同类:

public final class RefugioContract {
    //final para que no se pueda extender

    //Para las uris del content provider
    public static final String CONTENT_AUTHORITY="com.example.refugio2";
    public static final Uri BASE_CONTENT_URI=Uri.parse("content://"+CONTENT_AUTHORITY);
    public static final String PATH_MASCOTA="mascota";

    //Private para que no pueda ser instanciada. La quiero sólo por sus constantes
    private RefugioContract(){
    }

    //Una clase como esta por cada tabla de la Base de Datos
    public static final class MascotaEntry implements BaseColumns{

        //Uri para acceder al contenido de la tabla
        public static final Uri CONTENT_URI=Uri.withAppendedPath(BASE_CONTENT_URI,PATH_MASCOTA);

        //Tabla
        public static final String TABLA="mascota";

        //Columnas
        public static final String COLUMNA_NOMBRE="nombre";
        public static final String COLUMNA_ESPECIE="especie";
        public static final String COLUMNA_SEXO="sexo";
        public static final String COLUMNA_PESO="peso";

        //Valores concretos para usar en algunas columnas
        public static final int SEXO_MACHO=1;
        public static final int SEXO_HEMBRA=2;
        public static final int SEXO_DESCONOCIDO=0;
    }
}

这是内容提供者类:

public class RefugioProvider extends ContentProvider {
    //Para comprobar la validez de las uris que recibe
    private static final int MASCOTA=1;
    private static final int MASCOTA_ID=2;
    private static final UriMatcher um=new UriMatcher(UriMatcher.NO_MATCH);
    static{
        um.addURI(RefugioContract.CONTENT_AUTHORITY, RefugioContract.PATH_MASCOTA,MASCOTA);
        um.addURI(RefugioContract.CONTENT_AUTHORITY, RefugioContract.PATH_MASCOTA+"/#",MASCOTA_ID);
    }

    private RefugioDbHelper dbHelper;

    public RefugioProvider() {
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // Implement this to handle requests to delete one or more rows.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public String getType(Uri uri) {
        // TODO: Implement this to handle requests for the MIME type of the data
        // at the given URI.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        //Aquí podríamos añadir chequeos con
        // values.asString(MascotaEntry.COLUMNA_NOMBRE), o values.asFloat(MascotaEntry.COLUMNA.PESO) ...
        //Y por ejemplo devolver una uri con id -100, -200... que indique el tipo de error

        SQLiteDatabase db=dbHelper.getWritableDatabase();
        long nuevoId;
        switch(um.match(uri)){
            case MASCOTA:
                nuevoId=db.insert(RefugioContract.MascotaEntry.TABLA,null,values);
                break;
            default:
                throw new IllegalArgumentException("Uri no válida: "+uri);
        }
        return ContentUris.withAppendedId(uri,nuevoId);
    }

    @Override
    public boolean onCreate() {
        dbHelper=RefugioDbHelper.getInstance(getContext());
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        SQLiteDatabase db=dbHelper.getReadableDatabase();
        Cursor cursor=null;
        switch(um.match(uri)){
            case MASCOTA:
                cursor=db.query(RefugioContract.MascotaEntry.TABLA,projection,
                        selection,selectionArgs,null,null,sortOrder);
                break;
            case MASCOTA_ID:
                selection= RefugioContract.MascotaEntry._ID+"=?";
                selectionArgs=new String[]{String.valueOf(ContentUris.parseId(uri))};
                cursor=db.query(RefugioContract.MascotaEntry.TABLA,projection,
                        selection,selectionArgs,null,null,sortOrder);
                break;
            default:
                throw new IllegalArgumentException("Uri no válida: "+uri);
        }
        return cursor;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
                      String[] selectionArgs) {
        // TODO: Implement this to handle requests to update one or more rows.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

在应用程序中一切正常。但是。。。我制作了另一个应用程序(refugioconsumidor)作为此内容提供商的客户端,只需一个主要活动:

package com.example.refugioconsumidor;

import androidx.appcompat.app.AppCompatActivity;

import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    TextView contenido;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        ContentResolver cr =getApplicationContext().getContentResolver();
        Cursor cursor= null;
        cursor = cr.query(Uri.parse("content://com.example.refugio2/mascota"),
                null,null,null,null);

        while(cursor.moveToNext()){
            int id=cursor.getInt(1);
            String nombre=cursor.getString(2);
            String especie=cursor.getString(3);
            int sexo=cursor.getInt(4);
            float peso=cursor.getFloat(5);
            contenido.append(id+" - "+nombre+" - "+especie+" - "+sexo+" - "+peso+"\n");
        }

        cursor.close();
    }
}

当我在emulator上运行它时,它找不到内容提供程序,并且由于游标为null而引发以下错误:

12/29 08:51:10: Launching 'app' on Nexus 5X API 30.
Install successfully finished in 225 ms.
$ adb shell am start -n "com.example.refugioconsumidor/com.example.refugioconsumidor.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Connected to process 2983 on device 'emulator-5554'.
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
D/NetworkSecurityConfig: No Network Security Config specified, using platform default
D/NetworkSecurityConfig: No Network Security Config specified, using platform default
D/libEGL: loaded /vendor/lib/egl/libEGL_emulation.so
D/libEGL: loaded /vendor/lib/egl/libGLESv1_CM_emulation.so
D/libEGL: loaded /vendor/lib/egl/libGLESv2_emulation.so
W/fugioconsumido: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (greylist, reflection, allowed)
W/fugioconsumido: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (greylist, reflection, allowed)
E/ActivityThread: Failed to find provider info for com.example.refugio2
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.refugioconsumidor, PID: 2983
    java.lang.NullPointerException: Attempt to invoke interface method 'boolean android.database.Cursor.moveToNext()' on a null object reference
        at com.example.refugioconsumidor.MainActivity.onStart(MainActivity.java:30)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1435)
        at android.app.Activity.performStart(Activity.java:8024)
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3475)
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

我认为问题与内容提供商身份有关。¿有人能帮忙吗?

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题