1page.title=Creating a Stub Content Provider
2
3trainingnavtop=true
4@jd:body
5
6
7<div id="tb-wrapper">
8<div id="tb">
9
10<h2>This lesson teaches you to</h2>
11<ol>
12    <li>
13        <a href="#CreateProvider">Add a Stub Content Provider</a>
14    </li>
15    <li>
16        <a href="#DeclareProvider">Declare the Provider in the Manifest</a>
17    </li>
18</ol>
19
20<h2>You should also read</h2>
21<ul>
22    <li>
23        <a href="{@docRoot}guide/topics/providers/content-provider-basics.html"
24        >Content Provider Basics</a>
25    </li>
26</ul>
27
28<h2>Try it out</h2>
29
30<div class="download-box">
31 <a href="http://developer.android.com/shareables/training/BasicSyncAdapter.zip" class="button">Download the sample</a>
32 <p class="filename">BasicSyncAdapter.zip</p>
33</div>
34
35</div>
36</div>
37<p>
38    The sync adapter framework is designed to work with device data managed by the flexible and
39    highly secure content provider framework. For this reason, the sync adapter framework expects
40    that an app that uses the framework has already defined a content provider for its local data.
41    If the sync adapter framework tries to run your sync adapter, and your app doesn't have a
42    content provider, your sync adapter crashes.
43</p>
44<p>
45    If you're developing a new app that transfers data from a server to the device, you should
46    strongly consider storing the local data in a content provider. Besides their importance for
47    sync adapters, content providers offer a variety of security benefits and are specifically
48    designed to handle data storage on Android systems. To learn more about creating a content
49    provider, see <a href="{@docRoot}guide/topics/providers/content-provider-creating.html"
50    >Creating a Content Provider</a>.
51</p>
52<p>
53    However, if you're already storing local data in another form, you can still use a sync
54    adapter to handle data transfer. To satisfy the sync adapter framework requirement for a
55    content provider, add a stub content provider to your app. A stub provider implements the
56    content provider class, but all of its required methods return {@code null} or {@code 0}. If you
57    add a stub provider, you can then use a sync adapter to transfer data from any storage
58    mechanism you choose.
59</p>
60<p>
61    If you already have a content provider in your app, you don't need a stub content provider.
62    In that case, you can skip this lesson and proceed to the lesson
63    <a href="creating-sync-adapter.html">Creating a Sync Adapter</a>. If you don't yet have a
64    content provider, this lesson shows you how to add a stub content provider that allows you to
65    plug your sync adapter into the framework.
66</p>
67<h2 id="CreateProvider">Add a Stub Content Provider</h2>
68<p>
69    To create a stub content provider for your app, extend the class
70    {@link android.content.ContentProvider} and stub out its required methods. The following
71    snippet shows you how to create the stub provider:
72</p>
73<pre>
74/*
75 * Define an implementation of ContentProvider that stubs out
76 * all methods
77 */
78public class StubProvider extends ContentProvider {
79    /*
80     * Always return true, indicating that the
81     * provider loaded correctly.
82     */
83    &#64;Override
84    public boolean onCreate() {
85        return true;
86    }
87    /*
88     * Return no type for MIME type
89     */
90    &#64;Override
91    public String getType(Uri uri) {
92        return null;
93    }
94    /*
95     * query() always returns no results
96     *
97     */
98    &#64;Override
99    public Cursor query(
100            Uri uri,
101            String[] projection,
102            String selection,
103            String[] selectionArgs,
104            String sortOrder) {
105        return null;
106    }
107    /*
108     * insert() always returns null (no URI)
109     */
110    &#64;Override
111    public Uri insert(Uri uri, ContentValues values) {
112        return null;
113    }
114    /*
115     * delete() always returns "no rows affected" (0)
116     */
117    &#64;Override
118    public int delete(Uri uri, String selection, String[] selectionArgs) {
119        return 0;
120    }
121    /*
122     * update() always returns "no rows affected" (0)
123     */
124    public int update(
125            Uri uri,
126            ContentValues values,
127            String selection,
128            String[] selectionArgs) {
129        return 0;
130    }
131}
132</pre>
133<h2 id="DeclareProvider">Declare the Provider in the Manifest</h2>
134<p>
135    The sync adapter framework verifies that your app has a content provider by checking that your
136    app has declared a provider in its app manifest. To declare the stub provider in the
137    manifest, add a <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"
138    >&lt;provider&gt;</a></code> element with  the following attributes:
139</p>
140<dl>
141    <dt>
142        <code>android:name="com.example.android.datasync.provider.StubProvider"</code>
143    </dt>
144    <dd>
145        Specifies the fully-qualified name of the class that implements the stub content provider.
146    </dd>
147    <dt>
148        <code>android:authorities="com.example.android.datasync.provider"</code>
149    </dt>
150    <dd>
151        A URI authority that identifies the stub content provider. Make this value your app's
152        package name with the string ".provider" appended to it. Even though you're declaring your
153        stub provider to the system, nothing tries to access the provider itself.
154   </dd>
155    <dt>
156        <code>android:exported="false"</code>
157    </dt>
158    <dd>
159        Determines whether other apps can access the content provider. For your stub content
160        provider, set the value to {@code false}, since there's no need to allow other apps to see
161        the provider. This value doesn't affect the interaction between the sync adapter framework
162        and the content provider.
163    </dd>
164    <dt>
165        <code>android:syncable="true"</code>
166    </dt>
167    <dd>
168        Sets a flag that indicates that the provider is syncable. If you set this flag to
169        {@code true}, you don't have to call {@link android.content.ContentResolver#setIsSyncable
170        setIsSyncable()} in your code. The flag allows the sync adapter framework to make data
171        transfers with the content provider, but transfers only occur if you do them explicitly.
172    </dd>
173</dl>
174<p>
175    The following snippet shows you how to add the
176    <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"
177    >&lt;provider&gt;</a></code> element to the app manifest:
178</p>
179<pre>
180&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
181    package="com.example.android.network.sync.BasicSyncAdapter"
182    android:versionCode="1"
183    android:versionName="1.0" &gt;
184    &lt;application
185        android:allowBackup="true"
186        android:icon="&#64;drawable/ic_launcher"
187        android:label="&#64;string/app_name"
188        android:theme="&#64;style/AppTheme" &gt;
189    ...
190    &lt;provider
191        android:name="com.example.android.datasync.provider.StubProvider"
192        android:authorities="com.example.android.datasync.provider"
193        android:exported="false"
194        android:syncable="true"/&gt;
195    ...
196    &lt;/application&gt;
197&lt;/manifest&gt;
198</pre>
199<p>
200    Now that you have created the dependencies required by the sync adapter framework, you can
201    create the component that encapsulates your data transfer code. This component is called a
202    sync adapter. The next lesson shows you how to add this component to your app.
203</p>
204