Переглянути джерело

send contacts to oc instance

Bartek Przybylski 13 роки тому
батько
коміт
cf2c2eedc5

+ 107 - 54
AndroidManifest.xml

@@ -1,76 +1,129 @@
 <?xml version="1.0" encoding="utf-8"?>
 <?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-      package="eu.alefzero.owncloud"
-      android:versionCode="1"
-      android:versionName="1.0">
-<uses-permission
-        android:name="android.permission.GET_ACCOUNTS" />
-    <uses-permission
-        android:name="android.permission.USE_CREDENTIALS" />
-    <uses-permission
-        android:name="android.permission.MANAGE_ACCOUNTS" />
-    <uses-permission
-        android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
-    <uses-permission
-        android:name="android.permission.INTERNET" />
-    <uses-permission
-        android:name="android.permission.WRITE_SETTINGS" />
-    <uses-permission
-        android:name="android.permission.READ_SYNC_STATS" />
-    <uses-permission
-        android:name="android.permission.READ_SYNC_SETTINGS" />
-    <uses-permission
-        android:name="android.permission.WRITE_SYNC_SETTINGS" />
-    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="13" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
-
-    <application android:icon="@drawable/icon" android:label="@string/app_name">
-        <activity android:name=".ui.activity.FileDisplayActivity" android:theme="@style/Theme.ownCloud" android:label="@string/app_name"></activity>
-        <activity android:name=".Uploader">
+<manifest package="eu.alefzero.owncloud"
+    android:versionCode="1"
+    android:versionName="1.0" xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+    <uses-permission android:name="android.permission.USE_CREDENTIALS" />
+    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
+    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.READ_SYNC_STATS" />
+    <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
+    <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
+
+    <uses-sdk
+        android:minSdkVersion="7"
+        android:targetSdkVersion="13" />
+
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >
+    </uses-permission>
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+
+    <application
+        android:icon="@drawable/icon"
+        android:label="@string/app_name" >
+        <activity
+            android:name=".ui.activity.FileDisplayActivity"
+            android:label="@string/app_name"
+            android:theme="@style/Theme.ownCloud" >
+        </activity>
+        <activity android:name=".Uploader" >
             <intent-filter>
             <intent-filter>
-                <action android:name="android.intent.action.SEND"></action>
-                <category android:name="android.intent.category.DEFAULT"></category>
-                <data android:mimeType="*/*"></data>
+                <action android:name="android.intent.action.SEND" >
+                </action>
+
+                <category android:name="android.intent.category.DEFAULT" >
+                </category>
+
+                <data android:mimeType="*/*" >
+                </data>
             </intent-filter>
             </intent-filter>
             <intent-filter>
             <intent-filter>
-                <action android:name="android.intent.action.SEND_MULTIPLE"></action>
-                <category android:name="android.intent.category.DEFAULT"></category>
-                <data android:mimeType="*/*"></data>
+                <action android:name="android.intent.action.SEND_MULTIPLE" >
+                </action>
+
+                <category android:name="android.intent.category.DEFAULT" >
+                </category>
+
+                <data android:mimeType="*/*" >
+                </data>
             </intent-filter>
             </intent-filter>
         </activity>
         </activity>
-        <activity android:name=".ui.activity.Preferences"></activity>
-        <activity android:name=".ui.activity.PreferencesNewSessionewSession"></activity>
-                <service
-            android:exported="true" android:name=".authenticator.AccountAuthenticatorService">
+        <activity android:name=".ui.activity.Preferences" >
+        </activity>
+        <activity android:name=".ui.activity.PreferencesNewSessionewSession" >
+        </activity>
+
+        <service
+            android:name=".authenticator.AccountAuthenticatorService"
+            android:exported="true" >
             <intent-filter>
             <intent-filter>
-                <action
-                    android:name="android.accounts.AccountAuthenticator" />
+                <action android:name="android.accounts.AccountAuthenticator" />
             </intent-filter>
             </intent-filter>
