Merge "Updated the sample"

This commit is contained in:
Daniel Lehmann
2011-09-29 17:09:29 -07:00
committed by Android (Google) Code Review
27 changed files with 436 additions and 802 deletions

View File

@@ -46,7 +46,7 @@
<uses-permission <uses-permission
android:name="android.permission.WRITE_SYNC_SETTINGS" /> android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="11"/> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="14"/>
<application <application
android:icon="@drawable/icon" android:icon="@drawable/icon"
@@ -100,27 +100,8 @@
</activity> </activity>
<activity <activity
android:name=".editor.ContactEditorActivity" android:name=".activites.InviteContactActivity"
android:theme="@style/ContactEditTheme" android:theme="@android:style/Theme.Dialog">
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action
android:name="android.intent.action.INSERT" />
<data
android:mimeType="vnd.android.cursor.item/contact" />
</intent-filter>
<!--
Note that the editor gets a raw contact URI, but is expected to call
setResult with the corresponding aggregate contact URI, not raw contact
URI.
-->
<intent-filter>
<action
android:name="android.intent.action.EDIT" />
<data
android:mimeType="vnd.android.cursor.item/raw_contact" />
</intent-filter>
<!-- <!--
We use the INVITE intent to add a raw contact to an existing contact. We use the INVITE intent to add a raw contact to an existing contact.
It always comes with a lookup URI. It always comes with a lookup URI.
@@ -132,5 +113,50 @@
android:mimeType="vnd.android.cursor.item/contact" /> android:mimeType="vnd.android.cursor.item/contact" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity
android:name=".activities.ViewGroupActivity"
android:theme="@android:style/Theme.Dialog">
<!--
We use the VIEW intent to view a group in our app.
It always comes with a lookup URI.
-->
<intent-filter>
<action
android:name="android.intent.action.VIEW" />
<data
android:mimeType="vnd.android.cursor.item/group" />
</intent-filter>
</activity>
<activity
android:name=".activities.ViewStreamItemActivity"
android:theme="@android:style/Theme.Dialog">
<!--
We use the VIEW intent to view a stream item in our app.
It always comes with a lookup URI.
-->
<intent-filter>
<action
android:name="android.intent.action.VIEW" />
<data
android:mimeType="vnd.android.cursor.item/stream_item" />
</intent-filter>
</activity>
<activity
android:name=".activities.ViewStreamItemPhotoActivity"
android:theme="@android:style/Theme.Dialog">
<!--
We use the VIEW intent to view a stream item photo in our app.
It always comes with a lookup URI.
-->
<intent-filter>
<action
android:name="android.intent.action.VIEW" />
<data
android:mimeType="vnd.android.cursor.item/stream_item_photo" />
</intent-filter>
</activity>
</application> </application>
</manifest> </manifest>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/EditPanelBackgroundColor" />
<stroke android:width="2dip" android:color="@color/EditPanelBorderColor" />
<padding android:left="5dip" android:top="5dip" android:right="5dip" android:bottom="5dip" />
</shape>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 658 B

View File

@@ -1,43 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
/**
* Copyright (c) 2010, 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.
*/
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="600dip"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/border">
<include layout="@layout/editor_header" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dip"
android:paddingTop="20dip"
android:paddingRight="20dip"
android:paddingBottom="20dip"
android:paddingLeft="20dip"
android:layout_weight="1">
<include layout="@layout/editor_fields" />
</ScrollView>
</LinearLayout>
</LinearLayout>

View File

@@ -1,58 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 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.
-->
<!-- Account info header -->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="64dip"
android:layout_width="match_parent"
android:background="?android:attr/selectableItemBackground">
<ImageView
android:id="@+id/header_account_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="7dip"
android:layout_marginRight="7dip"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:src="@drawable/icon" />
<TextView
android:id="@+id/header_account_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/header_account_icon"
android:layout_alignTop="@id/header_account_icon"
android:layout_marginTop="-4dip"
android:textSize="24sp"
android:textColor="?android:attr/textColorPrimary"
android:singleLine="true"
android:text="@string/header_account_type" />
<TextView
android:id="@+id/header_account_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/header_account_icon"
android:layout_alignBottom="@+id/header_account_icon"
android:layout_marginBottom="2dip"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorPrimary"
android:singleLine="true" />
</RelativeLayout>

View File

