Commit 268396d3 authored by Alan McNatty's avatar Alan McNatty
Browse files

A large commit that moves the artefactdatasqlhelper 'stuff' into a content...

A large commit that moves the artefactdatasqlhelper 'stuff' into a content provider so we can set upa content observer and listen for content changes. This is significant in the cleanliness of the artefacts .. an uninstall and reinstall will be required.

Also split the Utils class into Sync and Account Util classes so it's a bit more focused (easier to know where to look etc).
parent 0c1048db
...@@ -94,8 +94,14 @@ ...@@ -94,8 +94,14 @@
<meta-data android:name="android.content.SyncAdapter" <meta-data android:name="android.content.SyncAdapter"
android:resource="@xml/syncadapter" /> android:resource="@xml/syncadapter" />
</service> </service>
<provider android:name="nz.net.catalyst.MaharaDroid.provider.MaharaProvider" <provider android:name=".provider.SyncContentProvider"
android:authorities="nz.net.catalyst.MaharaDroid" android:authorities="nz.net.catalyst.MaharaDroid.Sync"
android:label="MaharaDroid"
android:syncable="true"
android:enabled="true">
</provider>
<provider android:name=".provider.ArtefactContentProvider"
android:authorities="nz.net.catalyst.MaharaDroid.Artefact"
android:label="MaharaDroid" android:label="MaharaDroid"
android:syncable="true" android:syncable="true"
android:enabled="true"> android:enabled="true">
......
...@@ -50,12 +50,6 @@ ...@@ -50,12 +50,6 @@
style="@android:style/TextAppearance.Small"> style="@android:style/TextAppearance.Small">
</TextView> </TextView>
</LinearLayout> </LinearLayout>
<!--
<ImageView android:id="@+id/UploadArtefact"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ImageView>
-->
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ArtefactTitleLayout" android:id="@+id/ArtefactTitleLayout"
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
android:layout_below="@+id/artefacts_banner_text" android:layout_below="@+id/artefacts_banner_text"
/> />
<TextView android:text="@string/artefacts_help" <TextView android:id="@+id/artefacts_help"
android:layout_margin="5dp" android:layout_margin="5dp"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:singleLine="false" android:singleLine="false"
......
...@@ -4,8 +4,16 @@ ...@@ -4,8 +4,16 @@
<string name="artefacts_banner_text">Open source ePortfolios</string> <string name="artefacts_banner_text">Open source ePortfolios</string>
<string name="artefacts_banner_text2">[mah-har-rah;verb]: to think, thinking, thought</string> <string name="artefacts_banner_text2">[mah-har-rah;verb]: to think, thinking, thought</string>
<string name="artefacts_help"> <string name="artefacts_help">&lt;p&gt;Thanks for using MaharaDroid!&lt;/p&gt;
&lt;p&gt;To get started touch Menu -&gt; Preferences.&lt;/p&gt;
&lt;p&gt;
Enter your Mahara username on set the initial token. At the same time visit Mahara (Settings) and set the same token value and click update.
Back in MaharaDroid touch your back button, and an authentication attempt will be made.
&lt;/p&gt;
&lt;p&gt;
Once authenticated check the Menu for options on writing Journal posts and uploading files.
Alternatively when taking photos, videos or recording audio look for options to \'share\' these files with MaharaDroid.
&lt;/p&gt;
</string> </string>
<string name="artefacts_no_saved_artefacts">Nothing saved at present.</string> <string name="artefacts_no_saved_artefacts">Nothing saved at present.</string>
......
<!-- API Version 7 requires the accountType attribute to be hard-coded as a string --> <!-- API Version 7 requires the accountType attribute to be hard-coded as a string -->
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android" <sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
android:contentAuthority="nz.net.catalyst.MaharaDroid" android:contentAuthority="nz.net.catalyst.MaharaDroid.Sync"
android:accountType="nz.net.catalyst.MaharaDroid.account" android:accountType="nz.net.catalyst.MaharaDroid.account"
android:supportsUploading="true" android:supportsUploading="true"
android:userVisible="true" android:userVisible="true"
......
...@@ -52,12 +52,16 @@ public class GlobalResources { ...@@ -52,12 +52,16 @@ public class GlobalResources {
public static final String ACCOUNT_TYPE = "nz.net.catalyst.MaharaDroid.account"; public static final String ACCOUNT_TYPE = "nz.net.catalyst.MaharaDroid.account";
public static final String AUTHTOKEN_TYPE = "nz.net.catalyst.MaharaDroid.account"; public static final String AUTHTOKEN_TYPE = "nz.net.catalyst.MaharaDroid.account";
public static final String CONTENT_URL = "nz.net.catalyst.MaharaDroid";
public static final String SYNC_CONTENT_URL = "nz.net.catalyst.MaharaDroid.Sync";
public static final String ARTEFACT_CONTENT_URL = "nz.net.catalyst.MaharaDroid.Artefact";
public static final String SYNC_AUTHORITY = "nz.net.catalyst.MaharaDroid"; public static final String SYNC_AUTHORITY = "nz.net.catalyst.MaharaDroid";
public static final String EXTRAS_SYNC_IS_PERIODIC = "nz.net.catalyst.MaharaDroid.periodic"; public static final String EXTRAS_SYNC_IS_PERIODIC = "nz.net.catalyst.MaharaDroid.periodic";
public static final String BROADCAST_ACTION = "nz.net.catalyst.MaharaDroid.UPLOAD_COMPLETED";
public static final String[] CONTENT_TABLES = new String[] { "tag", "blog", "folder" }; public static final String[] SYNC_CONTENT_TABLES = new String[] { "tag", "blog", "folder" };
public static final String[] CONTENT_FIELDS = new String[] { "ID", "VALUE" }; public static final String[] SYNC_CONTENT_FIELDS = new String[] { "ID", "VALUE" };
public static final Map<Integer, String> NOTIFICATIONS; public static final Map<Integer, String> NOTIFICATIONS;
static { static {
...@@ -76,5 +80,4 @@ public class GlobalResources { ...@@ -76,5 +80,4 @@ public class GlobalResources {
public static final int REQ_RECORD_AUDIO_RETURN = 2; public static final int REQ_RECORD_AUDIO_RETURN = 2;
public static final int REGISTRATION_TIMEOUT = 30 * 1000; // ms public static final int REGISTRATION_TIMEOUT = 30 * 1000; // ms
} }
\ No newline at end of file
...@@ -21,40 +21,26 @@ ...@@ -21,40 +21,26 @@
package nz.net.catalyst.MaharaDroid; package nz.net.catalyst.MaharaDroid;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import nz.net.catalyst.MaharaDroid.R; import nz.net.catalyst.MaharaDroid.R;
import nz.net.catalyst.MaharaDroid.ui.ArtefactExpandableListAdapterActivity; import nz.net.catalyst.MaharaDroid.ui.ArtefactExpandableListAdapterActivity;
import nz.net.catalyst.MaharaDroid.ui.about.AboutActivity;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Notification; import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.ContentProviderClient;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.PeriodicSync;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.database.Cursor; import android.database.Cursor;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.NetworkInfo; import android.net.NetworkInfo;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.provider.SyncStateContract.Constants;
import android.util.Log; import android.util.Log;
public class Utils { public class Utils {
...@@ -133,47 +119,6 @@ public class Utils { ...@@ -133,47 +119,6 @@ public class Utils {
return upload_url; return upload_url;
} }
public static String getSyncURLPref(Context context) {
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
String sync_url = mPrefs.getString(context.getResources().getString(R.string.pref_sync_url_key),
context.getResources().getString(R.string.pref_sync_url_default)).trim();
// If the part overrides the whole - just go with the part.
if ( sync_url.startsWith("http://") ) {
if ( DEBUG ) Log.d(TAG, "setting sync url to '" + sync_url + "'");
return sync_url;
}
String base_url = mPrefs.getString(context.getResources().getString(R.string.pref_base_url_key),
context.getResources().getString(R.string.pref_base_url_default)).trim().toLowerCase();
if ( ! base_url.startsWith("http") )
base_url = "http://" + base_url;
if ( ! base_url.endsWith("/") && ! sync_url.startsWith("/") )
base_url = base_url + "/";
// multiple joining '//' are fine
sync_url = base_url + sync_url;
if ( DEBUG ) Log.d(TAG, "setting sync url to '" + sync_url + "'");
return sync_url;
}
public static String getSyncNotificationsPref(Context context) {
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
String notificationString = "";
Iterator<Entry<Integer, String>> it = GlobalResources.NOTIFICATIONS.entrySet().iterator();
while (it.hasNext()) {
Entry<Integer, String> not = it.next();
if ( mPrefs.getBoolean(context.getResources().getString(not.getKey()), true) ) {
notificationString += ( notificationString.length() > 0 ) ? "," : "";
notificationString += not.getValue();
}
}
if ( DEBUG ) Log.d(TAG, "setting notifications string to '" + notificationString + "'");
return ( notificationString == "" ) ? null : notificationString;
}
public static String updateTokenFromResult(JSONObject json, Context context) { public static String updateTokenFromResult(JSONObject json, Context context) {
String newToken = null; String newToken = null;
if (json == null || json.has("fail")) { if (json == null || json.has("fail")) {
...@@ -241,94 +186,7 @@ public class Utils { ...@@ -241,94 +186,7 @@ public class Utils {
mNM.cancel(id); mNM.cancel(id);
} }
public static long processSyncResults(JSONObject result, ContentProviderClient myProvider, Context context, String sync_key) {
if ( myProvider == null ) {
Uri uri = Uri.parse("content://" + GlobalResources.CONTENT_URL);
myProvider = context.getContentResolver().acquireContentProviderClient(uri);
}
// TODO Auto-generated method stub
long numUpdates = 0;
try {
JSONObject syncObj = result.getJSONObject("sync");
//Log.i(TAG, syncObj.toString());
if ( syncObj.has("activity") && syncObj.optJSONArray("activity") != null ) {
JSONArray notArr = syncObj.getJSONArray("activity");
for (int i=0; i<notArr.length(); i++) {
Utils.showNotification(Integer.parseInt(notArr.getJSONObject(i).getString("id")),
notArr.getJSONObject(i).getString("subject"), notArr.getJSONObject(i).getString("message"),
null, context);
numUpdates++;
}
}
if ( syncObj.has("tags") && syncObj.optJSONArray("tags") != null ) {
long newItems = updateListPreferenceFromJSON(myProvider, syncObj.getJSONArray("tags"), "tag");
numUpdates += newItems;
}
if ( syncObj.has("blogs") && syncObj.optJSONArray("blogs") != null ) {
long newItems = updateListPreferenceFromJSON(myProvider, syncObj.getJSONArray("blogs"), "blog");
numUpdates += newItems;
}
if ( syncObj.has("folders") && syncObj.optJSONArray("folders") != null ) {
long newItems = updateListPreferenceFromJSON(myProvider, syncObj.getJSONArray("folders"), "folder");
numUpdates += newItems;
}
if ( syncObj.has("time") ) {
// Save last sync time
String last_sync = syncObj.getString("time");
Log.v(TAG, "saving sync time as: " + last_sync);
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
// We save current time in seconds since 1970 in UTC!!
// TODO fix this - get the sync api to respond with the current server time which we can save here
// i.e. a syncObj.has("time") piece containing the epoch to store.
mPrefs.edit()
.putString(sync_key, last_sync)
.commit()
;
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return numUpdates;
}
private static long updateListPreferenceFromJSON(ContentProviderClient myProvider, JSONArray jsonArray, String fieldName) throws JSONException, RemoteException {
int items = jsonArray.length();
ContentValues[] cv = new ContentValues[items];
Uri uri = Uri.parse("content://" + GlobalResources.CONTENT_URL + "/" + fieldName);
Log.i(TAG, jsonArray.toString());
for (int i=0; i<items; i++) {
String value = jsonArray.getJSONObject(i).getString(fieldName);
String id = jsonArray.getJSONObject(i).getString("id");
Log.v(TAG, "saving " + fieldName + " [ id: " + id + ", value: " + value + "]");
// test provider query
myProvider.query(uri, null, null, null, null);
if ( cv[i] == null )
cv[i] = new ContentValues();
cv[i].put("ID", id);
cv[i].put("VALUE", value);
//}
}
// TODO add a 'last_seen' column and delete any last_seen < this_sync
myProvider.delete(uri, null, null); // delete them all
myProvider.bulkInsert(uri, cv);
return items;
}
public static Intent makeCameraIntent(Context context) { public static Intent makeCameraIntent(Context context) {
//define the file-name to save photo taken by Camera activity //define the file-name to save photo taken by Camera activity
...@@ -354,108 +212,6 @@ public class Utils { ...@@ -354,108 +212,6 @@ public class Utils {
return i; return i;
} }
public static void setPeriodicSync(Account account, Context context) {
if ( account == null )
return;
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
Long periodic_sync = Long.valueOf(mPrefs.getString(context.getResources().getString(R.string.pref_sync_periodic_key), "0"));
if ( periodic_sync == null || periodic_sync <= 0 ) {
// Note - should only ever have 1
List<PeriodicSync> ps = ContentResolver.getPeriodicSyncs(account, GlobalResources.ACCOUNT_TYPE);
while ( ps != null && ! ps.isEmpty() ) {
if ( periodic_sync == 0 || ps.get(0).period != periodic_sync ) {
ContentResolver.removePeriodicSync(account, GlobalResources.ACCOUNT_TYPE, ps.get(0).extras);
if ( VERBOSE ) Log.v(TAG, "setPeriodicSync removing periodic sync '" + ps.get(0).period + "'");
}
ps.remove(0);
}
return;
}
periodic_sync = periodic_sync * 60; // convert to seconds
if ( DEBUG ) Log.v(TAG, "setPeriodicSync of '" + periodic_sync + "' seconds");
final Bundle bundle = new Bundle();
bundle.putBoolean( ContentResolver.SYNC_EXTRAS_UPLOAD, true );
ContentResolver.addPeriodicSync(account, GlobalResources.SYNC_AUTHORITY, bundle, periodic_sync);
}
public static Account getAccount(Context context) {
AccountManager mAccountManager = AccountManager.get(context);
Account account = null;
// if ( periodic_sync != null && periodic_sync > 0 ) {
//
// TODO replicated from AuthenticatorActivity
Account[] mAccounts = mAccountManager.getAccountsByType(GlobalResources.ACCOUNT_TYPE);
if ( mAccounts.length > 0 ) {
// Just pick the first one .. support multiple accounts can come later.
account = mAccounts[0];
}
return account;
}
public static void deleteAccount(Context context) {
AccountManager mAccountManager = AccountManager.get(context);
Account[] mAccounts = mAccountManager.getAccountsByType(GlobalResources.ACCOUNT_TYPE);
for ( int i = 0; i < mAccounts.length; i++ ) {
mAccountManager.removeAccount(mAccounts[i], null, null);
}
}
public static String[][] getJournals(String nullitem, Context context) {
return getValues("blog", nullitem, context);
}
public static String[][] getTags(String nullitem, Context context) {
return getValues("tag", nullitem, context);
}
public static String[][] getFolders(String nullitem, Context context) {
return getValues("folder", nullitem, context);
}
private static String[][] getValues(String type, String nullitem, Context context) {
Uri uri = Uri.parse("content://" + GlobalResources.CONTENT_URL + "/" + type);
ContentProviderClient myProvider = context.getContentResolver().acquireContentProviderClient(uri);
Cursor cursor = null;
try {
cursor = myProvider.query(uri, new String[] { "ID", "VALUE" }, null, null, null);
} catch (RemoteException e) {
// TODO Auto-generated catch block
Log.e(TAG, "Failed to aquire content provider for query - is there an active sync running?");
e.printStackTrace();
}
if ( cursor == null ) {
return null;
}
if ( VERBOSE ) Log.v(TAG, "getValues: have acquired content provider for " + type +
" (" + cursor.getCount() + " items returned for " + uri.toString() + ")");
cursor.moveToFirst();
String[] k = new String[cursor.getCount() + 1];
String[] v = new String[cursor.getCount() + 1];
if ( VERBOSE ) Log.v(TAG, "getValues: size " + k.length + " for " + type);
k[0] = null;
v[0] = nullitem;
while (! cursor.isAfterLast() ) {
k[cursor.getPosition() + 1] = cursor.getString(0);
v[cursor.getPosition() + 1] = cursor.getString(1);
if ( VERBOSE ) Log.v(TAG, "getValues: adding " + cursor.getString(0) + " at position " + cursor.getPosition() + " to " + type);
cursor.moveToNext();
}
cursor.close();
return new String[][] { k, v };
}
public static Bitmap getFileThumbData(Context context, String filename) { public static Bitmap getFileThumbData(Context context, String filename) {
if ( filename == null ) if ( filename == null )
return null; return null;
...@@ -490,5 +246,4 @@ public class Utils { ...@@ -490,5 +246,4 @@ public class Utils {
return bm; return bm;
} }
} }
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
package nz.net.catalyst.MaharaDroid.authenticator; package nz.net.catalyst.MaharaDroid.authenticator;
import nz.net.catalyst.MaharaDroid.authenticator.AuthenticatorActivity; import nz.net.catalyst.MaharaDroid.authenticator.AuthenticatorActivity;
import nz.net.catalyst.MaharaDroid.data.SyncUtils;
import nz.net.catalyst.MaharaDroid.GlobalResources; import nz.net.catalyst.MaharaDroid.GlobalResources;
import nz.net.catalyst.MaharaDroid.LogConfig; import nz.net.catalyst.MaharaDroid.LogConfig;
import nz.net.catalyst.MaharaDroid.Utils; import nz.net.catalyst.MaharaDroid.Utils;
...@@ -103,7 +104,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity { ...@@ -103,7 +104,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity {
//TODO confirm but shouldn't have to force this - setSyncAutomatically should kick one off I believe //TODO confirm but shouldn't have to force this - setSyncAutomatically should kick one off I believe
// ContentResolver.requestSync(account, GlobalResources.SYNC_AUTHORITY, null); // ContentResolver.requestSync(account, GlobalResources.SYNC_AUTHORITY, null);
Utils.setPeriodicSync(account, getApplicationContext()); SyncUtils.setPeriodicSync(account, getApplicationContext());
} }
final Intent intent = new Intent(); final Intent intent = new Intent();
......
...@@ -3,7 +3,8 @@ package nz.net.catalyst.MaharaDroid.authenticator; ...@@ -3,7 +3,8 @@ package nz.net.catalyst.MaharaDroid.authenticator;
import nz.net.catalyst.MaharaDroid.LogConfig; import nz.net.catalyst.MaharaDroid.LogConfig;
import nz.net.catalyst.MaharaDroid.R; import nz.net.catalyst.MaharaDroid.R;
import nz.net.catalyst.MaharaDroid.Utils; import nz.net.catalyst.MaharaDroid.Utils;
import nz.net.catalyst.MaharaDroid.provider.MaharaProvider; import nz.net.catalyst.MaharaDroid.data.SyncUtils;
import nz.net.catalyst.MaharaDroid.provider.SyncContentProvider;
import nz.net.catalyst.MaharaDroid.upload.http.RestClient; import nz.net.catalyst.MaharaDroid.upload.http.RestClient;
import org.json.JSONObject; import org.json.JSONObject;
...@@ -61,7 +62,7 @@ public class MaharaAuthHandler { ...@@ -61,7 +62,7 @@ public class MaharaAuthHandler {
// application preferences // application preferences
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext); SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
String authSyncURI = Utils.getSyncURLPref(mContext); String authSyncURI = SyncUtils.getSyncURLPref(mContext);
String token = mPrefs.getString(mContext.getResources().getString(R.string.pref_auth_token_key), ""); String token = mPrefs.getString(mContext.getResources().getString(R.string.pref_auth_token_key), "");
...@@ -74,12 +75,12 @@ public class MaharaAuthHandler { ...@@ -74,12 +75,12 @@ public class MaharaAuthHandler {
Utils.showNotification(NOTIFICATION, mContext.getResources().getText(R.string.login_authenticating), Utils.showNotification(NOTIFICATION, mContext.getResources().getText(R.string.login_authenticating),
null, null, mContext); null, null, mContext);
String syncNotifications = Utils.getSyncNotificationsPref(mContext); String syncNotifications = SyncUtils.getSyncNotificationsPref(mContext);
JSONObject result = RestClient.AuthSync(authSyncURI, token, username, lastsync, syncNotifications, mContext); JSONObject result = RestClient.AuthSync(authSyncURI, token, username, lastsync, syncNotifications, mContext);
token = Utils.updateTokenFromResult(result, mContext); token = Utils.updateTokenFromResult(result, mContext);
if ( result.has("sync") ) { if ( result.has("sync") ) {
Utils.processSyncResults(result, null, mContext, sync_key); SyncUtils.processSyncResults(result, null, mContext, sync_key);
} }
if ( token != null ) { if ( token != null ) {
......
...@@ -241,9 +241,7 @@ public class Artefact extends Object implements Parcelable { ...@@ -241,9 +241,7 @@ public class Artefact extends Object implements Parcelable {
mContext.startService(i); mContext.startService(i);
} }
public void delete(Context mContext) { public void delete(Context mContext) {
ArtefactDataSQLHelper artefactData = new ArtefactDataSQLHelper(mContext); ArtefactUtils.deleteSavedArtefact(mContext, id);
artefactData.deleteSavedArtefact(id);
artefactData.close();
} }
public void view(Context mContext) { public void view(Context mContext) {
try { try {
...@@ -269,21 +267,29 @@ public class Artefact extends Object implements Parcelable { ...@@ -269,21 +267,29 @@ public class Artefact extends Object implements Parcelable {
mContext.startActivity(i); mContext.startActivity(i);
} }
public void save(Context mContext) { public void save(Context mContext) {
ArtefactDataSQLHelper artefactData = new ArtefactDataSQLHelper(mContext);
if ( id != 0 ) { // update if ( id != 0 ) { // update
Log.d("Artefact", "save: is_draft: " + is_draft); Log.d("Artefact", "save: is_draft: " + is_draft);
Log.d("Artefact", "save: allow comments: " + allow_comments); Log.d("Artefact", "save: allow comments: " + allow_comments);
artefactData.update(id, filename, title, description, tags, saved_id, journal_id, is_draft, allow_comments); ArtefactUtils.update(mContext, id, filename, title, description, tags, saved_id, journal_id, is_draft, allow_comments);
} else { // add } else { // add
artefactData.add(filename, title, description, tags, journal_id, is_draft, allow_comments); ArtefactUtils.add(mContext, filename, title, description, tags, journal_id, is_draft, allow_comments);
} }
artefactData.close();
} }
public void load(Context mContext, Long id) {