Bonjour à tous,
Je commence à desespérer, après avoir suivi le tuto d'android mon async adapter ne fonctionne pas, je comprend d'aileurs mal ou sont les liens entre les différents élément (a part l'authority mais je trouve ca bien mince). Je met mon code si dessous, une idée du problème ?
ContentProvider
Authenticator service :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143 public class SienContentProvider extends android.content.ContentProvider{ private static final String TAG = "SIEN_CONTENTPROVIDER"; private static final String DB_NAME = "SIEN_API_DB.db"; private static final int DB_VERSION = 2; private static final String PRIMARY_TABLE_NAME = "sienApi"; public static final String AUTHORITY = "com.sien.apisienstore"; //URI MATCHER private static final UriMatcher uriMatcher; private static HashMap<String, String> constantProjectionMap; private static final int CONSTANTS = 1; private static final int CONSTANTS_ID = 2; static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, PRIMARY_TABLE_NAME, CONSTANTS); uriMatcher.addURI(AUTHORITY, PRIMARY_TABLE_NAME + "/#", CONSTANTS_ID); constantProjectionMap = new HashMap<String, String>(); constantProjectionMap.put(ConstantsModel.ApiConstants.ID, ConstantsModel.ApiConstants.ID); constantProjectionMap.put(ConstantsModel.ApiConstants.TITLE, ConstantsModel.ApiConstants.TITLE); constantProjectionMap.put(ConstantsModel.ApiConstants.VALUE, ConstantsModel.ApiConstants.VALUE); } private static class DatabaseHelper extends SQLiteOpenHelper{ DatabaseHelper(Context ctx){ super(ctx, DB_NAME, null, DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE " + PRIMARY_TABLE_NAME + " (" + ConstantsModel.ApiConstants.ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + ConstantsModel.ApiConstants.TITLE + " VARCHAR(255)," + ConstantsModel.ApiConstants.VALUE + " LONGTEXT" + ");"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data"); db.execSQL("DROP TABLE IF EXISTS " + PRIMARY_TABLE_NAME); onCreate(db); } } DatabaseHelper dbHelper; @Override public int delete(Uri uri, String where, String[] whereArgs) { SQLiteDatabase db = dbHelper.getWritableDatabase(); switch (uriMatcher.match(uri)) { case CONSTANTS: break; case CONSTANTS_ID: where = where + "_id = " + uri.getLastPathSegment(); break; default: throw new IllegalArgumentException("Unknown URI " + uri); } int count = db.delete(PRIMARY_TABLE_NAME, where, whereArgs); getContext().getContentResolver().notifyChange(uri, null); return count; } @Override public String getType(Uri uri) { switch (uriMatcher.match(uri)) { case CONSTANTS: return ConstantsModel.ApiConstants.CONTENT_TYPE; default: throw new IllegalArgumentException("Unknown URI " + uri); } } @Override public Uri insert(Uri uri, ContentValues initialValues) { if (uriMatcher.match(uri) != CONSTANTS) { throw new IllegalArgumentException("Unknown URI " + uri); } ContentValues values; if (initialValues != null) { values = new ContentValues(initialValues); } else { values = new ContentValues(); } SQLiteDatabase db = dbHelper.getWritableDatabase(); long rowId = db.insert(PRIMARY_TABLE_NAME, ConstantsModel.ApiConstants.VALUE, values); if (rowId > 0) { Uri noteUri = ContentUris.withAppendedId(ConstantsModel.ApiConstants.CONTENT_URI, rowId); getContext().getContentResolver().notifyChange(noteUri, null); return noteUri; } throw new android.database.SQLException("Failed to insert row into " + uri); } @Override public boolean onCreate() { dbHelper = new DatabaseHelper(getContext()); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); qb.setTables(PRIMARY_TABLE_NAME); qb.setProjectionMap(constantProjectionMap); switch (uriMatcher.match(uri)) { case CONSTANTS: break; case CONSTANTS_ID: selection = selection + "_id = " + uri.getLastPathSegment(); break; default: throw new IllegalArgumentException("Unknown URI " + uri); } SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder); c.setNotificationUri(getContext().getContentResolver(), uri); return c; } @Override public int update(Uri uri, ContentValues values, String where, String[] whereArgs) { SQLiteDatabase db = dbHelper.getWritableDatabase(); int count; switch (uriMatcher.match(uri)) { case CONSTANTS: count = db.update(PRIMARY_TABLE_NAME, values, where, whereArgs); break; default: throw new IllegalArgumentException("Unknown URI " + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } }
SyncAdapter service
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 public class DummyAuthenticatorService extends Service { private DummyAuthenticator authenticator; @Override public void onCreate() { super.onCreate(); authenticator = new DummyAuthenticator(this); } @Override public IBinder onBind(Intent intent) { return authenticator.getIBinder(); } private static class DummyAuthenticator extends AbstractAccountAuthenticator { public DummyAuthenticator(Context ctx) { super(ctx); } @Override public Bundle editProperties(AccountAuthenticatorResponse accountAuthenticatorResponse, String s) { throw new UnsupportedOperationException(); } @Override public Bundle addAccount(AccountAuthenticatorResponse accountAuthenticatorResponse, String s, String s2, String[] strings, Bundle bundle) throws NetworkErrorException { return null; } @Override public Bundle confirmCredentials(AccountAuthenticatorResponse accountAuthenticatorResponse, Account account, Bundle bundle) throws NetworkErrorException { return null; } @Override public Bundle getAuthToken(AccountAuthenticatorResponse accountAuthenticatorResponse, Account account, String s, Bundle bundle) throws NetworkErrorException { throw new UnsupportedOperationException(); } @Override public String getAuthTokenLabel(String s) { throw new UnsupportedOperationException(); } @Override public Bundle updateCredentials(AccountAuthenticatorResponse accountAuthenticatorResponse, Account account, String s, Bundle bundle) throws NetworkErrorException { throw new UnsupportedOperationException(); } @Override public Bundle hasFeatures(AccountAuthenticatorResponse accountAuthenticatorResponse, Account account, String[] strings) throws NetworkErrorException { throw new UnsupportedOperationException(); } } }
Authenticator XML :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 public class SyncBoundService extends Service { private static SyncAdapter syncAdapter = null; private static final Object syncAdapterLock = new Object(); // Thread safe @Override public void onCreate() { super.onCreate(); Log.v("APPSIEN", "ONCREATESYNC"); //synchronized (syncAdapterLock){ if(syncAdapter == null)syncAdapter = new SyncAdapter(getApplicationContext(), true); //} } @Override public IBinder onBind(Intent intent) { return syncAdapter.getSyncAdapterBinder(); } private static class SyncAdapter extends AbstractThreadedSyncAdapter { ContentResolver contentResolver; public SyncAdapter(Context ctx, boolean autoInit) { super(ctx, autoInit); contentResolver = ctx.getContentResolver(); } public SyncAdapter(Context ctx, boolean autoInit, boolean allowParallelSyncs) { super(ctx, autoInit, allowParallelSyncs); contentResolver = ctx.getContentResolver(); } @Override public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient contentProviderClient, SyncResult syncResult) { // Data transfer code here : // - Connect to server // - Download SIEN API infos // - Sync with content provider (using GSON ??) // - Handling data conflicts and errors // - Clean (close connections, clean tmp files etc ...) Log.v("APPSIEN", "ONPERFORMSYNC"); } } }
SyncAdpater XML :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 <?xml version="1.0" encoding="utf-8"?> <account-authenticator xmlns:android="http://schemas.android.com/apk/res/android" android:accountType="urlauncher.com" android:icon="@drawable/ic_allapps" android:smallIcon="@drawable/ic_allapps" android:label="@string/app_name"> </account-authenticator>
Code correspondant dans le manifest :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 <?xml version="1.0" encoding="utf-8"?> <sync-adapter xmlns:android="http://schemas.android.com/apk/res/android" android:contentAuthority="com.sien.apisienstore" android:accountType="urlauncher.com" android:userVisible="false" android:supportsUploading="false" android:allowParallelSyncs="false" android:isAlwaysSyncable="true"> </sync-adapter>
Code de lancement dans l'activity :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 <!-- API SIEN CONSTANTS --> <provider android:authorities="com.sien.apisienstore" android:name="com.sien.apisienstore.SienContentProvider" android:syncable="true"/> <service android:name="com.sien.apisienstore.SyncBoundService" android:exported="true" android:process=":synca"> <intent-filter> <action android:name="android.content.SyncAdapter"/> </intent-filter> <meta-data android:name="android.content.SyncAdapter" android:resource="@xml/apisyncadapter" /> </service> <service android:name="com.sien.apisienstore.DummyAuthenticatorService"> <intent-filter> <action android:name="android.accounts.AccountAuthenticator"/> </intent-filter> <meta-data android:name="android.accounts.AccountAuthenticator" android:resource="@xml/authenticator" /> </service> <activity android:name="com.sien.apisienstore.APISienStoreActivity"/> <!--********************-->
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 Account newAccount = new Account("dummyAccount", "urlauncher.com"); AccountManager accountManager = (AccountManager) getSystemService(ACCOUNT_SERVICE); if(accountManager.addAccountExplicitly(newAccount, null, null)){ getContentResolver().setIsSyncable(newAccount, SienContentProvider.AUTHORITY, 1); }else{ // How could it be possible that a false account fail ? } getContentResolver().setSyncAutomatically(newAccount, SienContentProvider.AUTHORITY, true); getContentResolver().addPeriodicSync(newAccount, SienContentProvider.AUTHORITY, Bundle.EMPTY, 15); //getContentResolver().requestSync(newAccount, SienContentProvider.AUTHORITY, Bundle.EMPTY);
Partager