+
             <meta-data
             <meta-data
                 android:name="android.accounts.AccountAuthenticator"
                 android:name="android.accounts.AccountAuthenticator"
                 android:resource="@xml/authenticator" />
                 android:resource="@xml/authenticator" />
         </service>
         </service>
-         <service
-            android:exported="true" android:name=".syncadapter.FileSyncService">
+        <service
+            android:name=".syncadapter.FileSyncService"
+            android:exported="true" >
+            <intent-filter>
+                <action android:name="android.content.SyncAdapter" />
+            </intent-filter>
+
+            <meta-data
+                android:name="android.content.SyncAdapter"
+                android:resource="@xml/syncadapter_files" />
+        </service>
+        <service
+            android:name=".syncadapter.ContactSyncService"
+            android:exported="true"
+            android:process=":contacts" >
             <intent-filter>
             <intent-filter>
-                <action android:name="android.content.SyncAdapter"/>
+                <action android:name="android.content.SyncAdapter" />
             </intent-filter>
             </intent-filter>
+
             <meta-data
             <meta-data
                 android:name="android.content.SyncAdapter"
                 android:name="android.content.SyncAdapter"
-                android:resource="@xml/syncadapter_files"/>
+                android:resource="@xml/syncadapter_contacts" />
+            <meta-data
+                android:name="android.provider.CONTACTS_STRUCTURE"
+                android:resource="@xml/contacts" />
+        </service>
+
+        <provider
+            android:name=".providers.FileContentProvider"
+            android:authorities="org.owncloud"
+            android:enabled="true"
+            android:exported="false"
+            android:label="@string/sync_string_files"
+            android:syncable="true" >
+        </provider>
+
+        <activity
+            android:name=".ui.activity.AuthenticatorActivity"
+            android:theme="@style/Theme.ownCloud" >
+        </activity>
+
+        <service android:name=".FileDownloader" >
         </service>
         </service>
-         <provider android:name=".cp" android:enabled="true" android:syncable="true" android:exported="false" android:authorities="org.owncloud" android:label="@string/sync_string_files"></provider>
-         <activity android:name=".ui.activity.AuthenticatorActivity" android:theme="@style/Theme.ownCloud"></activity>
-         <service android:name=".FileDownloader">
-         </service>
-         <activity android:name=".ui.activity.FileDetailActivity"></activity>
-         <activity android:name=".ui.activity.LandingActivity"
-             android:theme="@style/Theme.ownCloud"
-             android:label="@string/app_name">
-             <intent-filter>
+
+        <activity android:name=".ui.activity.FileDetailActivity" >
+        </activity>
+        <activity
+            android:name=".ui.activity.LandingActivity"
+            android:label="@string/app_name"
+            android:theme="@style/Theme.ownCloud" >
+            <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <action android:name="android.intent.action.MAIN" />
+
                 <category android:name="android.intent.category.LAUNCHER" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
             </intent-filter>
-         </activity>
+        </activity>
     </application>
     </application>
+
 </manifest>
 </manifest>

+ 1 - 1
res/xml/contacts.xml

@@ -20,7 +20,7 @@
 <ContactsSource xmlns:android="http://schemas.android.com/apk/res/android">
 <ContactsSource xmlns:android="http://schemas.android.com/apk/res/android">
 
 
     <ContactsDataKind
     <ContactsDataKind
-        android:mimeType="vnd.android.cursor.item/vnd.samplesyncadapter.profile"
+        android:mimeType="vnd.android.cursor.item/vnd.owncloud.contact.profile"
         android:icon="@drawable/icon"
         android:icon="@drawable/icon"
         android:summaryColumn="data2"
         android:summaryColumn="data2"
         android:detailColumn="data3"
         android:detailColumn="data3"

+ 2 - 2
src/eu/alefzero/owncloud/cp.java → src/eu/alefzero/owncloud/providers/FileContentProvider.java

@@ -16,7 +16,7 @@
  *
  *
  */
  */
 
 
-package eu.alefzero.owncloud;
+package eu.alefzero.owncloud.providers;
 
 
 import java.util.HashMap;
 import java.util.HashMap;
 
 
