Merge "Updated the sample"
This commit is contained in:
committed by
Android (Google) Code Review
commit
2a3f7172e7
@@ -46,7 +46,7 @@
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_SYNC_SETTINGS" />
|
||||
|
||||
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="11"/>
|
||||
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="14"/>
|
||||
|
||||
<application
|
||||
android:icon="@drawable/icon"
|
||||
@@ -100,27 +100,8 @@
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".editor.ContactEditorActivity"
|
||||
android:theme="@style/ContactEditTheme"
|
||||
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>
|
||||
android:name=".activites.InviteContactActivity"
|
||||
android:theme="@android:style/Theme.Dialog">
|
||||
<!--
|
||||
We use the INVITE intent to add a raw contact to an existing contact.
|
||||
It always comes with a lookup URI.
|
||||
@@ -132,5 +113,50 @@
|
||||
android:mimeType="vnd.android.cursor.item/contact" />
|
||||
</intent-filter>
|
||||
</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>
|
||||
</manifest>
|
||||
|
||||
@@ -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 |
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -18,19 +18,15 @@
|
||||
-->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<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>
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:text="@string/invite_contact_description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
<TextView
|
||||
android:id="@+id/invite_contact_uri"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
@@ -55,7 +55,8 @@
|
||||
android:scrollHorizontally="true"
|
||||
android:capitalize="none"
|
||||
android:autoText="false"
|
||||
android:inputType="textEmailAddress" />
|
||||
android:inputType="textEmailAddress"
|
||||
android:text="user" />
|
||||
<TextView
|
||||
android:id="@+id/username_fixed"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
@@ -81,7 +82,8 @@
|
||||
android:capitalize="none"
|
||||
android:autoText="false"
|
||||
android:password="true"
|
||||
android:inputType="textPassword" />
|
||||
android:inputType="textPassword"
|
||||
android:text="test" />
|
||||
<TextView
|
||||
android:id="@+id/message_bottom"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
|
||||
32
samples/SampleSyncAdapter/res/layout/view_group_activity.xml
Normal file
32
samples/SampleSyncAdapter/res/layout/view_group_activity.xml
Normal 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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -109,4 +109,34 @@
|
||||
<!-- The label of the button to add contact to this contact provider -->
|
||||
<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>
|
||||
@@ -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>
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
<ContactsAccountType
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
editContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
|
||||
createContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
|
||||
>
|
||||
|
||||
<ContactsDataKind
|
||||
|
||||
@@ -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
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
editContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
|
||||
createContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
|
||||
inviteContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
|
||||
inviteContactActivity="com.example.android.samplesync.activities.InviteContactActivity"
|
||||
inviteContactActionLabel="@string/invite_action_label"
|
||||
viewContactNotifyService="com.example.android.samplesync.notifier.NotifierService"
|
||||
viewGroupActivity="com.example.android.samplesync.viewer.ViewGroupActivity"
|
||||
viewStreamItemActivity="com.example.android.samplesync.viewer.ViewStreamItemActivity"
|
||||
viewStreamItemPhotoActivity="com.example.android.samplesync.viewer.ViewStreamItemPhotoActivity"
|
||||
viewGroupActivity="com.example.android.samplesync.activities.ViewGroupActivity"
|
||||
viewGroupActionLabel="@string/view_group_action_label"
|
||||
viewStreamItemActivity="com.example.android.samplesync.activities.ViewStreamItemActivity"
|
||||
viewStreamItemPhotoActivity="com.example.android.samplesync.activities.ViewStreamItemPhotoActivity"
|
||||
>
|
||||
|
||||
<ContactsDataKind
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
<ContactsSource
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
editContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
|
||||
createContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
|
||||
>
|
||||
|
||||
<ContactsDataKind
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -110,7 +110,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity {
|
||||
mMessage = (TextView) findViewById(R.id.message);
|
||||
mUsernameEdit = (EditText) findViewById(R.id.username_edit);
|
||||
mPasswordEdit = (EditText) findViewById(R.id.password_edit);
|
||||
mUsernameEdit.setText(mUsername);
|
||||
if (!TextUtils.isEmpty(mUsername)) mUsernameEdit.setText(mUsername);
|
||||
mMessage.setText(getMessage());
|
||||
}
|
||||
|
||||
|
||||
@@ -16,16 +16,6 @@
|
||||
|
||||
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.HttpResponse;
|
||||
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.HttpParams;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONArray;
|
||||
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.ByteArrayOutputStream;
|
||||
@@ -54,11 +50,8 @@ import java.io.UnsupportedEncodingException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* Provides utility methods for communicating with the server.
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,7 @@ import android.provider.ContactsContract.CommonDataKinds.Photo;
|
||||
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
|
||||
import android.provider.ContactsContract.Contacts;
|
||||
import android.provider.ContactsContract.Data;
|
||||
import android.provider.ContactsContract.Groups;
|
||||
import android.provider.ContactsContract.RawContacts;
|
||||
import android.provider.ContactsContract.Settings;
|
||||
import android.provider.ContactsContract.StatusUpdates;
|
||||
@@ -54,6 +55,41 @@ public class 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
|
||||
* contacts database. Typically this list of contacts would have been
|
||||
@@ -67,7 +103,7 @@ public class ContactManager {
|
||||
* sync request.
|
||||
*/
|
||||
public static synchronized long updateContacts(Context context, String account,
|
||||
List<RawContact> rawContacts, long lastSyncMarker) {
|
||||
List<RawContact> rawContacts, long groupId, long lastSyncMarker) {
|
||||
|
||||
long currentSyncMarker = lastSyncMarker;
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
@@ -112,7 +148,7 @@ public class ContactManager {
|
||||
Log.d(TAG, "In addContact");
|
||||
if (!rawContact.isDeleted()) {
|
||||
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,
|
||||
@@ -235,12 +271,13 @@ public class ContactManager {
|
||||
* @param context the Authenticator Activity context
|
||||
* @param accountName the account the contact belongs to
|
||||
* @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 batchOperation allow us to batch together multiple operations
|
||||
* into a single provider call
|
||||
*/
|
||||
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
|
||||
final ContactOperations contactOp = ContactOperations.createNewContact(
|
||||
@@ -252,6 +289,7 @@ public class ContactManager {
|
||||
.addPhone(rawContact.getCellPhone(), Phone.TYPE_MOBILE)
|
||||
.addPhone(rawContact.getHomePhone(), Phone.TYPE_HOME)
|
||||
.addPhone(rawContact.getOfficePhone(), Phone.TYPE_WORK)
|
||||
.addGroupMembership(groupId)
|
||||
.addAvatar(rawContact.getAvatarUrl());
|
||||
|
||||
// If we have a serverId, then go ahead and create our status profile.
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Email;
|
||||
import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Photo;
|
||||
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
|
||||
@@ -185,6 +186,20 @@ public class ContactOperations {
|
||||
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) {
|
||||
if (avatarUrl != null) {
|
||||
byte[] avatarBuffer = NetworkUtilities.downloadAvatar(avatarUrl);
|
||||
|
||||
@@ -15,6 +15,15 @@
|
||||
*/
|
||||
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.AccountManager;
|
||||
import android.accounts.AuthenticatorException;
|
||||
@@ -27,18 +36,7 @@ import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
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.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -91,6 +89,9 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
|
||||
final String authtoken = mAccountManager.blockingGetAuthToken(account,
|
||||
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 users that need to be sync'd to the server...
|
||||
dirtyContacts = ContactManager.getDirtyContacts(mContext, account);
|
||||
@@ -106,6 +107,7 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
|
||||
long newSyncState = ContactManager.updateContacts(mContext,
|
||||
account.name,
|
||||
updatedContacts,
|
||||
groupId,
|
||||
lastSyncMarker);
|
||||
|
||||
// This is a demo of how you can update IM-style status messages
|
||||
|
||||
Reference in New Issue
Block a user