Access data using ContentProvider

0

I am trying to access an application with a Content Provider from another application by reference to a Content Resolver. But something I have done wrong and I can not figure out what. For the error that it throws seems not to square the URI, but for more than I have reviewed it and compared with solutions that I have found in the network I do not manage to solve it.

Error message that occurs:

E/ActivityThread: Failed to find provider info for com.example.usuario.contenproviderusuarios
D/AndroidRuntime: Shutting down VM


                  --------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.example.usuario.contentresolverusuarios, PID: 2456
                  java.lang.NullPointerException: Attempt to invoke interface method 'boolean android.database.Cursor.moveToFirst()' on a null object reference
                      at com.example.usuario.contentresolverusuarios.MainActivity$1.onClick(MainActivity.java:45)
                      at android.view.View.performClick(View.java:5198)
                      at android.view.View$PerformClick.run(View.java:21147)
                      at android.os.Handler.handleCallback(Handler.java:739)
                      at android.os.Handler.dispatchMessage(Handler.java:95)
                      at android.os.Looper.loop(Looper.java:148)
                      at android.app.ActivityThread.main(ActivityThread.java:5417)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

ContentProviderUsers application:

package com.example.usuario.contenproviderusuarios;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.provider.BaseColumns;
import android.support.annotation.Nullable;

public class UsuariosProvider extends ContentProvider
{
    private static final String uri = "content://com.example.usuario.contenproviderusuarios/tblUsuarios";
    public static final Uri CONTENT_URI = Uri.parse(uri);

    //Clase interna para declarar las constantes de columna
    public static final class Usuarios implements BaseColumns
    {
        private Usuarios()
        {
        }

        //Nombres de columnas
        public static final String COL_USUARIO = "usuario";
        public static final String COL_PASSWORD = "password";
        public static final String COL_EMAIL = "email";
    }

    //Base de datos
    private UsuariosSQLiteHelper usuarioDBH;
    private static final String BD_NOMBRE = "DBUsuarios";
    private static final int BD_VERSION = 1;
    private static final String TABLA_USUARIOS = "tblUsuarios";

    //UriMatcher
    private static final int USUARIOS = 1;
    private static final int USUARIOS_ID = 2;
    private static final UriMatcher uriMatcher;

    //Inicializamos el UriMatcher
    static
    {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI("com.example.usuario.contenproviderusuarios", "tblUsuarios", USUARIOS);
        uriMatcher.addURI("com.example.usuario.contenproviderusuarios", "tblUsuarios/#", USUARIOS_ID);
    }

    @Override
    public boolean onCreate()
    {
        usuarioDBH = new UsuariosSQLiteHelper(getContext(), BD_NOMBRE, null, BD_VERSION);
        return true;
    }

    @Nullable
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
    {
        //Si es una consulta a un ID concreto construimos el WHERE
        String where = selection;
        if (uriMatcher.match(uri) == USUARIOS_ID)
        {
            where = "_id=" + uri.getLastPathSegment();
        }

        SQLiteDatabase db = usuarioDBH.getWritableDatabase();
        Cursor c = db.query(TABLA_USUARIOS, projection, where, selectionArgs, null, null, sortOrder);
        return c;
    }

