2015-06-24 71 views
0

這裏是什麼時候是logcat的:未知URI嘗試編輯/更新SQLite數據庫記錄

06-24 13:33:04.226 23618-23618 /? E/AndroidRuntime:致命例外:main 進程:com.example.saleh.findmypassword,PID:23618 java.lang.IllegalArgumentException:Unknown Uri:content://com.example.saleh.findmypassword.provider/PInfos/1 在com.example.saleh.findmypassword.PInfoProvider.update(PInfoProvider.java:161) 在android.content.ContentProvider $ Transport.update(ContentProvider.java:287) 在android.content.ContentResolver.update(ContentResolver.java :1316) at com.example.saleh.findmypassword.EditActivity $ 1.onClick(EditActivity.java:62) at android.view.View.performClick(View.java:4438) at android.view.View $ PerformClick。運行(View.java:18422) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5001) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java :785) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 在dalvik.system.NativeStart.main(本機方法)

內容提供者類:

public class PInfoProvider extends ContentProvider { 
    private PInfoDatabase mOpenHelper; 

    private static String TAG = PInfoProvider.class.getSimpleName(); 
    private static final UriMatcher sUriMatcher = buildUriMatcher(); 

    private static final int PINFOS = 100; 
    private static final int PINFOS_ID = 101; 

    private static UriMatcher buildUriMatcher(){ 
     final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); 
     final String authority = PInfoContract.CONTENT_AUTHORITY; 
     matcher.addURI(authority, "PInfos", PINFOS); 
     matcher.addURI(authority, "Pinfos/*", PINFOS_ID); 
     return matcher; 
    } 
    @Override 
    public boolean onCreate() { 
     mOpenHelper = new PInfoDatabase(getContext()); 
     return true; 
    } 

    private void deleteDatabase(){ 
     mOpenHelper.close(); 
     PInfoDatabase.deleteDatabase(getContext()); 
     mOpenHelper = new PInfoDatabase(getContext()); 
    } 
    @Override 
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 
     final SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 
     final int match = sUriMatcher.match(uri); 

     SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); 
     queryBuilder.setTables(PInfoDatabase.Tables.PINFOS); 

     switch(match){ 
      case PINFOS: 
       //do nothing 
       break; 
      case PINFOS_ID: 
       String id = PInfoContract.PInfos.getPInfoId(uri); 
       queryBuilder.appendWhere(BaseColumns._ID + "=" + id); 
       break; 
      default: 
       throw new IllegalArgumentException("Unknown Uri: " + uri); 
     } 

     Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder); 
     //projection in content provider means the list of columns you want to return. 
     return cursor; 

    } 

    @Override 
    public String getType(Uri uri) { 
     final int match = sUriMatcher.match(uri); 
     switch(match){ 
      case PINFOS: 
       return PInfoContract.PInfos.CONTENT_TYPE; 
      case PINFOS_ID: 
       return PInfoContract.PInfos.CONTENT_ITEM_TYPE; 
      default: 
       throw new IllegalArgumentException("Unknown Uri: " + uri); 
     } 
    } 

    @Override 
    public Uri insert(Uri uri, ContentValues values) { 
     //ContentValues: is a list of content values of our database such as the email and username. Contains the column names and the values we want to associate to it when we're writing to the database/ 
     Log.v(TAG, "insert(uri=" + uri + ", values =" + values.toString()); 

     final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 
     final int match = sUriMatcher.match(uri); 

     switch(match){ 
      case PINFOS:    //only using the PInfo and not the ID because it's to insert only. 
       long recordID = db.insertOrThrow(PInfoDatabase.Tables.PINFOS, null, values); //inserts a row into the database 
       return PInfoContract.PInfos.buildPInfoUri(String.valueOf(recordID)); 
      default: 
       throw new IllegalArgumentException("Unknown Uri: " + uri); 
     } 
    } 

    @Override 
    public int delete(Uri uri, String selection, String[] selectionArgs) { 
     Log.v(TAG, "delete(uri=" + uri); 

     if(uri.equals(PInfoContract.URI_TABLE)){ 
      deleteDatabase(); 
      return 0; 
      //This will be executed if the user didn't input a valid record id. 
      //Base content uri doesn't contain an ID nor a path. 
     } 
     final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 
     final int match = sUriMatcher.match(uri); 

     String selectionCriteria = selection; 

     switch(match){ 

      /* 
      case PInfo: 
       If this was called and didn't "break" it would change all the records in the table. 
       We will still leave it out because we added the database deletion code above. 
       break; 
      */ 

      case PINFOS_ID: 
       String id = PInfoContract.PInfos.getPInfoId(uri); 
       selectionCriteria = BaseColumns._ID + "=" + id 
         + (!TextUtils.isEmpty(selection) ? "AND (" + selection + ")" : ""); 
       return db.delete(PInfoDatabase.Tables.PINFOS, selectionCriteria, selectionArgs); 

      default: 
       throw new IllegalArgumentException("Unknown Uri: " + uri); 
     } 

    } 

    @Override 
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 
     Log.v(TAG, "update(uri=" + uri + ", values =" + values.toString()); 

     final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 
     final int match = sUriMatcher.match(uri); 

     String selectionCriteria = selection; 
     //We set selectionCriteria to equal selection in the case PInfo case was chosen. After all, 
     //we still need to record the selection. 

     switch(match){ 
      case PINFOS: 
       //do nothing 
       //If this was called and didn't "break" it would change all the records in the table. 
       break; 
      case PINFOS_ID: 
       String id = PInfoContract.PInfos.getPInfoId(uri); 
       selectionCriteria = BaseColumns._ID + "=" + id 
        + (!TextUtils.isEmpty(selection) ? "AND (" + selection + ")" : ""); 
       break; 

      default: 
       throw new IllegalArgumentException("Unknown Uri: " + uri); 
     } 
     return db.update(PInfoDatabase.Tables.PINFOS, values, selectionCriteria, selectionArgs); 
    } 
} 

