Joan Casadellà
Joan Casadellà

Reputation: 286

Extended Calendar View - Content provider permission denied requires signature

I'm trying to show daily view for one android Aplication. I decided to use the library ExtendedCalendarView and I can't make it run.

What I'm doing?

First of all, I downloaded the library from github and import into my workspace. Then, I import de library to my project. It seems to be well imported (with the green tick).

In my MainActivity.java I'm not doing nothing:

public class MainActivity extends Activity {

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

}

In my design XML files I have the code to show the xml. (It's the same that are in the github):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent" >

<com.tyczj.extendedcalendarview.ExtendedCalendarView 
    android:id="@+id/calendar"
    android:layout_height="match_parent"
    android:layout_width="match_parent"/>

</RelativeLayout>

Fially, in the AndroidManifest.xml I declare the ContentProvider into the tag:

<provider
        android:name="com.tyczj.extendedcalendarview.CalendarProvider"
        android:authorities="com.tyczj.extendedcalendarview.cAlEndarprovider" />

What is happening?

When compile the error, the APP crash with this error message on the log:

FATAL EXCEPTION: AsyncTask #1 java.lang.RuntimeException: An error occured while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:299) at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) at java.util.concurrent.FutureTask.setException(FutureTask.java:124) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) at java.util.concurrent.FutureTask.run(FutureTask.java:137) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) at java.lang.Thread.run(Thread.java:856)

Caused by: java.lang.SecurityException: Permission Denial: opening provider com.tyczj.extendedcalendarview.CalendarProvider from ProcessRecord{42dc32a8 8394:com.jcasadella.testcalendar/u0a145} (pid=8394, uid=10145) requires signature or signature at android.os.Parcel.readException(Parcel.java:1425) at android.os.Parcel.readException(Parcel.java:1379) at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:2561) at android.app.ActivityThread.acquireProvider(ActivityThread.java:4347) at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:1836) at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1129) at android.content.ContentResolver.query(ContentResolver.java:378) at android.content.ContentResolver.query(ContentResolver.java:336) at com.tyczj.extendedcalendarview.Day$GetEvents.doInBackground(Day.java:122) at com.tyczj.extendedcalendarview.Day$GetEvents.doInBackground(Day.java:1) at android.os.AsyncTask$2.call(AsyncTask.java:287) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)

What are my research?

I searched a lot of pages (stackoverflow) and others and I can't found nobody with this error.

It seems to be some permission I forgot. For the moment I never used ContentProvider and maybe the problem are here...

I read documentation in android developers oficial page and now I'm little confused for why the library are using ContentProvider.

Also I visit the issuses page in github to search some solution, but bad luck.

The question

The questions I have are:

1) Can use this library without using ContentProvider? Saving the events in sqlite or in memory... If I can, please point me to right direction.

2) What is the reason of the error I write beffore? Can someone point me a possible solution?

News (12/06/2014)

I tested the same APP in other device and it was working! I don't know what is happening:

Samusng Galaxy S3 (Android 4.3) -> Works perfectly

Samsung Tab 3 (tablet Android 4.1) -> permission denial error.

This APP will ned to work in a tablet tab3 with android between 4.1 and 4.3. Now, I'm going to open and issuse in the library github page. If I've more results i'll post here in answer format.

Thanks in advance! I appreciate your hard work in stackoverflow every day.

(Sorry for my english)

Upvotes: 1

Views: 2078

Answers (1)

Alexander Sidikov Pfeif
Alexander Sidikov Pfeif

Reputation: 2435

You Can write your own provider - like this

(Dirty code - but should works)

CalendarProviderLocal.java

public class CalendarProviderLocal  {

    private static final String DATABASE_NAME = "Calendar";
    private static final String EVENTS_TABLE = "events";
    private static final int DATABASE_VERSION = 4;

    public static final String EVENT = "event";
    public static final String LOCATION = "location";
    public static final String DESCRIPTION = "description";
    public static final String START = "start";
    public static final String END = "end";
    public static final String ID = "_id";
    public static final String START_DAY = "start_day";
    public static final String END_DAY = "end_day";
    public static final String COLOR = "color";

//  private static final HashMap<String, String> mMap;
    private DatabaseHelper DBHelper;
    private SQLiteDatabase db;

    private Context ctx;


    public CalendarProviderLocal(Context ctx){
        this.ctx = ctx;
        DBHelper = new DatabaseHelper(ctx);
        db = DBHelper.getWritableDatabase();
    }

    private static class DatabaseHelper extends SQLiteOpenHelper{
        DatabaseHelper(Context context) 
        {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

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


        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, 
                              int newVersion) 
        {
            Log.w("CalendarProvider", "Upgrading database from version " + oldVersion 
                  + " to "
                  + newVersion + ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS events");
            onCreate(db);
        }

        private void createTables(SQLiteDatabase db){
            db.execSQL("CREATE TABLE " + EVENTS_TABLE + "(" + ID + " integer primary key autoincrement, " +
                    EVENT + " TEXT, " + LOCATION + " TEXT, " + DESCRIPTION + " TEXT, "
                    + START + " INTEGER, "+ END + " INTEGER, " + START_DAY + " INTEGER, " + END_DAY + " INTEGER, " + COLOR +" INTEGER);");
        }
    }


    public void deleteEvent(Event event) {
        db.delete(EVENTS_TABLE, ID + " = ?",
                new String[] { String.valueOf(event.getEventId()) });

    }


    public long insert(ContentValues values) {
        long rowID = db.insert(EVENTS_TABLE,null, values);
        return rowID;
    }


    public void resetTable() {
        // Delete All Rows
        db.delete(EVENTS_TABLE, null, null);

    }

}

And use it like this

ContentValues values = new ContentValues();
values.put(CalendarProvider.COLOR, Event.COLOR_PURPLE);
//.. bla bla
// Uri uri = getContentResolver().insert(CalendarProvider.CONTENT_URI, values);
long rowID = calendarProviderLocal.insert(values);

Upvotes: 1

Related Questions