@@ -1,127 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
/**
* Copyright (c) 2010, 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.
*/
-->
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="2">
<TableRow>
<TextView
android:layout_column="1"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_name"
android:padding="3dip" />
<EditText
android:layout_column="2"
android:id="@+id/editor_name"
android:singleLine="true"
android:inputType="textPersonName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minWidth="250dip"
android:scrollHorizontally="true"
android:capitalize="none"
android:textSize="@dimen/contact_name_text_size"
android:gravity="fill_horizontal"
android:autoText="false" />
</TableRow>
<TableRow>
<TextView
android:layout_column="1"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_phone_home"
android:padding="3dip" />
<EditText
android:id="@+id/editor_phone_home"
android:singleLine="true"
android:inputType="phone"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minWidth="250dip"
android:scrollHorizontally="true"
android:capitalize="none"
android:gravity="fill_horizontal"
android:autoText="false" />
</TableRow>
<TableRow>
<TextView
android:layout_column="1"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_phone_mobile"
android:padding="3dip" />
<EditText
android:id="@+id/editor_phone_mobile"
android:singleLine="true"
android:inputType="phone"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minWidth="250dip"
android:scrollHorizontally="true"
android:capitalize="none"
android:gravity="fill_horizontal"
android:autoText="false" />
</TableRow>
<TableRow>
<TextView
android:layout_column="1"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_phone_work"
android:padding="3dip" />
<EditText
android:id="@+id/editor_phone_work"
android:singleLine="true"
android:phoneNumber="true"
android:autoText="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minWidth="250dip"
android:scrollHorizontally="true"
android:capitalize="none"
android:gravity="fill_horizontal" />
</TableRow>
<TableRow>
<TextView
android:layout_column="1"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_email"
android:padding="3dip" />
<EditText
android:id="@+id/editor_email"
android:singleLine="true"
android:inputType="textEmailAddress"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minWidth="250dip"
android:scrollHorizontally="true"
android:capitalize="none"
android:gravity="fill_horizontal"
android:autoText="false" />
</TableRow>
</TableLayout>

View File

@@ -18,19 +18,15 @@
--> -->
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:orientation="vertical"
android:layout_height="match_parent" android:layout_width="wrap_content"
android:orientation="vertical"> android:layout_height="wrap_content">
<TextView
<ScrollView android:text="@string/invite_contact_description"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="0dip" android:layout_height="wrap_content" />
android:paddingTop="20dip" <TextView
android:paddingRight="20dip" android:id="@+id/invite_contact_uri"
android:paddingBottom="20dip" android:layout_width="wrap_content"
android:paddingLeft="20dip" android:layout_height="wrap_content" />
android:layout_weight="1">
<include layout="@layout/editor_fields" />
</ScrollView>
</LinearLayout> </LinearLayout>

View File

@@ -55,7 +55,8 @@
android:scrollHorizontally="true" android:scrollHorizontally="true"
android:capitalize="none" android:capitalize="none"
android:autoText="false" android:autoText="false"
android:inputType="textEmailAddress" /> android:inputType="textEmailAddress"
android:text="user" />
<TextView <TextView
android:id="@+id/username_fixed" android:id="@+id/username_fixed"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
@@ -81,7 +82,8 @@
android:capitalize="none" android:capitalize="none"
android:autoText="false" android:autoText="false"
android:password="true" android:password="true"
android:inputType="textPassword" /> android:inputType="textPassword"
android:text="test" />
<TextView <TextView
android:id="@+id/message_bottom" android:id="@+id/message_bottom"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
/**
* Copyright (c) 2011, 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.
*/
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:text="@string/view_group_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/view_group_uri"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
/**
* Copyright (c) 2011, 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.
*/
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:text="@string/view_stream_item_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/view_stream_item_uri"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
/**
* Copyright (c) 2011, 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.
*/
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:text="@string/view_stream_item_photo_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/view_stream_item_photo_uri"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>

View File

@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 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.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_done"
android:alphabeticShortcut="\n"
android:icon="@drawable/done_menu_icon"
android:title="@string/menu_done"
android:showAsAction="always|withText" />
<item
android:id="@+id/menu_cancel"
android:alphabeticShortcut="q"
android:title="@string/menu_cancel"
android:showAsAction="always|withText" />
</menu>

View File

