Урок 101. Создаем свой ContentProvider
Добавлено: 06 авг 2012, 23:00
В этом уроке:
- создаем свой ContentProvider
Click here to read this article!
- создаем свой ContentProvider
Click here to read this article!
Добро пожаловать на форум сайта
http://forum.startandroid.ru/
Принципиально прав, но я бы сказал, что он дает подключиться к БД более чем одному процессу.rezak90 писал(а):короче я так понял провайдер даёт возможность подключаться к бд более чем одному приложению?
Тут скорей всего вопрос в правильном построении SQL запроса.rezak90 писал(а):Но не понял можно ли получить данные из бд которую не знаешь (например указать имя бд и вытянуть от тудого все таблицы с полями, заведомо не зная названия таблиц и столбцов)?
Лично у меня оно так и сделано в моем приложении, а ещё у меня запрещено другим приложениям, кроме моего, обращаться к моему контент провайдеру.rezak90 писал(а): И ещё, можно ли присабачить провайдер и программу в одно приложение, а не как создавать в уроке.
Когда с ними разберешься, то такое можно организовать.rezak90 писал(а): ап, ещё вычитал что с помощу провайдеров могут общаться между собой приложения, было бы интересно на это посмотреть.
getContentResolver() - это интерфейс, что ищет нужного контент провайдера по Uri.rezak90 писал(а):я так понял что getContentResolver() возвращает все провайдеры которые есть в Android'e. В общем как например вытащить все названия провайдеров которые функционируют на данный момент в системе, не зная их названия.
Код: Выделить всё
uMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uMatcher.addURI(AUTHORITY, TABLE_NAME, 1);
uMatcher.addURI(AUTHORITY, TABLE_NAME + "/#", 2);
Он тебе правильно возвращает 2.rezak90 писал(а):всё время выходит путанница с айди. Вот у меня такой адрес "ua.my.providers.Supershop/sneakers/" где sneakers - название таблицы. Если обращаюсь по адресу "ua.my.providers.Supershop/sneakers/33" то uMatcher.match(uri) возвращает мне цифру 2 всегда, мне почему то казалось что метод match возвращает то что стоит в конце или же после названия таблицы, он берёт от куда то двойку. Сам UriMatcher такой:Код: Выделить всё
uMatcher = new UriMatcher(UriMatcher.NO_MATCH); uMatcher.addURI(AUTHORITY, TABLE_NAME, 1); uMatcher.addURI(AUTHORITY, TABLE_NAME + "/#", 2);
Код: Выделить всё
// Вычисляем какая таблица нужна.
switch (uriMatcher.match(uri)){
case 1:
uTable = TABLE_NAME;
break;
case 2:
uTable = TABLE_NAME;
// Получаем id необходимой строки
uID = uri.getLastPathSegment();
break;
}
Верно, у меня ошибка в уроке. Вместоgh-gh писал(а):"У нас тут получилось, что имя таблицы в БД совпало с path в Uri. Это вовсе необязательно, они могут быть разными."
Если не ошибаюсь, если они будут разными, то в вашем примере будет IllegalArgumentException("Wrong URI: " + uri);
Код: Выделить всё
04-30 14:53:15.150: D/dalvikvm(2455): GC_CONCURRENT freed 56K, 7% free 2803K/3004K, paused 18ms+5ms, total 72ms
04-30 14:53:15.150: D/AndroidRuntime(2455): Shutting down VM
04-30 14:53:15.150: W/dalvikvm(2455): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
04-30 14:53:15.170: E/AndroidRuntime(2455): FATAL EXCEPTION: main
04-30 14:53:15.170: E/AndroidRuntime(2455): java.lang.RuntimeException: Unable to start activity ComponentInfo{ru.startandroid.develop.contprovclient/ru.startandroid.develop.contprovclient.MainActivity}: java.lang.SecurityException: Permission Denial: opening provider ru.startandroid.develop.contentprovider.MyContactProvider from ProcessRecord{41718cd8 2455:ru.startandroid.develop.contprovclient/u0a10047} (pid=2455, uid=10047) that is not exported from uid 10046
04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.ActivityThread.access$600(ActivityThread.java:141)
04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
04-30 14:53:15.170: E/AndroidRuntime(2455): at android.os.Handler.dispatchMessage(Handler.java:99)
04-30 14:53:15.170: E/AndroidRuntime(2455): at android.os.Looper.loop(Looper.java:137)
04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.ActivityThread.main(ActivityThread.java:5041)
04-30 14:53:15.170: E/AndroidRuntime(2455): at java.lang.reflect.Method.invokeNative(Native Method)
04-30 14:53:15.170: E/AndroidRuntime(2455): at java.lang.reflect.Method.invoke(Method.java:511)
04-30 14:53:15.170: E/AndroidRuntime(2455): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
04-30 14:53:15.170: E/AndroidRuntime(2455): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
04-30 14:53:15.170: E/AndroidRuntime(2455): at dalvik.system.NativeStart.main(Native Method)
04-30 14:53:15.170: E/AndroidRuntime(2455): Caused by: java.lang.SecurityException: Permission Denial: opening provider ru.startandroid.develop.contentprovider.MyContactProvider from ProcessRecord{41718cd8 2455:ru.startandroid.develop.contprovclient/u0a10047} (pid=2455, uid=10047) that is not exported from uid 10046
04-30 14:53:15.170: E/AndroidRuntime(2455): at android.os.Parcel.readException(Parcel.java:1425)
04-30 14:53:15.170: E/AndroidRuntime(2455): at android.os.Parcel.readException(Parcel.java:1379)
04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:2545)
04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.ActivityThread.acquireProvider(ActivityThread.java:4462)
04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2002)
04-30 14:53:15.170: E/AndroidRuntime(2455): at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1101)
04-30 14:53:15.170: E/AndroidRuntime(2455): at android.content.ContentResolver.query(ContentResolver.java:356)
04-30 14:53:15.170: E/AndroidRuntime(2455): at android.content.ContentResolver.query(ContentResolver.java:315)
04-30 14:53:15.170: E/AndroidRuntime(2455): at ru.startandroid.develop.contprovclient.MainActivity.onCreate(MainActivity.java:29)
04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.Activity.performCreate(Activity.java:5104)
04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
04-30 14:53:15.170: E/AndroidRuntime(2455): ... 11 more
У меня была похожая ошибка.Mill666 писал(а):Здравствуйте =)
вроде бы все делаю по уроку, однако программа при запуске сразу выдает ошибку =(Код: Выделить всё
04-30 14:53:15.150: D/dalvikvm(2455): GC_CONCURRENT freed 56K, 7% free 2803K/3004K, paused 18ms+5ms, total 72ms 04-30 14:53:15.150: D/AndroidRuntime(2455): Shutting down VM 04-30 14:53:15.150: W/dalvikvm(2455): threadid=1: thread exiting with uncaught exception (group=0x40a71930) 04-30 14:53:15.170: E/AndroidRuntime(2455): FATAL EXCEPTION: main 04-30 14:53:15.170: E/AndroidRuntime(2455): java.lang.RuntimeException: Unable to start activity ComponentInfo{ru.startandroid.develop.contprovclient/ru.startandroid.develop.contprovclient.MainActivity}: java.lang.SecurityException: Permission Denial: opening provider ru.startandroid.develop.contentprovider.MyContactProvider from ProcessRecord{41718cd8 2455:ru.startandroid.develop.contprovclient/u0a10047} (pid=2455, uid=10047) that is not exported from uid 10046 04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180) 04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230) 04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.ActivityThread.access$600(ActivityThread.java:141) 04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234) 04-30 14:53:15.170: E/AndroidRuntime(2455): at android.os.Handler.dispatchMessage(Handler.java:99) 04-30 14:53:15.170: E/AndroidRuntime(2455): at android.os.Looper.loop(Looper.java:137) 04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.ActivityThread.main(ActivityThread.java:5041) 04-30 14:53:15.170: E/AndroidRuntime(2455): at java.lang.reflect.Method.invokeNative(Native Method) 04-30 14:53:15.170: E/AndroidRuntime(2455): at java.lang.reflect.Method.invoke(Method.java:511) 04-30 14:53:15.170: E/AndroidRuntime(2455): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 04-30 14:53:15.170: E/AndroidRuntime(2455): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 04-30 14:53:15.170: E/AndroidRuntime(2455): at dalvik.system.NativeStart.main(Native Method) 04-30 14:53:15.170: E/AndroidRuntime(2455): Caused by: java.lang.SecurityException: Permission Denial: opening provider ru.startandroid.develop.contentprovider.MyContactProvider from ProcessRecord{41718cd8 2455:ru.startandroid.develop.contprovclient/u0a10047} (pid=2455, uid=10047) that is not exported from uid 10046 04-30 14:53:15.170: E/AndroidRuntime(2455): at android.os.Parcel.readException(Parcel.java:1425) 04-30 14:53:15.170: E/AndroidRuntime(2455): at android.os.Parcel.readException(Parcel.java:1379) 04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:2545) 04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.ActivityThread.acquireProvider(ActivityThread.java:4462) 04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2002) 04-30 14:53:15.170: E/AndroidRuntime(2455): at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1101) 04-30 14:53:15.170: E/AndroidRuntime(2455): at android.content.ContentResolver.query(ContentResolver.java:356) 04-30 14:53:15.170: E/AndroidRuntime(2455): at android.content.ContentResolver.query(ContentResolver.java:315) 04-30 14:53:15.170: E/AndroidRuntime(2455): at ru.startandroid.develop.contprovclient.MainActivity.onCreate(MainActivity.java:29) 04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.Activity.performCreate(Activity.java:5104) 04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080) 04-30 14:53:15.170: E/AndroidRuntime(2455): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144) 04-30 14:53:15.170: E/AndroidRuntime(2455): ... 11 more
В AndroidManifest.xml указываем exported = false. При этом провайдер должен быть объявлен в самом приложении, а не как в уроке отдельно.Ant писал(а):и ещё один вопрос: если кто-то сможет разобраться с запросами к моему провайдеру, то без проблем сможет курочить мою БД своим приложением? как от этого защищаться?
Код: Выделить всё
<provider
android:name="[i]provider_name[/i]"
android:authorities="[i]provider_authorities[/i]"
android:exported="false">
</provider>
Значение свойства exported определяет, доступен ли provider из других приложений.android:exported
Whether the content provider is available for other applications to use:
true: The provider is available to other applications. Any application can use the provider's content URI to access it, subject to the permissions specified for the provider.
false: The provider is not available to other applications. Set android:exported="false" to limit access to the provider to your applications. Only applications that have the same user ID (UID) as the provider will have access to it.
The default value is "true" for applications that set either android:minSdkVersion or android:targetSdkVersion to "16" or lower. For applications that set either of these attributes to "17" or higher, the default is "false".
You can set android:exported="false" and still limit access to your provider by setting permissions with the permission attribute.