EditActivity類:

public class EditActivity extends FragmentActivity { 
     private final String LOG_TAG = EditActivity.class.getSimpleName(); 
     private TextView mWebsiteTextView, mEmailTextView, mUsernameTextView, mPasswordTextView; 
     private Button mButton; 
     private ContentResolver mContentResolver; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.add_edit); //same layout as the AddActivity class. 
     getActionBar().setDisplayHomeAsUpEnabled(true); //returns up one level rather than back to the top level 

     mWebsiteTextView = (TextView) findViewById(R.id.pinfoWebsite); 
     mEmailTextView = (TextView) findViewById(R.id.pinfoEmail); 
     mUsernameTextView = (TextView) findViewById(R.id.pinfoUsername); 
     mPasswordTextView = (TextView) findViewById((R.id.pinfoPassword)); 

     mContentResolver = EditActivity.this.getContentResolver(); 

     Intent intent = getIntent(); //Getting the intent that was passed to this activity from the PInfoCustomAdapter class 
     final String _id = intent.getStringExtra(PInfoContract.PInfoColumns.PINFO_ID); 
     String website = intent.getStringExtra(PInfoContract.PInfoColumns.PINFO_WEBSITE); 
     String email = intent.getStringExtra(PInfoContract.PInfoColumns.PINFO_EMAIL); 
     String username= intent.getStringExtra(PInfoContract.PInfoColumns.PINFO_USERNAME); 
     String password = intent.getStringExtra(PInfoContract.PInfoColumns.PINFO_PASSWORD); 

     //Now to populate what's on screen: 
     mWebsiteTextView.setText(website); 
     mEmailTextView.setText(email); 
     mUsernameTextView.setText(username); 
     mPasswordTextView.setText(password); 

     mButton = (Button) findViewById(R.id.saveButton); 
     mButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       ContentValues values = new ContentValues(); //Content Values Class is used to store a set of values that the ContentResolver can process. 
       values.put(PInfoContract.PInfoColumns.PINFO_WEBSITE, mWebsiteTextView.getText().toString()); //.put add values ot the set & .toString() to convert it to the right format 
       values.put(PInfoContract.PInfoColumns.PINFO_EMAIL, mEmailTextView.getText().toString()); 
       values.put(PInfoContract.PInfoColumns.PINFO_USERNAME, mUsernameTextView.getText().toString()); 
       values.put(PInfoContract.PInfoColumns.PINFO_PASSWORD, mPasswordTextView.getText().toString()); 

       Uri uri = PInfoContract.PInfos.buildPInfoUri(_id); //To know which record we're dealing with 
       int recordsUpdated = mContentResolver.update(uri, values, null, null); 
       Log.d(LOG_TAG, "Number of records updated = " + recordsUpdated); 
       Intent intent = new Intent(EditActivity.this, MainActivity.class); 
       startActivity(intent); 
       finish(); //always use this when the activity's process is finished 
      } 
     }); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()){ 
      case android.R.id.home: 
       NavUtils.navigateUpFromSameTask(this); //Just allows to navigate back to the parent method. So: when someone presses home it will go back to the kain menu 
       break; 
     } 
     return true; 
    } 
} 