@@ -109,4 +109,34 @@
<!-- The label of the button to add contact to this contact provider --> <!-- The label of the button to add contact to this contact provider -->
<string name="invite_action_label">Add to Sample SyncAdaper</string> <string name="invite_action_label">Add to Sample SyncAdaper</string>
<!-- The description for the invite contact flow -->
<string name="invite_contact_description">Congratulations! The user wants to add the contact
to the amazing Sample SyncAdapter social network. If this was a real app, it should now
make best efforts to add the contact to this network. This would probably involve
looking up the person on the network, inviting if he is not there already and syncing
the new contact down.
Ideally, when the user gets back to the People app, the new contact should already
be there, enriching the original contact.
This is the information we got to lookup the contact:</string>
<!-- The label of the button to view a group -->
<string name="view_group_action_label">Show sample group details</string>
<!-- The description for the view group button -->
<string name="view_group_description">This would now show the details of the group.
This is the group uri:</string>
<!-- The description for the view stream item -->
<string name="view_stream_item_description">This would now show the details of the stream item.
This is the uri of the stream item:</string>
<!-- The description for the view stream item photo -->
<string name="view_stream_item_photo_description">This would now show the details of the stream item photo.
This is the uri of the photo:</string>
</resources> </resources>

View File

@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 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.
-->
<resources>
<!--
These styles will only be used in Honeycomb and later because
Android doesn't support third-party contact editing in pre-
Honeycomb versions.
-->
<color name="EditPanelBackgroundColor">#ffffff</color>
<color name="EditPanelBorderColor">#cccccc</color>
<style name="ContactEditTheme" parent="android:Theme.Holo.Light">
</style>
</resources>

View File

@@ -19,8 +19,6 @@
<ContactsAccountType <ContactsAccountType
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
editContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
createContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
> >
<ContactsDataKind <ContactsDataKind

View File

@@ -17,18 +17,15 @@
*/ */
--> -->
<!-- This sample doesn't currently support groups or stream items. viewGroupActivity and
viewStreamItemActivity and viewStreamItemPhotoActivity or just here for reference -->
<ContactsAccountType <ContactsAccountType
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
editContactActivity="com.example.android.samplesync.editor.ContactEditorActivity" inviteContactActivity="com.example.android.samplesync.activities.InviteContactActivity"
createContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
inviteContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
inviteContactActionLabel="@string/invite_action_label" inviteContactActionLabel="@string/invite_action_label"
viewContactNotifyService="com.example.android.samplesync.notifier.NotifierService" viewContactNotifyService="com.example.android.samplesync.notifier.NotifierService"
viewGroupActivity="com.example.android.samplesync.viewer.ViewGroupActivity" viewGroupActivity="com.example.android.samplesync.activities.ViewGroupActivity"
viewStreamItemActivity="com.example.android.samplesync.viewer.ViewStreamItemActivity" viewGroupActionLabel="@string/view_group_action_label"
viewStreamItemPhotoActivity="com.example.android.samplesync.viewer.ViewStreamItemPhotoActivity" viewStreamItemActivity="com.example.android.samplesync.activities.ViewStreamItemActivity"
viewStreamItemPhotoActivity="com.example.android.samplesync.activities.ViewStreamItemPhotoActivity"
> >
<ContactsDataKind <ContactsDataKind

View File

@@ -19,8 +19,6 @@
<ContactsSource <ContactsSource
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
editContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
createContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
> >
<ContactsDataKind <ContactsDataKind

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2011 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.example.android.samplesync.activities;
import com.example.android.samplesync.R;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
/**
* Activity to handle the invite-intent. In a real app, this would look up the user on the network
* and either connect ("add as friend", "follow") or invite them to the network
*/
public class InviteContactActivity extends Activity {
private static final String TAG = "InviteContactActivity";
private TextView mUriTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.invite_contact_activity);
mUriTextView = (TextView) findViewById(R.id.invite_contact_uri);
mUriTextView.setText(getIntent().getDataString());
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2011 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.example.android.samplesync.activities;
import com.example.android.samplesync.R;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
/**
* Activity to handle the view-group action. In a real app, this would show a rich view of the
* group, like members, updates etc.
*/
public class ViewGroupActivity extends Activity {
private static final String TAG = "ViewGroupActivity";
private TextView mUriTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_group_activity);
mUriTextView = (TextView) findViewById(R.id.view_group_uri);
mUriTextView.setText(getIntent().getDataString());
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2011 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.example.android.samplesync.activities;
import com.example.android.samplesync.R;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
/**
* Activity to handle view a stream-item. In a real app, this would show a rich view of the
* item.
*/
public class ViewStreamItemActivity extends Activity {
private static final String TAG = "ViewStreamItemActivity";
private TextView mUriTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_stream_item_activity);
mUriTextView = (TextView) findViewById(R.id.view_stream_item_uri);
mUriTextView.setText(getIntent().getDataString());
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2011 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.example.android.samplesync.activities;
import com.example.android.samplesync.R;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
/**
* Activity to view a stream-item-photo. In a real app, this would show a fullscreen view of the
* photo, potentially with ways to interact with it
*/
public class ViewStreamItemPhotoActivity extends Activity {
private static final String TAG = "ViewStreamItemPhotoActivity";
private TextView mUriTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_stream_item_photo_activity);
mUriTextView = (TextView) findViewById(R.id.view_stream_item_photo_uri);
mUriTextView.setText(getIntent().getDataString());
}
}