    @Nullable
    @Override
    public String getType(Uri uri)
    {
        int match = uriMatcher.match(uri);
        switch (match)
        {
            case USUARIOS:
                return "vnd.android.cursor.dir/vnd.example.contentproviders";
            case USUARIOS_ID:
                return "vnd.android.cursor.item/vnd.example.contentproviders";
            default:
                return null;
        }
    }

    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues values)
    {
        long regId = 1;

        SQLiteDatabase db = usuarioDBH.getWritableDatabase();
        regId = db.insert(TABLA_USUARIOS, null, values);

        Uri newUri = ContentUris.withAppendedId(CONTENT_URI, regId);
        return newUri;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs)
    {
        int cont;

        //Si es una consulta a un ID concreto construimos el WHERE
        String where = selection;

        if (uriMatcher.match(uri) == USUARIOS_ID)
        {
            where = "_id=" + uri.getLastPathSegment();
        }
        SQLiteDatabase db = usuarioDBH.getWritableDatabase();
        cont = db.delete(TABLA_USUARIOS, where, selectionArgs);
        return cont;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
    {
        int cont;

        //Si es una consulta a un ID concreto construimos el WHERE
        String where = selection;
        if (uriMatcher.match(uri) == USUARIOS_ID)
        {
            where = "_id=" + uri.getLastPathSegment();
        }

        SQLiteDatabase db = usuarioDBH.getWritableDatabase();
        cont = db.update(TABLA_USUARIOS, values, where, selectionArgs);
        return cont;
    }
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.usuario.contenproviderusuarios">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <provider
            android:name="UsuariosProvider"
            android:authorities="com.example.usuario.contenproviderusuarios"/>

    </application>

</manifest>

ContentResolverUsers application:

package com.example.usuario.contentresolverusuarios;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity
{
    private Button btnConsultar;
    private Button btnInsertar;
    private Button btnEliminar;
    private TextView txtResultados;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        txtResultados = (TextView) findViewById(R.id.TxtResultados);

        btnConsultar = (Button) findViewById(R.id.BtnConsultar);
        btnConsultar.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View arg0)
            {
                //Columnas de la tabla a recuperar
                String[] proyeccion = new String[]{"_id", "usuario", "password", "email"};

                //Incorporamos el uri al que queremos acceder
                String uri = "content://com.example.usuario.contenproviderusuarios/tblUsuarios";
                Uri usuariosUri = Uri.parse(uri);

                //Obtenemos una referencia al content provider al que queremos acceder
                ContentResolver cr = getContentResolver();

                //Hacemos la consulta
                Cursor cur = cr.query(usuariosUri, proyeccion, null, null, null);
                if (cur.moveToFirst())
                {
                    String usuario, password, email;

                    int colUsuario = cur.getColumnIndex("usuario");
                    int colPassword = cur.getColumnIndex("password");
                    int colEmail = cur.getColumnIndex("email");

                    txtResultados.setText("");
                    do
                    {
                        usuario = cur.getString(colUsuario);
                        password = cur.getString(colPassword);
                        email = cur.getString(colEmail);

                        txtResultados.append(usuario + " - " + password + " - " + email + "\n");

                    } while (cur.moveToNext());
                }
            }
        });

        btnInsertar = (Button) findViewById(R.id.BtnInsertar);
        btnInsertar.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View arg0)
            {
                //Creamos los datos de un usuario nuevo
                ContentValues values = new ContentValues();
                values.put("usuario", "UsuarioN");
                values.put("password", "PasswordXXX");
                values.put("email", "[email protected]");

                //Incorporamos el uri al que queremos acceder
                String uri = "content://com.example.usuario.contenproviderusuarios/tblUsuarios";
                Uri usuariosUri = Uri.parse(uri);

                //Obtenemos una referencia al content provider al que queremos acceder
                ContentResolver cr = getContentResolver();

                //Insertamos un usuario nuevo
                cr.insert(usuariosUri, values);
            }
        });

        btnEliminar = (Button) findViewById(R.id.BtnEliminar);
        btnEliminar.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View arg0)
            {
                //Incorporamos el uri al que queremos acceder
                String uri = "content://com.example.usuario.contenproviderusuarios/tblUsuarios";
                Uri usuariosUri = Uri.parse(uri);

                //Obtenemos una referencia al content provider al que queremos acceder
                ContentResolver cr = getContentResolver();

                //Eliminamos el usuario introducido con el botón de Insertar
                cr.delete(usuariosUri, "usuario" + " = 'UsuarioN'", null);
            }
        });
    }
}
    
asked by Oemtri 08.01.2017 в 19:03
source

1 answer

0

I have kept looking for information about it and finally I found the error. I publish the solution in case someone in my situation can serve him in the future.

SOLUTION : Add the exported attribute of the provider tag in the AndroidManifest of the application that contains the ContentProvider, leaving the following:

<provider
    android:name=".UsuariosProvider"
    android:authorities="com.example.usuario.contenproviderusuarios"
    android:exported="true">
</provider>
    
answered by 08.01.2017 в 22:00