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);
}
});
}
}