title: java.lang.SecurityException: Permission Denial: opening provider when implement content provider
body: <p>i have problem went i try to implement content provider, in my comsumer apps :</p>
  
  <p>This is my Android Manifest from App A (Provider) :</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.erlanggakmoekasan.imovie"&gt;
      &lt;permission android:name="com.erlanggakmoekasan.imovie.READ_DATABASE" android:protectionLevel="normal" /&gt;
      &lt;permission android:name="com.erlanggakmoekasan.imovie.WRITE_DATABASE" android:protectionLevel="normal" /&gt;
      &lt;uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /&gt;
      &lt;uses-permission android:name="android.permission.INTERNET" /&gt;
  
      &lt;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/AppTheme"
          android:usesCleartextTraffic="true"&gt;
          &lt;receiver android:name=".widgets.MoviesWidget"&gt;
              &lt;intent-filter&gt;
                  &lt;action android:name="android.appwidget.action.APPWIDGET_UPDATE" /&gt;
              &lt;/intent-filter&gt;
  
              &lt;meta-data
                  android:name="android.appwidget.provider"
                  android:resource="@xml/movies_widget_info" /&gt;
          &lt;/receiver&gt;
  
          &lt;activity android:name=".activity.TvShowActivitySearch" /&gt;
          &lt;activity android:name=".activity.MovieActivitySearch" /&gt;
          &lt;activity android:name=".activity.TvShowActivity" /&gt;
          &lt;activity
              android:name=".activity.MainActivity"
              android:configChanges="orientation|screenSize|keyboardHidden"
              android:label="@string/app_name"&gt;
              &lt;intent-filter&gt;
                  &lt;action android:name="android.intent.action.MAIN" /&gt;
  
                  &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
              &lt;/intent-filter&gt;
          &lt;/activity&gt;
          &lt;activity android:name=".activity.MovieActivity"&gt;
              &lt;meta-data
                  android:name="android.support.PARENT_ACTIVITY"
                  android:value=".activity.MainActivity" /&gt;
          &lt;/activity&gt;
          &lt;provider
              android:authorities="com.erlanggakmoekasan.imovie"
              android:name=".provider.MoviesProvider"
              android:exported="true"
              android:readPermission="com.erlanggakmoekasan.imovie.READ_DATABASE"
              android:writePermission="com.erlanggakmoekasan.imovie.WRITE_DATABASE" /&gt;
          &lt;service
              android:name="com.erlanggakmoekasan.imovie.widgets.StackWidgetService"
              android:permission="android.permission.BIND_REMOTEVIEWS" /&gt;
  
      &lt;/application&gt;
  
  &lt;/manifest&gt;
  </code></pre>
  
  <p>This is my Android Manifest from App B (Consumer) :</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.erlanggakmoekasan.favoritemovies"&gt;
  
      &lt;uses-permission android:name="android.permission.INTERNET"/&gt;
      &lt;permission android:name="com.erlanggakmoekasan.imovie.READ_DATABASE" /&gt;
      &lt;permission android:name="com.erlanggakmoekasan.imovie.WRITE_DATABASE" /&gt;
  
      &lt;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/AppTheme"&gt;
          &lt;activity android:name=".activity.MainActivity"&gt;
              &lt;intent-filter&gt;
                  &lt;action android:name="android.intent.action.MAIN" /&gt;
  
                  &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
              &lt;/intent-filter&gt;
          &lt;/activity&gt;
      &lt;/application&gt;
  
  &lt;/manifest&gt;
  </code></pre>
  
  <p>My Provider from App A :</p>
  
  <pre><code>package com.erlanggakmoekasan.imovie.provider;
  
  import android.content.ContentProvider;
  import android.content.ContentValues;
  import android.content.UriMatcher;
  import android.database.Cursor;
  import android.net.Uri;
  import android.support.annotation.Nullable;
  import com.erlanggakmoekasan.imovie.utils.MoviesHelper;
  
  import static com.erlanggakmoekasan.imovie.utils.MoviesContract.AUTHORITY;
  import static com.erlanggakmoekasan.imovie.utils.MoviesContract.MoviesColumns.CONTENT_URI;
  import static com.erlanggakmoekasan.imovie.utils.MoviesContract.MoviesColumns.TABLE_NAME;
  
  public class MoviesProvider extends ContentProvider {
      private static final int MOVIES = 1;
      private static final int MOVIES_ID = 2;
      private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
      static {
  
          // content://com.erlanggastudio.imovie/movies
          sUriMatcher.addURI(AUTHORITY, TABLE_NAME, MOVIES);
  
          // content://com.erlanggastudio.imovie/movies/id
          sUriMatcher.addURI(AUTHORITY,
                  TABLE_NAME+ "/#",
                  MOVIES_ID);
      }
      private MoviesHelper moviesHelper;
  
      @Override
      public boolean onCreate() {
          moviesHelper = MoviesHelper.getInstance(getContext());
          return false;
      }
  
      @Nullable
      @Override
      public Cursor query(@Nullable Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
          moviesHelper.open();
          Cursor cursor;
          switch (sUriMatcher.match(uri)) {
              case MOVIES:
                  cursor = moviesHelper.queryProvider();
                  break;
              case MOVIES_ID:
                  cursor = moviesHelper.queryByIdProvider(uri.getLastPathSegment());
                  break;
              default:
                  cursor = null;
                  break;
          }
          if (cursor!=null){
  
              cursor.setNotificationUri(getContext().getContentResolver(),uri);
          }
          return cursor;
      }
  
      @Nullable
      @Override
      public String getType(@Nullable Uri uri) {
          return null;
      }
  
      @Nullable
      @Override
      public Uri insert(@Nullable Uri uri, @Nullable ContentValues values) {
          moviesHelper.open();
          long added ;
  
          switch (sUriMatcher.match(uri)){
              case MOVIES:
                  added = moviesHelper.insertProvider(values);
                  break;
              default:
                  added = 0;
                  break;
          }
  
          if (added &gt; 0) {
              getContext().getContentResolver().notifyChange(uri, null);
          }
          return Uri.parse(CONTENT_URI + "/" + added);
      }
  
      @Nullable
      public int delete(@Nullable Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
          moviesHelper.open();
          int deleted;
          switch (sUriMatcher.match(uri)) {
              case MOVIES_ID:
                  deleted =  moviesHelper.deleteProvider(uri.getLastPathSegment());
                  break;
              default:
                  deleted = 0;
                  break;
          }
  
          if (deleted &gt; 0) {
              getContext().getContentResolver().notifyChange(uri, null);
          }
          return deleted;
      }
  
      @Nullable
      public int update(@Nullable Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
          moviesHelper.open();
          int movieUpdated ;
          switch (sUriMatcher.match(uri)) {
              case MOVIES_ID:
                  movieUpdated =  moviesHelper.updateProvider(uri.getLastPathSegment(),values);
                  break;
              default:
                  movieUpdated = 0;
                  break;
          }
  
          if (movieUpdated &gt; 0) {
              getContext().getContentResolver().notifyChange(uri, null);
          }
          return movieUpdated;
      }
  }
  </code></pre>
  
  <p>My Main Activity from App B :</p>
  
  <pre><code>package com.erlanggakmoekasan.favoritemovies.activity;
  
  import android.content.Context;
  import android.database.ContentObserver;
  import android.database.Cursor;
  import android.os.AsyncTask;
  import android.os.Handler;
  import android.os.HandlerThread;
  import android.support.v7.app.AppCompatActivity;
  import android.os.Bundle;
  import android.support.v7.widget.LinearLayoutManager;
  import android.support.v7.widget.RecyclerView;
  import android.widget.Toast;
  
  import com.erlanggakmoekasan.favoritemovies.R;
  import com.erlanggakmoekasan.favoritemovies.adapter.MoviesAdapter;
  import com.erlanggakmoekasan.favoritemovies.callback.MoviesCallback;
  import com.erlanggakmoekasan.favoritemovies.model.Movie;
  
  import java.lang.ref.WeakReference;
  import java.util.ArrayList;
  
  import static com.erlanggakmoekasan.favoritemovies.entity.MappingHelper.mapCursorToArrayList;
  import static com.erlanggakmoekasan.favoritemovies.utils.MoviesContract.MoviesColumns.CONTENT_URI;
  
  public class MainActivity extends AppCompatActivity implements MoviesCallback {
  
      private DataObserver myObserver;
      private RecyclerView moviesList;
      private MoviesAdapter moviesAdapter;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
  
          moviesList = findViewById(R.id.movie_list);
          moviesAdapter = new MoviesAdapter(this);
          moviesList.setLayoutManager(new LinearLayoutManager(this));
          moviesList.setHasFixedSize(true);
          moviesList.setAdapter(moviesAdapter);
          HandlerThread handlerThread = new HandlerThread("DataObserver");
          handlerThread.start();
          Handler handler = new Handler(handlerThread.getLooper());
          myObserver = new DataObserver(handler, this);
          getContentResolver().registerContentObserver(CONTENT_URI, true, myObserver);
          new getData(this, this).execute();
  
      }
  
      @Override
      public void postExecute(Cursor movie) {
  
          ArrayList&lt;Movie&gt; listMovie = mapCursorToArrayList(movie);
          if (listMovie.size() &gt; 0) {
              moviesAdapter.setListMovies(listMovie);
          } else {
              Toast.makeText(this, "Tidak Ada data saat ini", Toast.LENGTH_SHORT).show();
              moviesAdapter.setListMovies(new ArrayList&lt;Movie&gt;());
          }
      }
  
  
      private static class getData extends AsyncTask&lt;Void, Void, Cursor&gt; {
          private final WeakReference&lt;Context&gt; weakContext;
          private final WeakReference&lt;MoviesCallback&gt; weakCallback;
  
  
          private getData(Context context, MoviesCallback callback) {
              weakContext = new WeakReference&lt;&gt;(context);
              weakCallback = new WeakReference&lt;&gt;(callback);
          }
  
          @Override
          protected Cursor doInBackground(Void... voids) {
              return weakContext.get().getContentResolver().query(CONTENT_URI, null, null, null, null);
          }
  
          @Override
          protected void onPostExecute(Cursor data) {
              super.onPostExecute(data);
              weakCallback.get().postExecute(data);
          }
  
      }
  
      static class DataObserver extends ContentObserver {
  
          final Context context;
  
          DataObserver(Handler handler, Context context) {
              super(handler);
              this.context = context;
          }
  
          @Override
          public void onChange(boolean selfChange) {
              super.onChange(selfChange);
              new getData(context, (MainActivity) context).execute();
          }
      }
  }
  </code></pre>
  
  <p>The error is :</p>
  
  <blockquote>
    <p>Process: com.erlanggakmoekasan.favoritemovies, PID: 27146
    java.lang.RuntimeException: Unable to start activity
    ComponentInfo{com.erlanggakmoekasan.favoritemovies/com.erlanggakmoekasan.favoritemovies.activity.MainActivity}:
    java.lang.SecurityException: Permission Denial: opening provider
    com.erlanggakmoekasan.imovie.provider.MoviesProvider from
    ProcessRecord{7b99e1ed0
    27146:com.erlanggakmoekasan.favoritemovies/u0a307} (pid=27146,
    uid=10307) requires com.erlanggakmoekasan.imovie.READ_DATABASE or
    com.erlanggakmoekasan.imovie.WRITE_DATABASE</p>
  </blockquote>
  
  <p>the error when trying to call <code>getContentResolver().registerContentObserver(CONTENT_URI, true, myObserver);</code></p>
  
  <p>from app B
  Any solution for my problem???</p>