0

私は自分のコンテンツプロバイダをユーザー用にコーディングしようとしています。ユーザーが存在するかどうかを検証しようとすると、DBHelperがデータベースを作成しようとすると、null例外がスローされます。ここでDBHelper.getWirtableDatabseがnull例外をスローする

は、コンテンツプロバイダである:

public class MyUserProvider extends ContentProvider { 
    private UserDBHelper db; 

    private static final int USERS = 10; 
    private static final int USER_ID = 20; 

    private static final String AUTHORITY = 
      "net.ifo420.ritc.agenda.userprovider"; 

    private static final String BASE_PATH = "users"; 
    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY 
             + "/" + BASE_PATH); 

    public static final String CONTENT_TYPE = 
      ContentResolver.CURSOR_DIR_BASE_TYPE + "/users"; 

    public static final String CONTENT_ITEM_TYPE = 
      ContentResolver.CURSOR_ITEM_BASE_TYPE + "/user"; 

    private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 

    static { 
     uriMatcher.addURI(AUTHORITY, BASE_PATH, USERS); 
     uriMatcher.addURI(AUTHORITY, BASE_PATH + "/#", USER_ID); 
    } 

    public MyUserProvider() { 
    } 

    @Override 
    public boolean onCreate() { 
     db = new UserDBHelper(getContext()); 
     return false; 
    } 

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

     checkColumns(projection); 

     queryBuilder.setTables(UserTable.TABLE); 

     int uriType = uriMatcher.match(uri); 
     switch (uriType) { 
      case USERS: 
       break; 
      case USER_ID: 
       queryBuilder.appendWhere(UserTable.COLUMN_ID + " = " + uri.getLastPathSegment()); 
       break; 
      default: 
       throw new IllegalArgumentException("Uknown uri " + uri); 
     } 
     SQLiteDatabase db1 = db.getReadableDatabase(); 
     Cursor cursor = queryBuilder.query(db1, projection, selection, selectionArgs, 
       null, null, sortOrder); 

     cursor.setNotificationUri(getContext().getContentResolver(), uri); 

     return cursor; 
    } 

    @Override 
    public String getType(Uri uri) { 
     return null; 
    } 

    @Override 
    public Uri insert(Uri uri, ContentValues values) { 
     int uriType = uriMatcher.match(uri); 
     SQLiteDatabase database = db.getReadableDatabase(); 
     long id = 0; 
     switch (uriType) { 
      case USERS: 
       id = database.insert(UserTable.TABLE, null, values); 
       break; 
      default: 
       throw new IllegalArgumentException("Unknown URI: " + uri); 
     } 
     getContext().getContentResolver().notifyChange(uri, null); 
     return Uri.parse(BASE_PATH + "/" + id); 
    } 

    @Override 
    public int delete(Uri uri, String selection, String[] selectionArgs) { 
     int uriType = uriMatcher.match(uri); 
     SQLiteDatabase sqLiteDatabase = db.getReadableDatabase(); 
     int rowsDeleted = 0; 
     switch (uriType) { 
      case USERS: 
       rowsDeleted = sqLiteDatabase.delete(UserTable.TABLE, selection, 
         selectionArgs); 
       break; 
      case USER_ID: 
       String id = uri.getLastPathSegment(); 
       if(TextUtils.isEmpty(selection)) { 
        rowsDeleted = sqLiteDatabase.delete(UserTable.TABLE, 
          UserTable.COLUMN_ID + " = " + id, null); 
       } else { 
        rowsDeleted = sqLiteDatabase.delete(UserTable.TABLE, 
          UserTable.COLUMN_ID + " = " + id + " and " + 
        selection, selectionArgs); 
       } 
       break; 
      default: 
       throw new IllegalArgumentException("Unknown URI: " + uri); 
     } 
     getContext().getContentResolver().notifyChange(uri, null); 
     return rowsDeleted; 
    } 

    @Override 
    public int update(Uri uri, ContentValues values, String selection, 
         String[] selectionArgs) { 
     int uriType = uriMatcher.match(uri); 
     SQLiteDatabase sqLiteDatabase = db.getReadableDatabase(); 
     int rowsUpdated = 0; 
     switch (uriType) { 
      case USERS: 
       rowsUpdated = sqLiteDatabase.update(UserTable.TABLE, 
         values, 
         selection, 
         selectionArgs); 
       break; 
      case USER_ID: 
       String id = uri.getLastPathSegment(); 
       if (TextUtils.isEmpty(selection)) { 
        rowsUpdated = sqLiteDatabase.update(UserTable.TABLE, 
          values, 
          UserTable.COLUMN_ID + "=" + id, 
          null); 
       } else { 
        rowsUpdated = sqLiteDatabase.update(UserTable.TABLE, 
          values, 
          UserTable.COLUMN_ID + "=" + id 
            + " and " 
            + selection, 
          selectionArgs); 
       } 
       break; 
      default: 
       throw new IllegalArgumentException("Unknown URI: " + uri); 
     } 
     getContext().getContentResolver().notifyChange(uri, null); 
     return rowsUpdated; 
    } 

    private void checkColumns(String[] projection) { 
     String[] available = {UserTable.COLUMN_USERNAME, UserTable.COLUMN_PASSWORD, 
          UserTable.COLUMN_ID}; 

     if (projection != null) { 

      HashSet<String> requestedColumns = 
        new HashSet<String>(Arrays.asList(projection)); 
      HashSet<String> availableColumns = 
        new HashSet<String>(Arrays.asList(available)); 

      if (!availableColumns.containsAll(requestedColumns)) { 
       throw new IllegalArgumentException("Unknown columns in projection"); 
      } 
     } 
    } 

