扩展日历视图 - 拒绝内容提供商权限需要签名

时间:2014-06-11 11:56:09

标签: android eclipse permissions calendar android-library

我正在尝试显示一个Android应用程序的每日视图。我决定使用库ExtendedCalendarView而我无法运行它。

我在做什么?

首先,我从github下载了库并导入到我的工作区。然后,我将de library导入到我的项目中。它似乎进口良好(绿色勾号)。

在我的MainActivity.java中我什么都不做:

public class MainActivity extends Activity {

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

}

在我的设计XML文件中,我有代码来显示xml。 (它与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,在AndroidManifest.xml中,我将ContentProvider声明为标记:

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

发生了什么事?

编译错误时,APP会在日志中显示此错误消息:

  

致命异常:AsyncTask#1 java.lang.RuntimeException:在java.util.concurrent.FutureTask $ Sync的android.os.AsyncTask $ 3.done(AsyncTask.java:299)上执行doInBackground()时发生错误。在java.util.concurrent.FutureTask的java.util.concurrent.FutureTask.setException(FutureTask.java:124)中的innerSetException(FutureTask.java:273)$ java.util.concurrent中的$ Sync.innerRun(FutureTask.java:307)在java.util的java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)的android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:230)的.FutureTask.run(FutureTask.java:137) .concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:569)       在java.lang.Thread.run(Thread.java:856)

     

引起:java.lang.SecurityException:Permission Denial:从ProcessRecord打开提供者com.tyczj.extendedcalendarview.CalendarProvider {42dc32a8 8394:com.jcasadella.testcalendar / u0a145}(pid = 8394,uid = 10145)需要签名或在Android.app.A.Ar响应android.app.Ap.Percel.readException(Parcel.java:1379)的android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:2561)上的android.os.Parcel.readException(Parcel.java:1425)处签名.ActivityThread.acquireProvider(ActivityThread.java:4347)位于android.content.ContentIvs上的android.contentImpl $ ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:1836)android.content.ContentUnstableProvider(ContentResolver.java:1129)。在com.tyczj.extendedcalendarview.Day $ GetEvents.doInBackground(Day.java:122)的com.tyczj.extendedcalendarview.Day上的android.content.ContentResolver.query(ContentResolver.java:336)查询(ContentResolver.java:378) $ GetEvents.doInBackgro und(Day.java:1)at android.os.AsyncTask $ 2.call(AsyncTask.java:287)at java.util.concurrent.FutureTask $ Sync.innerRun(FutureTask.java:305)

我的研究是什么?

我搜索了很多页面(stackoverflow)和其他人,但我发现没有人发现此错误。

这似乎是我忘了的一些许可。目前我从未使用过ContentProvider,也许问题就在这里......

我在Android开发人员的页面中阅读了documentation,现在我对该库为何使用ContentProvider感到困惑。

另外,我访问github中的issuses页面来搜索一些解决方案,但运气不好。

问题

我的问题是:

1)可以在不使用ContentProvider的情况下使用此库吗?将事件保存在sqlite或内存中......如果可以的话,请指出我正确的方向。

2)我写错误的原因是什么?有人能指出我可能的解决方案吗?

新闻(12/06/2014)

我在其他设备上测试了相同的APP,它正在运行!我不知道发生了什么:

Samusng Galaxy S3(Android 4.3) - &gt;完美运作

Samsung Tab 3(平板电脑Android 4.1) - &gt;许可拒绝错误。

这个APP将在平板电脑tab3中工作,android在4.1和4.3之间。 现在,我将在库github页面中打开并发布。如果我有更多结果,我会以答案格式发布。

提前致谢!感谢您每天在stackoverflow中的辛勤工作。

(对不起我的英文)

1 个答案:

答案 0 :(得分:1)

您可以编写自己的提供商 - 就像这样

(脏代码 - 但应该有用)

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

    }

}

并像这样使用

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