View File

@@ -110,7 +110,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity {
mMessage = (TextView) findViewById(R.id.message); mMessage = (TextView) findViewById(R.id.message);
mUsernameEdit = (EditText) findViewById(R.id.username_edit); mUsernameEdit = (EditText) findViewById(R.id.username_edit);
mPasswordEdit = (EditText) findViewById(R.id.password_edit); mPasswordEdit = (EditText) findViewById(R.id.password_edit);
mUsernameEdit.setText(mUsername); if (!TextUtils.isEmpty(mUsername)) mUsernameEdit.setText(mUsername);
mMessage.setText(getMessage()); mMessage.setText(getMessage());
} }

View File

@@ -16,16 +16,6 @@
package com.example.android.samplesync.client; package com.example.android.samplesync.client;
import android.accounts.Account;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import com.example.android.samplesync.authenticator.AuthenticatorActivity;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus; import org.apache.http.HttpStatus;
@@ -41,9 +31,15 @@ import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams; import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject;
import android.accounts.Account;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.TextUtils;
import android.util.Log;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@@ -54,11 +50,8 @@ import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.TimeZone;
/** /**
* Provides utility methods for communicating with the server. * Provides utility methods for communicating with the server.

View File

@@ -1,430 +0,0 @@
/*
* Copyright (C) 2010 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.example.android.samplesync.editor;
import com.example.android.samplesync.Constants;
import com.example.android.samplesync.R;
import com.example.android.samplesync.client.RawContact;
import com.example.android.samplesync.platform.BatchOperation;
import com.example.android.samplesync.platform.ContactManager;
import com.example.android.samplesync.platform.ContactManager.ContactQuery;
import com.example.android.samplesync.platform.ContactManager.EditorQuery;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.RawContacts;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.TextView;
/**
* Implements a sample editor for a contact that belongs to a remote contact service.
* The editor can be invoked for an existing SampleSyncAdapter contact, or it can
* be used to create a brand new SampleSyncAdapter contact. We look at the Intent
* object to figure out whether this is a "new" or "edit" operation.
*/
public class ContactEditorActivity extends Activity {
private static final String TAG = "SampleSyncAdapter";
// Keep track of whether we're inserting a new contact or editing an
// existing contact.
private boolean mIsInsert;
// The name of the external account we're syncing this contact to.
private String mAccountName;
// For existing contacts, this is the URI to the contact data.
private Uri mRawContactUri;
// The raw clientId for this contact
private long mRawContactId;
// Make sure we only attempt to save the contact once if the
// user presses the "done" button multiple times...
private boolean mSaveInProgress = false;
// Keep track of the controls used to edit contact values, so we can get/set
// those values easily.
private EditText mNameEditText;
private EditText mHomePhoneEditText;
private EditText mMobilePhoneEditText;
private EditText mWorkPhoneEditText;
private EditText mEmailEditText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.editor);
mNameEditText = (EditText)findViewById(R.id.editor_name);
mHomePhoneEditText = (EditText)findViewById(R.id.editor_phone_home);
mMobilePhoneEditText = (EditText)findViewById(R.id.editor_phone_mobile);
mWorkPhoneEditText = (EditText)findViewById(R.id.editor_phone_work);
mEmailEditText = (EditText)findViewById(R.id.editor_email);
// Figure out whether we're creating a new contact (ACTION_INSERT), editing
// an existing contact, or adding a new one to existing contact (INVITE_CONTACT).
Intent intent = getIntent();
String action = intent.getAction();
if (Intent.ACTION_INSERT.equals(action)) {
// We're inserting a new contact, so save off the external account name
// which should have been added to the intent we were passed.
mIsInsert = true;
String accountName = intent.getStringExtra(RawContacts.ACCOUNT_NAME);
if (accountName == null) {
Log.e(TAG, "Account name is required");
finish();
}
setAccountName(accountName);
} else if (ContactsContract.Intents.INVITE_CONTACT.equals(action)) {
// Adding to an existing contact.
mIsInsert = true;
// Use the first account found.
Account[] myAccounts = AccountManager.get(this).getAccountsByType(
Constants.ACCOUNT_TYPE);
if (myAccounts.length == 0) {
Log.e(TAG, "Account not configured");
finish();
}
setAccountName(myAccounts[0].name);
Uri lookupUri = intent.getData();
if (lookupUri == null) {
Log.e(TAG, "Contact lookup URI is required");
finish();
}
startLoadContactEntity(lookupUri);
} else {
// We're editing an existing contact. Load in the data from the contact
// so that the user can edit it.
mIsInsert = false;
mRawContactUri = intent.getData();
if (mRawContactUri == null) {
Log.e(TAG, "Raw contact URI is required");
finish();
}
startLoadRawContactEntity();
}
}
@Override
public void onBackPressed() {
// This method will have been called if the user presses the "Back" button
// in the ActionBar. We treat that the same way as the "Done" button in
// the ActionBar.
save();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// This method gets called so that we can place items in the main Options menu -
// for example, the ActionBar items. We add our menus from the res/menu/edit.xml
// file.
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.edit, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
case R.id.menu_done:
// The user pressed the "Home" button or our "Done" button - both
// in the ActionBar. In both cases, we want to save the contact
// and exit.
save();
return true;
case R.id.menu_cancel:
// The user pressed the Cancel menu item in the ActionBar.
// Close the editor without saving any changes.
finish();
return true;
}
return false;
}
/**
* Create an AsyncTask to load the contact from the Contacts data provider
*/
private void startLoadRawContactEntity() {
Uri uri = Uri.withAppendedPath(mRawContactUri, RawContacts.Entity.CONTENT_DIRECTORY);
new LoadRawContactTask().execute(uri);
}
/**
* Called by the LoadRawContactTask when the contact information has been
* successfully loaded from the Contacts data provider.
*/
public void onRawContactEntityLoaded(Cursor cursor) {
if (cursor.moveToFirst()) {
String mimetype = cursor.getString(EditorQuery.COLUMN_MIMETYPE);
if (StructuredName.CONTENT_ITEM_TYPE.equals(mimetype)) {
setAccountName(cursor.getString(EditorQuery.COLUMN_ACCOUNT_NAME));
mRawContactId = cursor.getLong(EditorQuery.COLUMN_RAW_CONTACT_ID);
mNameEditText.setText(cursor.getString(EditorQuery.COLUMN_FULL_NAME));
} else if (Phone.CONTENT_ITEM_TYPE.equals(mimetype)) {
final int type = cursor.getInt(EditorQuery.COLUMN_PHONE_TYPE);
if (type == Phone.TYPE_HOME) {
mHomePhoneEditText.setText(cursor.getString(EditorQuery.COLUMN_PHONE_NUMBER));
} else if (type == Phone.TYPE_MOBILE) {
mMobilePhoneEditText.setText(cursor.getString(EditorQuery.COLUMN_PHONE_NUMBER));
} else if (type == Phone.TYPE_WORK) {
mWorkPhoneEditText.setText(cursor.getString(EditorQuery.COLUMN_PHONE_NUMBER));
}
} else if (Email.CONTENT_ITEM_TYPE.equals(mimetype)) {
mEmailEditText.setText(cursor.getString(EditorQuery.COLUMN_DATA1));
}
}
}
/**
* Create an AsyncTask to load the contact from the Contacts data provider
*/
private void startLoadContactEntity(Uri lookupUri) {
new LoadContactTask().execute(lookupUri);
}
/**
* Called by the LoadContactTask when the contact information has been
* successfully loaded from the Contacts data provider.
*/
public void onContactEntityLoaded(Cursor cursor) {
if (cursor.moveToFirst()) {
mNameEditText.setText(cursor.getString(ContactQuery.COLUMN_DISPLAY_NAME));
}
}
/**
* Save the updated contact data. We actually take two different actions
* depending on whether we are creating a new contact or editing an
* existing contact.
*/
public void save() {
// If we're already saving this contact, don't kick-off yet
// another save - the user probably just pressed the "Done"
// button multiple times...
if (mSaveInProgress) {
return;
}
mSaveInProgress = true;
if (mIsInsert) {
saveNewContact();
} else {
saveChanges();
}
}
/**
* Save off the external contacts provider account name. We show the account name
* in the header section of the edit panel, and we also need it later when we
* save off a brand new contact.
*/
private void setAccountName(String accountName) {
mAccountName = accountName;
Log.i(TAG, "account=" + mAccountName);
if (accountName != null) {
TextView accountNameLabel = (TextView)findViewById(R.id.header_account_name);
if (accountNameLabel != null) {
accountNameLabel.setText(accountName);
}
}
}
/**
* Save a new contact using the Contacts content provider. The actual insertion
* is performed in an AsyncTask.
*/
@SuppressWarnings("unchecked")
private void saveNewContact() {
new InsertContactTask().execute(buildRawContact());
}
/**
* Save changes to an existing contact. The actual update is performed in
* an AsyncTask.
*/
@SuppressWarnings("unchecked")
private void saveChanges() {
new UpdateContactTask().execute(buildRawContact());
}
/**
* Build a RawContact object from the data in the user-editable form
* @return a new RawContact object representing the edited user
*/
private RawContact buildRawContact() {
return RawContact.create(mNameEditText.getText().toString(),
null,
null,
mMobilePhoneEditText.getText().toString(),
mWorkPhoneEditText.getText().toString(),
mHomePhoneEditText.getText().toString(),
mEmailEditText.getText().toString(),
null,
false,
mRawContactId,
-1);
}
/**
* Called after a contact is saved - both for edited contacts and new contacts.
* We set the final result of the activity to be "ok", and then close the activity
* by calling finish().
*/
public void onContactSaved(Uri result) {
if (result != null) {
Intent intent = new Intent();
intent.setData(result);
setResult(RESULT_OK, intent);
finish();
}
mSaveInProgress = false;
}
/**
* Represents an asynchronous task used to load a contact from
* the Contacts content provider.
*
*/
public class LoadRawContactTask extends AsyncTask<Uri, Void, Cursor> {
@Override
protected Cursor doInBackground(Uri... params) {
// Our background task is to load the contact from the Contacts provider
return getContentResolver().query(params[0], EditorQuery.PROJECTION, null, null, null);
}
@Override
protected void onPostExecute(Cursor cursor) {
if (cursor == null) return;
// After we've successfully loaded the contact, call back into
// the ContactEditorActivity so we can update the UI
try {
onRawContactEntityLoaded(cursor);
} finally {
cursor.close();
}
}
}
/**
* Represents an asynchronous task used to save a new contact
* into the contacts database.
*/
public class InsertContactTask extends AsyncTask<RawContact, Void, Uri> {
@Override
protected Uri doInBackground(RawContact... params) {
try {
final RawContact rawContact = params[0];
final Context context = getApplicationContext();
final ContentResolver resolver = getContentResolver();
final BatchOperation batchOperation = new BatchOperation(context, resolver);
ContactManager.addContact(context, mAccountName, rawContact, false, batchOperation);
Uri rawContactUri = batchOperation.execute();
// Convert the raw contact URI to a contact URI
if (rawContactUri != null) {
return RawContacts.getContactLookupUri(resolver, rawContactUri);
} else {
Log.e(TAG, "Could not save new contact");
return null;
}
} catch (Exception e) {
Log.e(TAG, "An error occurred while saving new contact", e);
}
return null;
}
@Override
protected void onPostExecute(Uri result) {
// Tell the UI that the contact has been successfully saved
onContactSaved(result);
}
}
/**
* Represents an asynchronous task used to save an updated contact
* into the contacts database.
*/
public class UpdateContactTask extends AsyncTask<RawContact, Void, Uri> {
@Override
protected Uri doInBackground(RawContact... params) {
try {
final RawContact rawContact = params[0];
final Context context = getApplicationContext();
final ContentResolver resolver = getContentResolver();
final BatchOperation batchOperation = new BatchOperation(context, resolver);
ContactManager.updateContact(context, resolver, rawContact, false, false, false,
false, rawContact.getRawContactId(), batchOperation);
batchOperation.execute();
// Convert the raw contact URI to a contact URI
return RawContacts.getContactLookupUri(resolver, mRawContactUri);
} catch (Exception e) {
Log.e(TAG, "Could not save changes", e);
}
return null;
}
@Override
protected void onPostExecute(Uri result) {
// Tell the UI that the contact has been successfully saved
onContactSaved(result);
}
}
/**
* Loads contact information by a lookup URI.
*/
public class LoadContactTask extends AsyncTask<Uri, Void, Cursor> {
@Override
protected Cursor doInBackground(Uri... params) {
return getContentResolver().query(params[0], ContactQuery.PROJECTION, null, null, null);
}
@Override
protected void onPostExecute(Cursor cursor) {
if (cursor == null) return;
try {
onContactEntityLoaded(cursor);
} finally {
cursor.close();
}
}
}
}