ここに私のDBHelperここ

public class UserDBHelper extends SQLiteOpenHelper { 
    private static final String DB_NAME = "agenda.db"; 
    private static final int DB_VERSION = 1; 

    public UserDBHelper (Context context) { 
     super(context, DB_NAME, null, DB_VERSION); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     UserTable.onCreate(db); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     UserTable.onUpgrade(db, oldVersion, newVersion); 
    } 

Here is the sample code I am using to verify if the user exists (sorry a bit is in french): 

     public void onClick(View view) { 
     switch (view.getId()) { 
      case R.id.boutonLogin: 
       if (userExists()) { 
        Toast.makeText(this, "L'utilisateur existe.", Toast.LENGTH_SHORT).show(); 
       } else { 
        Toast.makeText(this, "L'utilisateur n'existe pas.", Toast.LENGTH_SHORT).show(); 
       } 
    } 

    private boolean userExists() { 
     String username = nomUtilisateur.getText().toString(); 
     String password = motPasse.getText().toString(); 

     Cursor users = userProvider.query(MyUserProvider.CONTENT_URI, 
       null, 
       " WHERE username = " + nomUtilisateur.getText().toString() + 
       " AND password = " + motPasse.getText().toString(), null, null); 

     if (users.getCount() != 0) { 
      return true; 
     } else { 
      return false; 
     } 

はlogcatが私を与えるものです。

java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase net.info420.ritc.agendacegep.UserDBHelper.getReadableDatabase()' on a null object reference 
    at net.info420.ritc.agendacegep.MyUserProvider.query(MyUserProvider.java:70) 
    at net.info420.ritc.agendacegep.LoginActivity.utilisateurExiste(LoginActivity.java:69) 
    at net.info420.ritc.agendacegep.LoginActivity.onClick(LoginActivity.java:57) 
    at android.view.View.performClick(View.java:5610) 
    at android.view.View$PerformClick.run(View.java:22260) 
    at android.os.Handler.handleCallback(Handler.java:751) 
    at android.os.Handler.dispatchMessage(Handler.java:95) 
    at android.os.Looper.loop(Looper.java:154) 
    at android.app.ActivityThread.main(ActivityThread.java:6077) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 
+0

'onCreate'で' return true 'にしてください –

+0

まだ動作しません –

答えて

0

さて、私は自分の答えを得ました。はい、ContentProviderをインスタンス化できませんでしたが、それだけではありませんでした。私は自分のコードを変更し、クエリのselectionとselectionArgsパラメータを実際には下回っていないことに気付きました。

だから、から行った:だから、私は正しいクエリを作成していなかったので、カーソルがnullだったし、私のデータベースが作成されなかった理由です

private boolean userExists() { 
    String username = nomUtilisateur.getText().toString(); 
    String password = motPasse.getText().toString(); 
    String[] selection = {username, password}; 

    Cursor users = getApplicationContext().getContentResolver().query 
      (Agenda.UserEntry.CONTENT_URI, 
      null, 
      "username = ? AND password = ?", selection, null); 

    if (users.getCount() != 0) { 
     return true; 
    } else { 
     return false; 
    } 
} 

:へ

private boolean userExists() { 
    String username = nomUtilisateur.getText().toString(); 
    String password = motPasse.getText().toString(); 

    Cursor users = userProvider.query(MyUserProvider.CONTENT_URI, 
      null, 
      " WHERE username = " + nomUtilisateur.getText().toString() + 
      " AND password = " + motPasse.getText().toString(), null, null); 

    if (users.getCount() != 0) { 
     return true; 
    } else { 
     return false; 
    } 
} 

理由私はコードの最後にそれを必要としませんでした。

0

あなたは直接インスタンス化することはできませんし、 ContentProviderを呼び出すと、コンテンツリゾルバを経由する必要があります。それ以外の場合は、プロバイダのライフサイクルを経ず、onCreateは呼び出されません。

+0

カーソルが返す結果の数を取得しようとすると例外がスローされるようになりました。それはそれがnullであると言います、そして、私がdatabseを見ることを試みるとき、それは作成されません。 –

+0

私はタグを使っていくつかのテストを実行していましたが、getWritableDatabase()を使用するときではなく、アプリケーションの開始時にonCreateメソッドが呼び出されていることに気付きました。そして、私がそれを呼び出すときでも、query()メソッドは呼び出されないので、カーソルはnullですが、databseはまだ作成されません。 –

+0

私の答えを得ました、そして、問題の一部はあなたが言及したものでした。ありがとう! –

関連する問題