@@ -41,7 +41,7 @@ import android.text.TextUtils;
 * @author Bartek Przybylski
 * @author Bartek Przybylski
 * 
 * 
 */
 */
-public class cp extends ContentProvider {
+public class FileContentProvider extends ContentProvider {
 
 
   private DataBaseHelper mDbHelper;
   private DataBaseHelper mDbHelper;
   
   

+ 98 - 0
src/eu/alefzero/owncloud/syncadapter/ContactSyncAdapter.java

@@ -0,0 +1,98 @@
+package eu.alefzero.owncloud.syncadapter;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.entity.ByteArrayEntity;
+
+import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
+import eu.alefzero.owncloud.authenticator.AuthUtils;
+import eu.alefzero.owncloud.db.ProviderMeta;
+import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.content.ContentProviderClient;
+import android.content.Context;
+import android.content.SyncResult;
+import android.content.res.AssetFileDescriptor;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.ContactsContract;
+import android.util.Log;
+
+public class ContactSyncAdapter extends AbstractOwnCloudSyncAdapter {
+  private String mAddrBookUri;
+  
+  public ContactSyncAdapter(Context context, boolean autoInitialize) {
+    super(context, autoInitialize);
+    mAddrBookUri = null;
+  }
+
+  @Override
+  public void onPerformSync(Account account, Bundle extras, String authority,
+      ContentProviderClient provider, SyncResult syncResult) {
+    setAccount(account);
+    setContentProvider(provider);
+    Cursor c = getLocalContacts(false);
+    if (c.moveToFirst()) {
+      do {
+      String lookup = c.getString(c.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
+      String a = getAddressBookUri();
+      String uri = a + lookup + ".vcf";
+      FileInputStream f;
+      try {
+        f = getContactVcard(lookup);
+        HttpPut query = new HttpPut(uri);
+        byte[] b = new byte[f.available()];
+        f.read(b);
+        query.setEntity(new ByteArrayEntity(b));
+        HttpResponse response = fireRawRequest(query);
+      } catch (IOException e) {
+        e.printStackTrace();
+        return;
+      } catch (OperationCanceledException e) {
+        // TODO Auto-generated catch block
+        e.printStackTrace();
+      } catch (AuthenticatorException e) {
+        // TODO Auto-generated catch block
+        e.printStackTrace();
+      }
+      }while (c.moveToNext());
+      //} while (c.moveToNext());
+    }
+
+  }
+
+  private String getAddressBookUri() {
+    if (mAddrBookUri != null) return mAddrBookUri;
+
+    AccountManager am = getAccountManager();
+    String uri = am.getUserData(getAccount(), AccountAuthenticator.KEY_OC_URL)
+                   .replace(AuthUtils.WEBDAV_PATH_2_0, AuthUtils.CARDDAV_PATH_2_0);
+    uri += "/addressbooks/" + getAccount().name.substring(0, getAccount().name.lastIndexOf('@'))
+        + "/default/";
+    mAddrBookUri = uri;
+    return uri;
+  }
+  
+  private FileInputStream getContactVcard(String lookupKey) throws IOException {
+    Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
+    AssetFileDescriptor fd = getContext().getContentResolver().openAssetFileDescriptor(uri, "r");
+    return fd.createInputStream();
+  }
+  
+  private Cursor getLocalContacts(boolean include_hidden_contacts) {
+    return getContext().getContentResolver().query(
+        ContactsContract.Contacts.CONTENT_URI,
+        new String[] {ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY},
+        ContactsContract.Contacts.IN_VISIBLE_GROUP + " = ?",
+        new String[]{ (include_hidden_contacts?"0":"1")},
+        ContactsContract.Contacts._ID + " DESC");
+  }
+  
+}

+ 25 - 0
src/eu/alefzero/owncloud/syncadapter/ContactSyncService.java

@@ -0,0 +1,25 @@
+package eu.alefzero.owncloud.syncadapter;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class ContactSyncService extends Service {
+  private static final Object syncAdapterLock = new Object();
+  private static AbstractOwnCloudSyncAdapter mSyncAdapter = null;
+  
+  @Override
+  public void onCreate() {
+      synchronized (syncAdapterLock) {
+          if (mSyncAdapter == null) {
+              mSyncAdapter = new ContactSyncAdapter(getApplicationContext(), true);
+          }
+      }
+  }
+  
+  @Override
+  public IBinder onBind(Intent arg0) {
+    return mSyncAdapter.getSyncAdapterBinder();
+  }
+
+}

+ 1 - 1
src/eu/alefzero/owncloud/syncadapter/FileSyncAdapter.java

@@ -80,7 +80,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
 			e.printStackTrace();
 			e.printStackTrace();
 		}// catch (RemoteException e) {
 		}// catch (RemoteException e) {
 		//	e.printStackTrace();
 		//	e.printStackTrace();
-		//}
+		// q}
 	}
 	}
 
 
 	private void commitToDatabase(TreeNode root, String parentId) throws RemoteException {
 	private void commitToDatabase(TreeNode root, String parentId) throws RemoteException {

+ 42 - 0
src/eu/alefzero/owncloud/ui/fragment/FileList.java

@@ -17,14 +17,19 @@
  */
  */
 package eu.alefzero.owncloud.ui.fragment;
 package eu.alefzero.owncloud.ui.fragment;
 
 
+import java.util.ArrayList;
 import java.util.Stack;
 import java.util.Stack;
 import java.util.Vector;
 import java.util.Vector;
 
 
 import android.accounts.Account;
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.accounts.AccountManager;
 import android.app.Service;
 import android.app.Service;
+import android.content.ContentProviderOperation;
 import android.content.Intent;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.Bundle;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.RawContacts;
+import android.util.Log;
 import android.view.View;
 import android.view.View;
 import android.widget.AdapterView;
 import android.widget.AdapterView;
 import eu.alefzero.owncloud.R;
 import eu.alefzero.owncloud.R;
@@ -57,6 +62,7 @@ public class FileList extends FragmentListView {
     mAccountManager = (AccountManager)getActivity().getSystemService(Service.ACCOUNT_SERVICE);
     mAccountManager = (AccountManager)getActivity().getSystemService(Service.ACCOUNT_SERVICE);
     mAccount = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[0];
     mAccount = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[0];
     populateFileList();
     populateFileList();
+    //addContact(mAccount, "Bartek Przybylski", "czlowiek");
   }
   }
   
   
   @Override
   @Override
@@ -102,4 +108,40 @@ public class FileList extends FragmentListView {
     mFiles = file.getDirectoryContent();
     mFiles = file.getDirectoryContent();
     setListAdapter(new FileListListAdapter(file, getActivity()));
     setListAdapter(new FileListListAdapter(file, getActivity()));
   }
   }