View File

@@ -34,6 +34,7 @@ import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName; import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data; import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Groups;
import android.provider.ContactsContract.RawContacts; import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.Settings; import android.provider.ContactsContract.Settings;
import android.provider.ContactsContract.StatusUpdates; import android.provider.ContactsContract.StatusUpdates;
@@ -54,6 +55,41 @@ public class ContactManager {
private static final String TAG = "ContactManager"; private static final String TAG = "ContactManager";
public static final String SAMPLE_GROUP_NAME = "Sample Group";
public static long ensureSampleGroupExists(Context context, Account account) {
final ContentResolver resolver = context.getContentResolver();
// Lookup the sample group
long groupId = 0;
final Cursor cursor = resolver.query(Groups.CONTENT_URI, new String[] { Groups._ID },
Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=? AND " +
Groups.TITLE + "=?",
new String[] { account.name, account.type, SAMPLE_GROUP_NAME }, null);
if (cursor != null) {
try {
if (cursor.moveToFirst()) {
groupId = cursor.getLong(0);
}
} finally {
cursor.close();
}
}
if (groupId == 0) {
// Sample group doesn't exist yet, so create it
final ContentValues contentValues = new ContentValues();
contentValues.put(Groups.ACCOUNT_NAME, account.name);
contentValues.put(Groups.ACCOUNT_TYPE, account.type);
contentValues.put(Groups.TITLE, SAMPLE_GROUP_NAME);
contentValues.put(Groups.GROUP_IS_READ_ONLY, true);
final Uri newGroupUri = resolver.insert(Groups.CONTENT_URI, contentValues);
groupId = ContentUris.parseId(newGroupUri);
}
return groupId;
}
/** /**
* Take a list of updated contacts and apply those changes to the * Take a list of updated contacts and apply those changes to the
* contacts database. Typically this list of contacts would have been * contacts database. Typically this list of contacts would have been
@@ -67,7 +103,7 @@ public class ContactManager {
* sync request. * sync request.
*/ */
public static synchronized long updateContacts(Context context, String account, public static synchronized long updateContacts(Context context, String account,
List<RawContact> rawContacts, long lastSyncMarker) { List<RawContact> rawContacts, long groupId, long lastSyncMarker) {
long currentSyncMarker = lastSyncMarker; long currentSyncMarker = lastSyncMarker;
final ContentResolver resolver = context.getContentResolver(); final ContentResolver resolver = context.getContentResolver();
@@ -112,7 +148,7 @@ public class ContactManager {
Log.d(TAG, "In addContact"); Log.d(TAG, "In addContact");
if (!rawContact.isDeleted()) { if (!rawContact.isDeleted()) {
newUsers.add(rawContact); newUsers.add(rawContact);
addContact(context, account, rawContact, true, batchOperation); addContact(context, account, rawContact, groupId, true, batchOperation);
} }
} }
// A sync adapter should batch operations on multiple contacts, // A sync adapter should batch operations on multiple contacts,
@@ -235,12 +271,13 @@ public class ContactManager {
* @param context the Authenticator Activity context * @param context the Authenticator Activity context
* @param accountName the account the contact belongs to * @param accountName the account the contact belongs to
* @param rawContact the sample SyncAdapter User object * @param rawContact the sample SyncAdapter User object
* @param groupId the id of the sample group
* @param inSync is the add part of a client-server sync? * @param inSync is the add part of a client-server sync?
* @param batchOperation allow us to batch together multiple operations * @param batchOperation allow us to batch together multiple operations
* into a single provider call * into a single provider call
*/ */
public static void addContact(Context context, String accountName, RawContact rawContact, public static void addContact(Context context, String accountName, RawContact rawContact,
boolean inSync, BatchOperation batchOperation) { long groupId, boolean inSync, BatchOperation batchOperation) {
// Put the data in the contacts provider // Put the data in the contacts provider
final ContactOperations contactOp = ContactOperations.createNewContact( final ContactOperations contactOp = ContactOperations.createNewContact(
@@ -252,6 +289,7 @@ public class ContactManager {
.addPhone(rawContact.getCellPhone(), Phone.TYPE_MOBILE) .addPhone(rawContact.getCellPhone(), Phone.TYPE_MOBILE)
.addPhone(rawContact.getHomePhone(), Phone.TYPE_HOME) .addPhone(rawContact.getHomePhone(), Phone.TYPE_HOME)
.addPhone(rawContact.getOfficePhone(), Phone.TYPE_WORK) .addPhone(rawContact.getOfficePhone(), Phone.TYPE_WORK)
.addGroupMembership(groupId)
.addAvatar(rawContact.getAvatarUrl()); .addAvatar(rawContact.getAvatarUrl());
// If we have a serverId, then go ahead and create our status profile. // If we have a serverId, then go ahead and create our status profile.

View File

@@ -25,6 +25,7 @@ import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.provider.ContactsContract; import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Email; import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.Photo; import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName; import android.provider.ContactsContract.CommonDataKinds.StructuredName;
@@ -185,6 +186,20 @@ public class ContactOperations {
return this; return this;
} }
/**
* Adds a group membership
*
* @param id The id of the group to assign
* @return instance of ContactOperations
*/
public ContactOperations addGroupMembership(long groupId) {
mValues.clear();
mValues.put(GroupMembership.GROUP_ROW_ID, groupId);
mValues.put(GroupMembership.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
addInsertOp();
return this;
}
public ContactOperations addAvatar(String avatarUrl) { public ContactOperations addAvatar(String avatarUrl) {
if (avatarUrl != null) { if (avatarUrl != null) {
byte[] avatarBuffer = NetworkUtilities.downloadAvatar(avatarUrl); byte[] avatarBuffer = NetworkUtilities.downloadAvatar(avatarUrl);

View File

@@ -15,6 +15,15 @@
*/ */
package com.example.android.samplesync.syncadapter; package com.example.android.samplesync.syncadapter;
import com.example.android.samplesync.Constants;
import com.example.android.samplesync.client.NetworkUtilities;
import com.example.android.samplesync.client.RawContact;
import com.example.android.samplesync.platform.ContactManager;
import org.apache.http.ParseException;
import org.apache.http.auth.AuthenticationException;
import org.json.JSONException;
import android.accounts.Account; import android.accounts.Account;
import android.accounts.AccountManager; import android.accounts.AccountManager;
import android.accounts.AuthenticatorException; import android.accounts.AuthenticatorException;
@@ -27,18 +36,7 @@ import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.example.android.samplesync.Constants;
import com.example.android.samplesync.client.NetworkUtilities;
import com.example.android.samplesync.client.RawContact;
import com.example.android.samplesync.platform.ContactManager;
import org.apache.http.ParseException;
import org.apache.http.auth.AuthenticationException;
import org.json.JSONException;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
/** /**
@@ -91,6 +89,9 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
final String authtoken = mAccountManager.blockingGetAuthToken(account, final String authtoken = mAccountManager.blockingGetAuthToken(account,
Constants.AUTHTOKEN_TYPE, NOTIFY_AUTH_FAILURE); Constants.AUTHTOKEN_TYPE, NOTIFY_AUTH_FAILURE);
// Make sure that the sample group exists
final long groupId = ContactManager.ensureSampleGroupExists(mContext, account);
// Find the local 'dirty' contacts that we need to tell the server about... // Find the local 'dirty' contacts that we need to tell the server about...
// Find the local users that need to be sync'd to the server... // Find the local users that need to be sync'd to the server...
dirtyContacts = ContactManager.getDirtyContacts(mContext, account); dirtyContacts = ContactManager.getDirtyContacts(mContext, account);
@@ -106,6 +107,7 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
long newSyncState = ContactManager.updateContacts(mContext, long newSyncState = ContactManager.updateContacts(mContext,
account.name, account.name,
updatedContacts, updatedContacts,
groupId,
lastSyncMarker); lastSyncMarker);
// This is a demo of how you can update IM-style status messages // This is a demo of how you can update IM-style status messages