類,其中正在創建URI:

public class PInfoContract { 
     interface PInfoColumns { 
      String PINFO_ID = "_id"; 
      String PINFO_WEBSITE = "PInfo_Website"; 
      String PINFO_EMAIL = "PInfo_Email"; 
      String PINFO_USERNAME = "PInfo_Username"; 
      String PINFO_PASSWORD = "PInfo_Password"; 
     } 

public static final String CONTENT_AUTHORITY = "com.example.saleh.findmypassword.provider"; 
    public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY); 

    public static final String PATH_PINFOS = "PInfos"; 
    public static final Uri URI_TABLE = Uri.parse(BASE_CONTENT_URI.toString() + "/" + PATH_PINFOS); 

    public static final String[] TOP_LEVEL_PATHS = { 
      PATH_PINFOS 
    }; 

    public static class PInfos implements PInfoColumns, BaseColumns { 
     public static final Uri CONTENT_URI = 
       BASE_CONTENT_URI.buildUpon().appendEncodedPath(PATH_PINFOS).build(); 
     public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd." + CONTENT_AUTHORITY + ".PInfos"; 
     public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd." + CONTENT_AUTHORITY + ".PInfos"; 

     public static Uri buildPInfoUri(String pinfoid) { 
      return CONTENT_URI.buildUpon().appendEncodedPath(pinfoid).build(); 
     } 

     public static String getPInfoId(Uri uri) { 
      return uri.getPathSegments().get(1); 
     } 

    } 


} 

清單:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.saleh.findmypassword"> 

    <permission android:name="com.example.saleh.findmypassword.provider.READWRITE" /> 

    <uses-permission android:name="com.example.saleh.findmypassword.provider.READWRITE" /> 
    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@android:style/Theme.WithActionBar"> 
     <activity 
      android:name=".MainActivity" 
      android:label="Personal Info"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

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

     <activity 
      android:name=".AddActivity" 
      android:label="@string/add_pinfo_title" 
      android:parentActivityName=".MainActivity" 
      android:noHistory="true"/> 


     <activity 
      android:name=".EditActivity" 
      android:label="@string/edit_pinfo_title" 
      android:parentActivityName="com.example.saleh.findmypassword.MainActivity" 
      android:noHistory="true"/> 

     <activity 
      android:name=".SearchActivity" 
      android:label="@string/search_pinfo_title" 
      android:parentActivityName=".MainActivity" 
      android:noHistory="true"/> 

     <provider 
      android:name="com.example.saleh.findmypassword.PInfoProvider" 
      android:authorities="com.example.saleh.findmypassword.provider" 
      android:exported="true" 
      android:readPermission="com.example.saleh.findmypassword.provider.READWRITE" 
      android:writePermission="com.example.saleh.findmypassword.provider.READWRITE" /> 
    </application> 

</manifest> 

回答

0

你UriMatcher是匹配任何文本「Pinfos/*「,並且它應該匹配任何數字」Pinfos /#「

docs

+0

剛剛嘗試過,仍然是同樣的錯誤。 – Sora

+0

還有一個小寫「我」在「Pinfos /#」 – ILovemyPoncho

+0

老兄我愛你謝謝!!!!!!!!!!! – Sora