+  
+  private  void addContact(Account account, String name, String username) {
+    Log.i("ASD", "Adding contact: " + name);
+    ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();
+    
+    //Create our RawContact
+    ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
+    builder.withValue(RawContacts.ACCOUNT_NAME, account.name);
+    builder.withValue(RawContacts.ACCOUNT_TYPE, account.type);
+    builder.withValue(RawContacts.SYNC1, username);
+    operationList.add(builder.build());
+    
+    //Create a Data record of common type 'StructuredName' for our RawContact
+    builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
+    builder.withValueBackReference(ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, 0);
+    builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
+    builder.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name);
+    operationList.add(builder.build());
+    
+    //Create a Data record of custom type "vnd.android.cursor.item/vnd.fm.last.android.profile" to display a link to the Last.fm profile
+    builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
+    builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0);
+    builder.withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/vnd.owncloud.contact.profile");
+    builder.withValue(ContactsContract.Data.DATA1, username);
+    builder.withValue(ContactsContract.Data.DATA2, "Last.fm Profile");
+    builder.withValue(ContactsContract.Data.DATA3, "View profile");
+    operationList.add(builder.build());
+    
+    try {
+     getActivity().getContentResolver().applyBatch(ContactsContract.AUTHORITY, operationList);
+    } catch (Exception e) {
+     Log.e("ASD", "Something went wrong during creation! " + e);
+     e.printStackTrace();
+    }
+   }
+  
 }
 }