- remove an un-needed constant
- add a content provider helper that manages a table for storing sync state by account - add contact definitions to Contacts access the sync state
This commit is contained in:
175
api/current.xml
175
api/current.xml
@@ -17434,17 +17434,6 @@
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="PASSWORD_KEY"
|
||||
type="java.lang.String"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
value=""password""
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="USERDATA_KEY"
|
||||
type="java.lang.String"
|
||||
transient="false"
|
||||
@@ -114140,6 +114129,170 @@
|
||||
>
|
||||
</field>
|
||||
</class>
|
||||
<class name="SyncStateContract"
|
||||
extends="java.lang.Object"
|
||||
abstract="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<constructor name="SyncStateContract"
|
||||
type="android.provider.SyncStateContract"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</constructor>
|
||||
</class>
|
||||
<interface name="SyncStateContract.Columns"
|
||||
abstract="true"
|
||||
static="true"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<implements name="android.provider.BaseColumns">
|
||||
</implements>
|
||||
<field name="ACCOUNT_NAME"
|
||||
type="java.lang.String"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
value=""account_name""
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="ACCOUNT_TYPE"
|
||||
type="java.lang.String"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
value=""account_type""
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="DATA"
|
||||
type="java.lang.String"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
value=""data""
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
</interface>
|
||||
<class name="SyncStateContract.Constants"
|
||||
extends="java.lang.Object"
|
||||
abstract="false"
|
||||
static="true"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<implements name="android.provider.SyncStateContract.Columns">
|
||||
</implements>
|
||||
<constructor name="SyncStateContract.Constants"
|
||||
type="android.provider.SyncStateContract.Constants"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</constructor>
|
||||
<field name="CONTENT_DIRECTORY"
|
||||
type="java.lang.String"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
value=""syncstate""
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
</class>
|
||||
<class name="SyncStateContract.Helpers"
|
||||
extends="java.lang.Object"
|
||||
abstract="false"
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<constructor name="SyncStateContract.Helpers"
|
||||
type="android.provider.SyncStateContract.Helpers"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</constructor>
|
||||
<method name="get"
|
||||
return="byte[]"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="true"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="provider" type="android.content.ContentProviderClient">
|
||||
</parameter>
|
||||
<parameter name="uri" type="android.net.Uri">
|
||||
</parameter>
|
||||
<parameter name="account" type="android.accounts.Account">
|
||||
</parameter>
|
||||
<exception name="RemoteException" type="android.os.RemoteException">
|
||||
</exception>
|
||||
</method>
|
||||
<method name="newSetOperation"
|
||||
return="android.content.ContentProviderOperation"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="true"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="uri" type="android.net.Uri">
|
||||
</parameter>
|
||||
<parameter name="account" type="android.accounts.Account">
|
||||
</parameter>
|
||||
<parameter name="data" type="byte[]">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="set"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="true"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="provider" type="android.content.ContentProviderClient">
|
||||
</parameter>
|
||||
<parameter name="uri" type="android.net.Uri">
|
||||
</parameter>
|
||||
<parameter name="account" type="android.accounts.Account">
|
||||
</parameter>
|
||||
<parameter name="data" type="byte[]">
|
||||
</parameter>
|
||||
<exception name="RemoteException" type="android.os.RemoteException">
|
||||
</exception>
|
||||
</method>
|
||||
</class>
|
||||
<class name="UserDictionary"
|
||||
extends="java.lang.Object"
|
||||
abstract="false"
|
||||
|
||||
@@ -29,7 +29,6 @@ public class Constants {
|
||||
|
||||
public static final String ACCOUNTS_KEY = "accounts";
|
||||
public static final String AUTHENTICATOR_TYPES_KEY = "authenticator_types";
|
||||
public static final String PASSWORD_KEY = "password";
|
||||
public static final String USERDATA_KEY = "userdata";
|
||||
public static final String AUTHTOKEN_KEY = "authtoken";
|
||||
public static final String ACCOUNT_NAME_KEY = "authAccount";
|
||||
|
||||
@@ -16,13 +16,14 @@
|
||||
|
||||
package android.provider;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentProviderOperation;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
|
||||
import android.accounts.Account;
|
||||
import android.os.RemoteException;
|
||||
|
||||
/**
|
||||
* The contract between the contacts provider and applications. Contains definitions
|
||||
@@ -36,6 +37,48 @@ public final class ContactsContract {
|
||||
/** A content:// style uri to the authority for the contacts provider */
|
||||
public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
|
||||
|
||||
public interface SyncStateColumns extends SyncStateContract.Columns {
|
||||
}
|
||||
|
||||
public static final class SyncState {
|
||||
/**
|
||||
* This utility class cannot be instantiated
|
||||
*/
|
||||
private SyncState() {}
|
||||
|
||||
public static final String CONTENT_DIRECTORY =
|
||||
SyncStateContract.Constants.CONTENT_DIRECTORY;
|
||||
|
||||
/**
|
||||
* The content:// style URI for this table
|
||||
*/
|
||||
public static final Uri CONTENT_URI =
|
||||
Uri.withAppendedPath(AUTHORITY_URI, CONTENT_DIRECTORY);
|
||||
|
||||
/**
|
||||
* @see android.provider.SyncStateContract.Helpers#get
|
||||
*/
|
||||
public static byte[] get(ContentProviderClient provider, Account account)
|
||||
throws RemoteException {
|
||||
return SyncStateContract.Helpers.get(provider, CONTENT_URI, account);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see android.provider.SyncStateContract.Helpers#set
|
||||
*/
|
||||
public static void set(ContentProviderClient provider, Account account, byte[] data)
|
||||
throws RemoteException {
|
||||
SyncStateContract.Helpers.set(provider, CONTENT_URI, account, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see android.provider.SyncStateContract.Helpers#newSetOperation
|
||||
*/
|
||||
public static ContentProviderOperation newSetOperation(Account account, byte[] data) {
|
||||
return SyncStateContract.Helpers.newSetOperation(CONTENT_URI, account, data);
|
||||
}
|
||||
}
|
||||
|
||||
public interface AggregatesColumns {
|
||||
/**
|
||||
* The display name for the contact.
|
||||
|
||||
125
core/java/android/provider/SyncStateContract.java
Normal file
125
core/java/android/provider/SyncStateContract.java
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package android.provider;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentValues;
|
||||
import android.content.ContentProviderOperation;
|
||||
import android.accounts.Account;
|
||||
import android.database.Cursor;
|
||||
import android.os.RemoteException;
|
||||
|
||||
/**
|
||||
* The ContentProvider contract for associating data with ana data array account.
|
||||
* This may be used by providers that want to store this data in a standard way.
|
||||
*/
|
||||
public class SyncStateContract {
|
||||
public interface Columns extends BaseColumns {
|
||||
/**
|
||||
* A reference to the name of the account to which this data belongs
|
||||
* <P>Type: STRING</P>
|
||||
*/
|
||||
public static final String ACCOUNT_NAME = "account_name";
|
||||
|
||||
/**
|
||||
* A reference to the type of the account to which this data belongs
|
||||
* <P>Type: STRING</P>
|
||||
*/
|
||||
public static final String ACCOUNT_TYPE = "account_type";
|
||||
|
||||
/**
|
||||
* The sync data associated with this account.
|
||||
* <P>Type: NONE</P>
|
||||
*/
|
||||
public static final String DATA = "data";
|
||||
}
|
||||
|
||||
public static class Constants implements Columns {
|
||||
public static final String CONTENT_DIRECTORY = "syncstate";
|
||||
}
|
||||
|
||||
public static final class Helpers {
|
||||
private static final String[] DATA_PROJECTION = new String[]{Columns.DATA};
|
||||
private static final String SELECT_BY_ACCOUNT =
|
||||
Columns.ACCOUNT_NAME + "=? AND " + Columns.ACCOUNT_TYPE + "=?";
|
||||
|
||||
/**
|
||||
* Get the sync state that is associated with the account or null.
|
||||
* @param provider the {@link ContentProviderClient} that is to be used to communicate
|
||||
* with the {@link android.content.ContentProvider} that contains the sync state.
|
||||
* @param uri the uri of the sync state
|
||||
* @param account the {@link Account} whose sync state should be returned
|
||||
* @return the sync state or null if there is no sync state associated with the account
|
||||
* @throws RemoteException if there is a failure communicating with the remote
|
||||
* {@link android.content.ContentProvider}
|
||||
*/
|
||||
public static byte[] get(ContentProviderClient provider, Uri uri,
|
||||
Account account) throws RemoteException {
|
||||
Cursor c = provider.query(uri, DATA_PROJECTION, SELECT_BY_ACCOUNT,
|
||||
new String[]{account.mName, account.mType}, null);
|
||||
try {
|
||||
if (c.moveToNext()) {
|
||||
return c.getBlob(c.getColumnIndexOrThrow(Columns.DATA));
|
||||
}
|
||||
} finally {
|
||||
c.close();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the data array as the sync state for the given account.
|
||||
* @param provider the {@link ContentProviderClient} that is to be used to communicate
|
||||
* with the {@link android.content.ContentProvider} that contains the sync state.
|
||||
* @param uri the uri of the sync state
|
||||
* @param account the {@link Account} whose sync state should be set
|
||||
* @param data the byte[] that contains the sync state
|
||||
* @throws RemoteException if there is a failure communicating with the remote
|
||||
* {@link android.content.ContentProvider}
|
||||
*/
|
||||
public static void set(ContentProviderClient provider, Uri uri,
|
||||
Account account, byte[] data) throws RemoteException {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(Columns.DATA, data);
|
||||
values.put(Columns.ACCOUNT_NAME, account.mName);
|
||||
values.put(Columns.ACCOUNT_TYPE, account.mType);
|
||||
provider.insert(uri, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a ContentProviderOperation that assigns the data array as the
|
||||
* sync state for the given account.
|
||||
* @param uri the uri of the sync state
|
||||
* @param account the {@link Account} whose sync state should be set
|
||||
* @param data the byte[] that contains the sync state
|
||||
* @return the new ContentProviderOperation that assigns the data array as the
|
||||
* account's sync state
|
||||
*/
|
||||
public static ContentProviderOperation newSetOperation(Uri uri,
|
||||
Account account, byte[] data) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(Columns.DATA, data);
|
||||
return ContentProviderOperation
|
||||
.newInsert(uri)
|
||||
.withValue(Columns.ACCOUNT_NAME, account.mName)
|
||||
.withValue(Columns.ACCOUNT_TYPE, account.mType)
|
||||
.withValues(values)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.content;
|
||||
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
|
||||
import android.database.Cursor;
|
||||
import android.database.DatabaseUtils;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.accounts.Account;
|
||||
import android.content.ContentValues;
|
||||
import android.provider.SyncStateContract;
|
||||
|
||||
/**
|
||||
* Extends the schema of a ContentProvider to include the _sync_state table
|
||||
* and implements query/insert/update/delete to access that table using the
|
||||
* authority "syncstate". This can be used to store the sync state for a
|
||||
* set of accounts.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class SyncStateContentProviderHelper {
|
||||
private static final String SELECT_BY_ACCOUNT =
|
||||
SyncStateContract.Columns.ACCOUNT_NAME + "=? AND "
|
||||
+ SyncStateContract.Columns.ACCOUNT_TYPE + "=?";
|
||||
|
||||
private static final String SYNC_STATE_TABLE = "_sync_state";
|
||||
private static final String SYNC_STATE_META_TABLE = "_sync_state_metadata";
|
||||
private static final String SYNC_STATE_META_VERSION_COLUMN = "version";
|
||||
|
||||
private static long DB_VERSION = 1;
|
||||
|
||||
private static final String[] ACCOUNT_PROJECTION =
|
||||
new String[]{SyncStateContract.Columns.ACCOUNT_NAME,
|
||||
SyncStateContract.Columns.ACCOUNT_TYPE};
|
||||
|
||||
public static final String PATH = "syncstate";
|
||||
|
||||
public void createDatabase(SQLiteDatabase db) {
|
||||
db.execSQL("DROP TABLE IF EXISTS " + SYNC_STATE_TABLE);
|
||||
db.execSQL("CREATE TABLE " + SYNC_STATE_TABLE + " ("
|
||||
+ SyncStateContract.Columns._ID + " INTEGER PRIMARY KEY,"
|
||||
+ SyncStateContract.Columns.ACCOUNT_NAME + " TEXT NOT NULL,"
|
||||
+ SyncStateContract.Columns.ACCOUNT_TYPE + " TEXT NOT NULL,"
|
||||
+ SyncStateContract.Columns.DATA + " TEXT,"
|
||||
+ "UNIQUE(" + SyncStateContract.Columns.ACCOUNT_NAME + ", "
|
||||
+ SyncStateContract.Columns.ACCOUNT_TYPE + "));");
|
||||
|
||||
db.execSQL("DROP TABLE IF EXISTS " + SYNC_STATE_META_TABLE);
|
||||
db.execSQL("CREATE TABLE " + SYNC_STATE_META_TABLE + " ("
|
||||
+ SYNC_STATE_META_VERSION_COLUMN + " INTEGER);");
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(SYNC_STATE_META_VERSION_COLUMN, DB_VERSION);
|
||||
db.insert(SYNC_STATE_META_TABLE, SYNC_STATE_META_VERSION_COLUMN, values);
|
||||
}
|
||||
|
||||
public void onDatabaseOpened(SQLiteDatabase db) {
|
||||
long version = DatabaseUtils.longForQuery(db,
|
||||
"SELECT " + SYNC_STATE_META_VERSION_COLUMN + " FROM " + SYNC_STATE_META_TABLE,
|
||||
null);
|
||||
if (version != DB_VERSION) {
|
||||
createDatabase(db);
|
||||
}
|
||||
}
|
||||
|
||||
public Cursor query(SQLiteDatabase db, String[] projection,
|
||||
String selection, String[] selectionArgs, String sortOrder) {
|
||||
return db.query(SYNC_STATE_TABLE, projection, selection, selectionArgs,
|
||||
null, null, sortOrder);
|
||||
}
|
||||
|
||||
public long insert(SQLiteDatabase db, ContentValues values) {
|
||||
return db.replace(SYNC_STATE_TABLE, SyncStateContract.Columns.ACCOUNT_NAME, values);
|
||||
}
|
||||
|
||||
public int delete(SQLiteDatabase db, String userWhere, String[] whereArgs) {
|
||||
return db.delete(SYNC_STATE_TABLE, userWhere, whereArgs);
|
||||
}
|
||||
|
||||
public int update(SQLiteDatabase db, ContentValues values,
|
||||
String selection, String[] selectionArgs) {
|
||||
return db.update(SYNC_STATE_TABLE, values, selection, selectionArgs);
|
||||
}
|
||||
|
||||
public void onAccountsChanged(SQLiteDatabase db, Account[] accounts) {
|
||||
Cursor c = db.query(SYNC_STATE_TABLE, ACCOUNT_PROJECTION, null, null, null, null, null);
|
||||
try {
|
||||
while (c.moveToNext()) {
|
||||
final String accountName = c.getString(0);
|
||||
final String accountType = c.getString(1);
|
||||
Account account = new Account(accountName, accountType);
|
||||
if (!ArrayUtils.contains(accounts, account)) {
|
||||
db.delete(SYNC_STATE_TABLE, SELECT_BY_ACCOUNT,
|
||||
new String[]{accountName, accountType});
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
c.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user