SelectCalendarsSyncFragment.java revision cf7fd2b6d1b5af26c4ac422dde1778e2fd6c7ef6
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.calendar.selectcalendars; 18 19import com.android.calendar.AsyncQueryService; 20import com.android.calendar.R; 21import com.android.calendar.selectcalendars.SelectCalendarsSyncAdapter.CalendarRow; 22 23import android.accounts.Account; 24import android.app.Activity; 25import android.app.ListFragment; 26import android.app.LoaderManager; 27import android.content.ContentResolver; 28import android.content.ContentUris; 29import android.content.ContentValues; 30import android.content.CursorLoader; 31import android.content.Intent; 32import android.content.Loader; 33import android.content.res.Resources; 34import android.database.Cursor; 35import android.net.Uri; 36import android.os.Bundle; 37import android.provider.CalendarContract; 38import android.provider.CalendarContract.Calendars; 39import android.util.Log; 40import android.view.LayoutInflater; 41import android.view.View; 42import android.view.ViewGroup; 43import android.widget.Button; 44import android.widget.ListAdapter; 45import android.widget.TextView; 46 47import java.util.HashMap; 48 49public class SelectCalendarsSyncFragment extends ListFragment 50 implements View.OnClickListener, LoaderManager.LoaderCallbacks<Cursor> { 51 private static final String TAG = "SelectCalendarSync"; 52 53 private static final String COLLATE_NOCASE = " COLLATE NOCASE"; 54 private static final String SELECTION = Calendars.ACCOUNT_NAME + "=? AND " 55 + Calendars.ACCOUNT_TYPE + "=?"; 56 // is primary lets us sort the user's main calendar to the top of the list 57 private static final String IS_PRIMARY = "\"primary\""; 58 private static final String SORT_ORDER = IS_PRIMARY + " DESC," + Calendars.CALENDAR_DISPLAY_NAME 59 + COLLATE_NOCASE; 60 61 private static final String[] PROJECTION = new String[] { 62 Calendars._ID, 63 Calendars.CALENDAR_DISPLAY_NAME, 64 Calendars.CALENDAR_COLOR, 65 Calendars.SYNC_EVENTS, 66 "(" + Calendars.ACCOUNT_NAME + "=" + Calendars.OWNER_ACCOUNT + ") AS " + IS_PRIMARY, }; 67 68 private TextView mSyncStatus; 69 private Button mAccountsButton; 70 private Account mAccount; 71 private String[] mArgs = new String[2]; 72 private AsyncQueryService mService; 73 74 public SelectCalendarsSyncFragment() { 75 Log.d(TAG, "Without bundle was created"); 76 } 77 78 public SelectCalendarsSyncFragment(Bundle bundle) { 79 Log.d(TAG, "With bundle was created"); 80 mAccount = new Account(bundle.getString(Calendars.ACCOUNT_NAME), 81 bundle.getString(Calendars.ACCOUNT_TYPE)); 82 } 83 84 @Override 85 public View onCreateView( 86 LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 87 View v = inflater.inflate(R.layout.account_calendars, null); 88 mSyncStatus = (TextView) v.findViewById(R.id.account_status); 89 mSyncStatus.setVisibility(View.GONE); 90 91 mAccountsButton = (Button) v.findViewById(R.id.sync_settings); 92 mAccountsButton.setVisibility(View.GONE); 93 mAccountsButton.setOnClickListener(this); 94 95 return v; 96 } 97 98 @Override 99 public void onActivityCreated(Bundle savedInstanceState) { 100 super.onActivityCreated(savedInstanceState); 101 // Give some text to display if there is no data. In a real 102 // application this would come from a resource. 103 setEmptyText(getActivity().getText(R.string.no_syncable_calendars)); 104 // Prepare the loader. Either re-connect with an existing one, 105 // or start a new one. 106 getLoaderManager().initLoader(0, null, this); 107 } 108 109 @Override 110 public void onResume() { 111 super.onResume(); 112 if (!ContentResolver.getMasterSyncAutomatically() 113 || !ContentResolver.getSyncAutomatically(mAccount, CalendarContract.AUTHORITY)) { 114 Resources res = getActivity().getResources(); 115 mSyncStatus.setText(res.getString(R.string.acct_not_synced)); 116 mSyncStatus.setVisibility(View.VISIBLE); 117 mAccountsButton.setText(res.getString(R.string.accounts)); 118 mAccountsButton.setVisibility(View.VISIBLE); 119 } else { 120 mSyncStatus.setVisibility(View.GONE); 121 mAccountsButton.setVisibility(View.GONE); 122 } 123 } 124 125 @Override 126 public void onAttach(Activity activity) { 127 super.onAttach(activity); 128 mService = new AsyncQueryService(activity); 129 130 Bundle bundle = getArguments(); 131 if (bundle != null && bundle.containsKey(Calendars.ACCOUNT_NAME) 132 && bundle.containsKey(Calendars.ACCOUNT_TYPE)) { 133 mAccount = new Account(bundle.getString(Calendars.ACCOUNT_NAME), 134 bundle.getString(Calendars.ACCOUNT_TYPE)); 135 } 136 } 137 138 @Override 139 public void onPause() { 140 final ListAdapter listAdapter = getListAdapter(); 141 if (listAdapter != null) { 142 HashMap<Long, CalendarRow> changes = ((SelectCalendarsSyncAdapter) listAdapter) 143 .getChanges(); 144 if (changes != null && changes.size() > 0) { 145 for (CalendarRow row : changes.values()) { 146 if (row.synced == row.originalSynced) { 147 continue; 148 } 149 long id = row.id; 150 mService.cancelOperation((int) id); 151 // Use the full long id in case it makes a difference 152 Uri uri = ContentUris.withAppendedId(Calendars.CONTENT_URI, row.id); 153 ContentValues values = new ContentValues(); 154 // Toggle the current setting 155 int synced = row.synced ? 1 : 0; 156 values.put(Calendars.SYNC_EVENTS, synced); 157 values.put(Calendars.VISIBLE, synced); 158 mService.startUpdate((int) id, null, uri, values, null, null, 0); 159 } 160 changes.clear(); 161 } 162 } 163 super.onPause(); 164 } 165 166 @Override 167 public Loader<Cursor> onCreateLoader(int id, Bundle args) { 168 mArgs[0] = mAccount.name; 169 mArgs[1] = mAccount.type; 170 return new CursorLoader( 171 getActivity(), Calendars.CONTENT_URI, PROJECTION, SELECTION, mArgs, SORT_ORDER); 172 } 173 174 @Override 175 public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 176 SelectCalendarsSyncAdapter adapter = (SelectCalendarsSyncAdapter) getListAdapter(); 177 if (adapter == null) { 178 adapter = new SelectCalendarsSyncAdapter(getActivity(), data); 179 } else { 180 adapter.changeCursor(data); 181 } 182 setListAdapter(adapter); 183 getListView().setOnItemClickListener(adapter); 184 } 185 186 public void onLoaderReset(Loader<Cursor> loader) { 187 setListAdapter(null); 188 } 189 190 // Called when the Accounts button is pressed. Takes the user to the 191 // Accounts and Sync settings page. 192 @Override 193 public void onClick(View v) { 194 Intent intent = new Intent(); 195 intent.setAction("android.settings.SYNC_SETTINGS"); 196 getActivity().startActivity(intent); 197 } 198} 199