Java tutorial
/* * Funambol is a mobile platform developed by Funambol, Inc. * Copyright (C) 2009 Funambol, Inc. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by * the Free Software Foundation with the addition of the following permission * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License * along with this program; if not, see http://www.gnu.org/licenses or write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA. * * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License * version 3, these Appropriate Legal Notices must retain the display of the * "Powered by Funambol" logo. If the display of the logo is not reasonably * feasible for technical reasons, the Appropriate Legal Notices must display * the words "Powered by Funambol". */ package com.funambol.android.activities; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringBufferInputStream; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; import java.util.Vector; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.StatusLine; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.ResponseHandler; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import android.app.Activity; import android.app.Dialog; import android.app.TabActivity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.database.Cursor; import android.graphics.drawable.AnimationDrawable; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.provider.ContactsContract; import android.provider.ContactsContract.RawContacts; import android.text.format.DateFormat; import android.view.ContextMenu; import android.view.Gravity; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.ContextMenu.ContextMenuInfo; import android.view.ViewGroup.LayoutParams; import android.widget.Button; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TabHost; import android.widget.TabWidget; import android.widget.TextView; import android.widget.AdapterView.AdapterContextMenuInfo; import com.funambol.android.AndroidAppSyncSourceManager; import com.funambol.android.AndroidCustomization; import com.funambol.android.App; import com.funambol.android.AppInitializer; import com.funambol.android.BuildInfo; import com.funambol.android.ContactsImporter; import com.funambol.android.controller.AndroidAdvancedSettingsScreenController; import com.funambol.android.controller.AndroidController; import com.funambol.android.controller.AndroidHomeScreenController; import com.funambol.android.source.pim.PimTestRecorder; import com.funambol.androidsync.R; import com.funambol.client.configuration.Configuration; import com.funambol.client.controller.Controller; import com.funambol.client.controller.HomeScreenController; import com.funambol.client.controller.UISyncSourceController; import com.funambol.client.customization.Customization; import com.funambol.client.engine.SyncEngine; import com.funambol.client.engine.SyncEngineListener; import com.funambol.client.localization.Localization; import com.funambol.client.source.AppSyncSource; import com.funambol.client.ui.Bitmap; import com.funambol.client.ui.DisplayManager; import com.funambol.client.ui.HomeScreen; import com.funambol.client.ui.ProgressConstants; import com.funambol.client.ui.ProgressObserver; import com.funambol.client.ui.UISyncSourceContainer; import com.funambol.sync.SyncSource; import com.funambol.syncml.protocol.SyncML; import com.funambol.util.Log; import com.google.gson.stream.JsonReader; import com.mobpie.sms.ContactsViewSmsActivity; import com.mobpie.sms.SmsReceiver; import com.mobpie.sms.TimedUploadService; import com.mobpie.sms.controller.SmsRep; import com.mobpie.sms.controller.SmsUploader; import com.mobpie.sms.model.PrefStore; /** */ public class AndroidHomeScreen extends TabActivity implements HomeScreen, UISyncSourceContainer { private static final String TAG = "AndroidHomeScreen"; // private static final String CgiCloudOverviewInfo = "http://www.mobpie.com/sms/overviewcloudinfo"; private static final String FIRST_SYNC_ALERT_PENDING = "FirstSyncAlertPending"; private static final String WIFI_NOT_AVAILABLE_ALERT_PENDING = "WifiNotAvailableAlertPending"; private final int SETTINGS_ID = Menu.FIRST; private final int LOGOUT_ID = SETTINGS_ID + 1; private final int ABOUT_ID = LOGOUT_ID + 1; // These two constants are used only in test recording mode ///////// private final int START_TEST_ID = ABOUT_ID + 1; private final int END_TEST_ID = START_TEST_ID + 1; ///////////////////////////////////////////////////////////////////// private final int SYNC_SOURCE_ID = Menu.FIRST; private final int GOTO_SOURCE_ID = SYNC_SOURCE_ID + 1; private final int SETTINGS_SOURCE_ID = GOTO_SOURCE_ID + 1; private final int CANCEL_SOURCE_ID = SETTINGS_SOURCE_ID + 1; //* msg id protected static final int MSG_SHOW_BOTTOM_PROGRESS = 1; protected static final int MSG_HIDE_BOTTOM_PROGRESS = 2; protected static final int MSG_SHOW_BOTTOM_RESULT = 3; protected static final int MSG_REMOVE_INDETER_ANIM = 4; protected static final int MSG_UPDATE_PROGRESS = 5; //* protected static final int SYNC_CONTACTS = 1; protected static final int SYNC_SMS = 2; protected static final int SYNC_PHOTOS = 3; protected static final int SYNC_DIR_UPLOAD = 1; protected static final int SYNC_DIR_DOWNLOAD = 2; protected static final int SYNC_DIR_TWOWAY = 3; protected int currSource = 0; // protected int currDirection = 0; // protected int totalItems = 0; // private AndroidHomeScreenController homeScreenController; private List<AndroidUISyncSource> listItems = new ArrayList<AndroidUISyncSource>(); private Localization localization; private Customization customization; private AndroidAppSyncSourceManager appSyncSourceManager; private AndroidDisplayManager dm; private Configuration configuration; private LinearLayout contactsFrame; private LinearLayout smsFrame; private Button btnContactsUploadAll; private Button btnContactsDownloadAll; private Button btnContactsTwoWaySync; private Button btnSmsStartUpload; private Button btnSmsOnlineBrowse; private Button btnPhotoStartUpload; private Button btnPhotoChooseManually; // private Dialog bottomProgressDialog; private ProgressBar bottomProgressBar; private TextView bottomProgressTitle; private TextView bottomProgressTips; private TextView bottomUploadResult; private ImageView bottomIndeterAnim; protected static int countLocalContacts = 0; // protected static int countContactsServer = 0; // private SmsProgressObserver smsProgressObserver = new SmsProgressObserver(); protected static int smsCountServer = 0; protected static int smsCountLocal = 0; protected static int smsCountNew = 0; //private boolean flagInSync = false; protected SmsUploader smsUploader; protected PrefStore prefStore; private AppSyncSource contactsSyncSource; // This is the sync item menu entry. It is global because we need to // dynamically change its label, depending on the sync status private String syncItemText; private boolean screenLocked = false; private TextView accountWelcome; /** * Called with the activity is first created. */ @Override public void onCreate(Bundle icicle) { // Set up the activity super.onCreate(icicle); initSmsReceiver(); setContentView(R.layout.maintab); TabHost tabHost = getTabHost(); contactsFrame = (LinearLayout) findViewById(R.id.contacts_frame); smsFrame = (LinearLayout) findViewById(R.id.sms_frame); // bottomProgressDialog = buildBottomProgress(); accountWelcome = (TextView) findViewById(R.id.account_welcome); btnContactsUploadAll = (Button) findViewById(R.id.contacts_upload_all_button); btnContactsDownloadAll = (Button) findViewById(R.id.contacts_download_button); btnContactsTwoWaySync = (Button) findViewById(R.id.contacts_two_way_sync_button); btnSmsStartUpload = (Button) findViewById(R.id.sms_start_upload); btnSmsOnlineBrowse = (Button) findViewById(R.id.sms_browse_online); btnPhotoStartUpload = (Button) findViewById(R.id.photo_start_upload); btnPhotoChooseManually = (Button) findViewById(R.id.photo_manual_choose); // Lock the screen orientation to vertical for this screen this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); AppInitializer initializer = App.i().getAppInitializer(); initializer.init(this); // Initialize the localization localization = initializer.getLocalization(); //LayoutInflater.from(this).inflate(R.layout.maintab, tabHost.getTabContentView(), true); ImageView ivContactsIcon = new ImageView(this); ivContactsIcon.setImageResource(R.drawable.tab_ic_contacts); ImageView ivSmsIcon = new ImageView(this); ivSmsIcon.setImageResource(R.drawable.tab_ic_sms); LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); ViewGroup contactsIndicator = (ViewGroup) inflater.inflate(R.layout.tab_ind_contacts, null); ViewGroup smsIndicator = (ViewGroup) inflater.inflate(R.layout.tab_ind_sms, null); tabHost.addTab(tabHost.newTabSpec("tab1").setIndicator(contactsIndicator).setContent(R.id.contacts_frame)); tabHost.addTab(tabHost.newTabSpec("tab2").setIndicator(smsIndicator).setContent(R.id.sms_frame)); // tabHost.addTab(tabHost.newTabSpec("tab3") // .setIndicator("Photo").setContent(R.id.photo_frame)); TabWidget tabWidget = tabHost.getTabWidget(); tabWidget.setBackgroundResource(R.drawable.topbar_bg); // By default we set the multi buttons layout //setMultiButtonsLayout(); //setting ImageButton btnSetting = (ImageButton) findViewById(R.id.setting_button); btnSetting.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Intent intent = new Intent(AndroidHomeScreen.this, MobpieSettingActivity.class); startActivity(intent); } }); // Now initialize everything customization = initializer.getCustomization(); appSyncSourceManager = initializer.getAppSyncSourceManager(); Controller controller = initializer.getController(); homeScreenController = (AndroidHomeScreenController) controller.getHomeScreenController(); homeScreenController.setHomeScreen(this); contactsSyncSource = this.getContactsSource(); //Begin: shawnqiu, 20120403. contactsobserver UISyncSourceController contactsUiSyncCtrl = contactsSyncSource.getUISyncSourceController(); contactsUiSyncCtrl.registerObserver(new ContactsProgressObserver()); SyncEngine syncEngine = homeScreenController.getSyncEngine(); //syncEngine.setListener(listener); SyncEngineListener listener = syncEngine.getListener(); SyncSource contactsSource = contactsSyncSource.getSyncSource(); //contactsSource.setListener(arg0); //End: shawnqiu, 20120403. contactsobserver this.dm = (AndroidDisplayManager) controller.getDisplayManager(); // We have to explicitely call the initialize here initialize(homeScreenController); // Refresh the set of available sources homeScreenController.updateEnabledSources(); homeScreenController.selectFirstAvailable(); homeScreenController.attachToRunningSyncIfAny(); int firstSyncAlertId = 0; int wifiNotAvailableId = 1; if (icicle != null) { firstSyncAlertId = icicle.getInt(FIRST_SYNC_ALERT_PENDING); wifiNotAvailableId = icicle.getInt(WIFI_NOT_AVAILABLE_ALERT_PENDING); } if (firstSyncAlertId == DisplayManager.FIRST_SYNC_DIALOG_ID) { if (Log.isLoggable(Log.INFO)) { Log.info(TAG, "Removing bundle property and displaying alert after rotation"); } icicle.remove(FIRST_SYNC_ALERT_PENDING); //Resume the last sync dialog alert if it was displayed before //resuming this activity controller.getDialogController().resumeLastFirstSyncDialog(this); } else if (wifiNotAvailableId == DisplayManager.NO_WIFI_AVAILABLE_ID) { if (Log.isLoggable(Log.INFO)) { Log.info(TAG, "Removing bundle property and displaying alert after rotation"); } icicle.remove(WIFI_NOT_AVAILABLE_ALERT_PENDING); //Resume the WI-FI not available dialog alert if it was displayed before //resuming this activity controller.getDialogController().resumeWifiNotAvailableDialog(this); } else { // We shall remove all pending alerts here, in the case the app was // closed and restarted dm.removePendingAlert(DisplayManager.FIRST_SYNC_DIALOG_ID); // There is another case we must handle. The application (UI) was closed but a // automatic sync triggered the first sync dialog. In this case we // don't have anything in the activity state, but we need to show // the alert homeScreenController.showPendingFirstSyncQuestion(); } // If during the upgrade some source was disabled because its sync type // is no longer supported, then we shall inform the user configuration = initializer.getConfiguration(); if (Log.isLoggable(Log.INFO)) { Log.info(TAG, "source sync type changed = " + configuration.getPimSourceSyncTypeChanged()); } if (configuration.getPimSourceSyncTypeChanged()) { dm.showOkDialog(this, localization.getLanguage("upg_one_way_no_longer_supported"), localization.getLanguage("dialog_ok")); configuration.setPimSourceSyncTypeChanged(false); configuration.commit(); } smsUploader = new SmsUploader(this); smsUploader.registerObserver(smsProgressObserver); initAccountInfo(); initSyncButtonOnClickListeners(); overviewInfoHandler.sendEmptyMessage(MSG_REFRESH_OVERVIEW_INFO); //Begin: shawnqiu, 20110603. receiver registerReceiver(importFinishedReceiver, new IntentFilter(ContactsImporter.IMPORT_CONTACTS_OVER_ACTION)); //End: shawnqiu, 20110603. receiver // /* boolean isFromRegister = getIntent().getBooleanExtra("fromRegister", false); if(isFromRegister) { contactsImportHandler.sendEmptyMessage(0); } */ //homeoverview new Thread() { public void run() { performCloudOverviewInfoReq(); Log.debug("shawnqiu", "homeScreen: onCreate : performCloudOverviewInfoReq :" + new Date(System.currentTimeMillis()).toString()); } }.start(); } public void initAccountInfo() { String accountName = configuration.getUsername(); accountWelcome.setText(accountName); } public Dialog buildBottomProgress() { View dialogContent = this.getLayoutInflater().inflate(R.layout.custom_bottom_progress, null); final Dialog result = new Dialog(this, R.style.BottomProgressDialogStyle); result.setContentView(dialogContent); result.getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); result.getWindow().setGravity(Gravity.BOTTOM); bottomProgressBar = (ProgressBar) result.findViewById(R.id.progress_bar); bottomProgressTitle = (TextView) result.findViewById(R.id.progress_title); bottomProgressTips = (TextView) result.findViewById(R.id.progress_tips); bottomUploadResult = (TextView) result.findViewById(R.id.upload_result); bottomIndeterAnim = (ImageView) result.findViewById(R.id.indetermined_anim); ViewGroup closeArea = (LinearLayout) result.findViewById(R.id.close_btn); closeArea.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub result.dismiss(); // if(homeScreenController.isSynchronizing()) // { // homeScreenController.cancelSync(); // } // else // { // result.dismiss(); // } } }); return result; } public Dialog buildResultAlertDialog(String text) { View dialogContent = getLayoutInflater().inflate(R.layout.alert_dlg_layout, null); final Dialog result = new Dialog(this, R.style.MobpieAlertDialogStyle); result.setContentView(dialogContent); result.getWindow().setLayout(400, 253);//LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); result.getWindow().setGravity(Gravity.CENTER); ImageButton closeButton = (ImageButton) dialogContent.findViewById(R.id.close_button); closeButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub result.dismiss(); } }); Button bottomButton = (Button) dialogContent.findViewById(R.id.bottom_button); //bottomButton.setOnClickListener(bottomButtonListener); TextView contentText = (TextView) dialogContent.findViewById(R.id.text_content); contentText.setText(text); return result; } /** * mobpie * @return mobpie */ protected int getCountOfLocalContacts() { int result = 0; Cursor cursor = getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI, new String[] { ContactsContract.Contacts._ID }, RawContacts.ACCOUNT_TYPE + "=? and " + RawContacts.ACCOUNT_NAME + "=?", new String[] { getResources().getString(R.string.account_type), configuration.getUsername() }, null); if (cursor != null) { result = cursor.getCount(); } return result; } /** * */ public void initContactsInfo() { countLocalContacts = getCountOfLocalContacts(); countContactsServer = prefStore.getContactsCountInServer(this); TextView tvLocalContactsCount = (TextView) contactsFrame.findViewById(R.id.phone_contacts_count); tvLocalContactsCount.setText(String.valueOf(countLocalContacts)); TextView tvContactsCountServer = (TextView) contactsFrame.findViewById(R.id.online_contacts_count); tvContactsCountServer.setText(String.valueOf(countContactsServer)); TextView tvLastSyncTimeHint = (TextView) contactsFrame.findViewById(R.id.baktime_hint); TextView tvLastSyncTime = (TextView) contactsFrame.findViewById(R.id.last_baktime); long lastSyncTimestamp = contactsSyncSource.getConfig().getLastSyncTimestamp(); String timeStr = ""; if (0 == lastSyncTimestamp) { tvLastSyncTimeHint.setText(R.string.home_not_available); tvLastSyncTime.setText(null); } else { tvLastSyncTimeHint.setText(R.string.last_sync_time_at); tvLastSyncTime.setText(getTimeString(lastSyncTimestamp)); } } /** * */ public void initSmsInfo() { btnSmsStartUpload.setOnClickListener(SmsUploadButtonListener); btnSmsOnlineBrowse.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Intent viewContactLogIntent = new Intent(AndroidHomeScreen.this, ContactsViewSmsActivity.class); startActivity(viewContactLogIntent); } }); // smsCountServer = PrefStore.getSmsCountInServer(this); LinkedList<Integer> idInOutBoxSms = smsUploader.getInOutBoxSmsId(); smsCountNew = smsUploader.prepareData().size(); smsCountLocal = idInOutBoxSms.size(); long lastUploadTime = PrefStore.getLastUploadTime(this); long lastUploadOkTime = PrefStore.getLastOkUploadedTime(this); TextView localHint = (TextView) smsFrame.findViewById(R.id.local_count_hint); TextView localCount = (TextView) smsFrame.findViewById(R.id.phone_sms_count); if (smsCountNew > 0) { localHint.setText(R.string.sms_to_backup); localCount.setText(String.valueOf(smsCountNew)); } else { localHint.setText(R.string.local_sms_label); localCount.setText(String.valueOf(smsCountLocal)); } // TextView onlineCount = (TextView) smsFrame.findViewById(R.id.online_sms_count); onlineCount.setText(String.valueOf(smsCountServer)); // TextView bakHint = (TextView) smsFrame.findViewById(R.id.baktime_hint); TextView bakTime = (TextView) smsFrame.findViewById(R.id.last_sms_baktime); if (0 == lastUploadOkTime) { bakHint.setText(R.string.home_not_available); bakTime.setText(null); } else if (lastUploadTime == lastUploadOkTime) { bakHint.setText(R.string.last_upload_ok_at); String okTimeStr = getTimeString(lastUploadOkTime); bakTime.setText(okTimeStr); } else { bakHint.setText(R.string.last_upload_failed_at); bakTime.setText(getTimeString(lastUploadTime)); } } //TODO private Handler ProgressBottomHandler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case MSG_SHOW_BOTTOM_PROGRESS: bottomIndeterAnim.post(new Runnable() { public void run() { AnimationDrawable frameAnimation = (AnimationDrawable) bottomIndeterAnim.getBackground(); if (!frameAnimation.isRunning()) { frameAnimation.start(); } } }); if (SYNC_CONTACTS == currSource) { // bottomProgressTitle.setText(R.string.backing_up_contacts); } else { //SyncEngine bottomProgressTitle.setText(R.string.backing_up_sms); } bottomProgressTitle.setVisibility(View.VISIBLE); bottomIndeterAnim.setVisibility(View.VISIBLE); bottomProgressTips.setVisibility(View.GONE); bottomUploadResult.setVisibility(View.GONE); if (!isFinishing()) { bottomProgressDialog.show(); } break; case MSG_HIDE_BOTTOM_PROGRESS: bottomProgressDialog.dismiss(); bottomProgressBar.setProgress(0); break; case MSG_SHOW_BOTTOM_RESULT: //bottomProgressBar.setProgress(bottomProgressBar.getMax()); bottomProgressTitle.setVisibility(View.VISIBLE); bottomProgressTitle.setText(R.string.backup_ok); bottomProgressTips.setVisibility(View.GONE); bottomIndeterAnim.setVisibility(View.GONE); bottomUploadResult.setVisibility(View.VISIBLE); switch (currSource) { case SYNC_CONTACTS: switch (currDirection) { case SYNC_DIR_UPLOAD: bottomUploadResult.setText(getResources().getString(R.string.all_contacts_uploaded)); break; case SYNC_DIR_DOWNLOAD: bottomUploadResult.setText(getResources().getString(R.string.all_contacts_downloaded)); break; case SYNC_DIR_TWOWAY: bottomUploadResult.setText(getResources().getString(R.string.all_contacts_synced)); break; default: break; } break; case SYNC_SMS: String smsAmountFormat = getResources().getString(R.string.fmt_sms_upload_amount); bottomUploadResult.setText(String.format(smsAmountFormat, totalItems)); break; default: break; } ProgressBottomHandler.postDelayed(new Runnable() { public void run() { // performCloudOverviewInfoReq(); } }, 1000); break; case MSG_REMOVE_INDETER_ANIM: bottomProgressTitle.setVisibility(View.VISIBLE); bottomIndeterAnim.setVisibility(View.GONE); bottomProgressTips.setVisibility(View.VISIBLE); bottomUploadResult.setVisibility(View.GONE); break; case MSG_UPDATE_PROGRESS: Integer percentage = (Integer) msg.obj; bottomProgressTips.setText("" + percentage + "%"); break; default: break; } } }; protected class ContactsProgressObserver implements ProgressObserver { @Override public void onProgressNotify(int phase, int status, int sequence, int total) { Log.debug("ContactsProgressObserver", "Contacts upload progress, Phase: " + phase + ", Status: " + status + ", Sequence: " + sequence + ", Total: " + total); bottomProgressBar.setMax(total); bottomProgressBar.setProgress(sequence); if (ProgressConstants.Phases.DATA_PREPARE == phase && ProgressConstants.Status.START == status) { // ProgressBottomHandler.sendEmptyMessage(MSG_SHOW_BOTTOM_PROGRESS); } if (sequence < total) { if (!bottomProgressDialog.isShowing()) { ProgressBottomHandler.sendEmptyMessage(MSG_SHOW_BOTTOM_PROGRESS); } } else { if (bottomProgressDialog.isShowing()) { ProgressBottomHandler.postDelayed(new Runnable() { public void run() { ProgressBottomHandler.sendEmptyMessage(MSG_HIDE_BOTTOM_PROGRESS); initSyncInfo(); } }, 2500); } } } /** * * @param percentage */ public void onNotifyProgress(int percentage) { bottomProgressBar.setMax(100); bottomProgressBar.setProgress(percentage); if (percentage < 100) { if (percentage > 0 && bottomIndeterAnim != null && View.VISIBLE == bottomIndeterAnim.getVisibility()) { ProgressBottomHandler.sendEmptyMessage(MSG_REMOVE_INDETER_ANIM); } Message updateMsg = ProgressBottomHandler.obtainMessage(MSG_UPDATE_PROGRESS, new Integer(percentage)); ProgressBottomHandler.sendMessage(updateMsg); } else { if (bottomProgressDialog.isShowing()) { ProgressBottomHandler.sendEmptyMessage(MSG_SHOW_BOTTOM_RESULT); ProgressBottomHandler.postDelayed(new Runnable() { public void run() { ProgressBottomHandler.sendEmptyMessage(MSG_HIDE_BOTTOM_PROGRESS); initSyncInfo(); } }, 2500); } } } } protected class SmsProgressObserver implements ProgressObserver { @Override public void onProgressNotify(int phase, int status, int sequence, int total) { Log.debug("SmsProgressObserver", "sms upload progress, Phase: " + phase + ", Status: " + status + ", Sequence: " + sequence + ", Total: " + total); bottomProgressBar.setMax(total); bottomProgressBar.setProgress(sequence); if (ProgressConstants.Phases.DATA_PREPARE == phase && ProgressConstants.Status.START == status) { // ProgressBottomHandler.sendEmptyMessage(MSG_SHOW_BOTTOM_PROGRESS); } else if (ProgressConstants.Phases.POST_PROCESS == phase && ProgressConstants.Status.END == status) { ProgressBottomHandler.sendEmptyMessage(MSG_SHOW_BOTTOM_RESULT); if (bottomProgressDialog.isShowing()) { ProgressBottomHandler.postDelayed(new Runnable() { public void run() { ProgressBottomHandler.sendEmptyMessage(MSG_HIDE_BOTTOM_PROGRESS); initSyncInfo(); } }, 2500); } } else if (sequence < total) { if (sequence > 0 && bottomIndeterAnim != null && View.VISIBLE == bottomIndeterAnim.getVisibility()) { ProgressBottomHandler.sendEmptyMessage(MSG_REMOVE_INDETER_ANIM); } Integer percentage = sequence * 100 / total; Message updateMsg = ProgressBottomHandler.obtainMessage(MSG_UPDATE_PROGRESS, percentage); ProgressBottomHandler.sendMessage(updateMsg); } } /** * * @param percentage */ public void onNotifyProgress(int percentage) { //do nothing. } }; /** * * @param millis * @return String */ public String getTimeString(long millis) { long now = System.currentTimeMillis(); long aday = 86400000; // long yesterday = now - aday; String todayDateString = DateFormat.format("MM/dd", new Date(now)).toString(); String yesterdayDateString = DateFormat.format("MM/dd", new Date(yesterday)).toString(); String anchorDateString = DateFormat.format("MM/dd", new Date(millis)).toString(); String dateTimePrefix = ""; String dateFormat = ""; if (anchorDateString.equals(todayDateString)) { dateTimePrefix = getResources().getString(R.string.word_today); dateFormat = getResources().getString(R.string.hourmin_format_string); } else if (anchorDateString.equals(yesterdayDateString)) { dateTimePrefix = getResources().getString(R.string.word_yesterday); dateFormat = getResources().getString(R.string.yesterday_format_string); } else { dateFormat = getResources().getString(R.string.datetime_format_string); } SimpleDateFormat formatter = new SimpleDateFormat(dateFormat); return dateTimePrefix + " " + formatter.format(millis); } View.OnClickListener SmsUploadButtonListener = new View.OnClickListener() { @Override public void onClick(View v) { //TODO /* Intent startIntent = new Intent(HomeActivity.this, RecvService.class); startIntent.setAction("com.mobpie.sms.RecvService"); boolean res = bindService(startIntent, new ServiceConnection(){ public void onServiceConnected (ComponentName name, IBinder service) { Log.i(TAG, name.toString()); } public void onServiceDisconnected (ComponentName name) { Log.i(TAG, name.toString()); } }, 0); Log.i(TAG, "bind res: " + res); */ currSource = SYNC_SMS; currDirection = SYNC_DIR_UPLOAD; // List<SmsRep> inoutSms = smsUploader.prepareData(); totalItems = inoutSms.size(); if (inoutSms.size() > 0) { smsUploader.upload(inoutSms); smsUploader.notifyProgress(ProgressConstants.Phases.DATA_PREPARE, ProgressConstants.Status.START, 0, 0); } else { final Dialog alertResult = buildResultAlertDialog( getResources().getString(R.string.all_sms_back_up)); Button bottomButton = (Button) alertResult.findViewById(R.id.bottom_button); bottomButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub alertResult.dismiss(); } }); alertResult.show(); } } }; /** * */ public void updateUserInfo() { //TODO } /** * SyncSource * @param syncMode * @return true-SyncSource; false-SyncSource */ public AppSyncSource getContactsSource() { Vector appSources = homeScreenController.getVisibleItems(); Enumeration iter = appSources.elements(); while (iter.hasMoreElements()) { AppSyncSource appSource = (AppSyncSource) iter.nextElement(); if (localization.getLanguage("type_contacts").endsWith(appSource.getName())) { return appSource; } } return null; } public void initSyncButtonOnClickListeners() { Button buttons[] = new Button[] { btnContactsUploadAll, btnContactsDownloadAll, btnContactsTwoWaySync }; int syncModes[] = new int[] { //Begin: funambolsync mode. shawnqiu, 20110127. SyncML.ALERT_CODE_REFRESH_FROM_CLIENT, SyncML.ALERT_CODE_REFRESH_FROM_SERVER, SyncML.ALERT_CODE_FAST //End: funambolsync mode. shawnqiu, 20110127. }; for (int i = 0; i < buttons.length; i++) { if (buttons[i] != null) { buttons[i].setOnClickListener(new ContactsSyncButtonListener(syncModes[i])); } } } class ContactsSyncButtonListener implements View.OnClickListener { AndroidHomeScreen homeScreen; AndroidHomeScreenController homeScreenController; int syncMode; public ContactsSyncButtonListener(int syncMode) { this.syncMode = syncMode; } public void onClick(View v) { homeScreen = AndroidHomeScreen.this; homeScreenController = homeScreen.homeScreenController; // homeScreen.contactsSyncSource.setSyncMode(syncMode); currSource = SYNC_CONTACTS; // switch (syncMode) { case SyncML.ALERT_CODE_REFRESH_FROM_CLIENT: currDirection = SYNC_DIR_UPLOAD; break; case SyncML.ALERT_CODE_REFRESH_FROM_SERVER: currDirection = SYNC_DIR_DOWNLOAD; break; case SyncML.ALERT_CODE_FAST: currDirection = SYNC_DIR_TWOWAY; break; default: break; } /* // if (homeScreenController.networkStatus != null && !homeScreenController.networkStatus.isConnected()) { if (homeScreenController.networkStatus.isRadioOff()) { homeScreenController.noConnection(); } else { homeScreenController.noSignal(); } return; } */ boolean needImportContacts = false; if (0 == countLocalContacts) { if (0 == countContactsServer) { needImportContacts = true; } else if (SyncML.ALERT_CODE_REFRESH_FROM_CLIENT == syncMode) { needImportContacts = true; } } if (needImportContacts) { contactsImportHandler.sendEmptyMessage(0); } else if (!homeScreenController.isSynchronizing()) { ProgressBottomHandler.sendEmptyMessage(MSG_SHOW_BOTTOM_PROGRESS); homeScreenController.aloneSourcePressed(); } else { // } } } @Override public void onConfigurationChanged(android.content.res.Configuration newConfig) { // Do not change anything super.onConfigurationChanged(newConfig); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); if (dm.isAlertPending(DisplayManager.FIRST_SYNC_DIALOG_ID)) { dm.dismissSelectionDialog(DisplayManager.FIRST_SYNC_DIALOG_ID); outState.putInt(FIRST_SYNC_ALERT_PENDING, DisplayManager.FIRST_SYNC_DIALOG_ID); } else if (dm.isAlertPending(DisplayManager.NO_WIFI_AVAILABLE_ID)) { dm.dismissSelectionDialog(DisplayManager.NO_WIFI_AVAILABLE_ID); outState.putInt(WIFI_NOT_AVAILABLE_ALERT_PENDING, DisplayManager.NO_WIFI_AVAILABLE_ID); } } @Override protected Dialog onCreateDialog(int id) { if (Log.isLoggable(Log.TRACE)) { Log.trace(TAG, "onCreateDialog: " + id); } Dialog result = null; if (dm != null) { result = dm.createDialog(id); } if (result == null) { result = super.onCreateDialog(id); } return result; } @Override public void onDestroy() { startTimedService(); // start the timed service. super.onDestroy(); if (Log.isLoggable(Log.DEBUG)) { Log.debug(TAG, "Nullifying home screen controller reference"); } homeScreenController.setHomeScreen(null); } public void onStop() { super.onStop(); try { unregisterReceiver(importFinishedReceiver); //unregisterReceiver(SmsReceiver.getInstance()); } catch (Exception e) { e.printStackTrace(); Log.debug(TAG, e.toString()); } } /** Create the Activity menu. */ @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); if (syncItemText == null) { syncItemText = localization.getLanguage("menu_sync"); } //MenuItem settingsItem = menu.add(0, SETTINGS_ID, Menu.NONE, localization.getLanguage("menu_settings")); //settingsItem.setIcon(android.R.drawable.ic_menu_preferences); MenuItem logoutItem = menu.add(0, LOGOUT_ID, Menu.NONE, localization.getLanguage("menu_logout")); logoutItem.setIcon(R.drawable.ic_menu_logout); MenuItem aboutItem = menu.add(0, ABOUT_ID, Menu.NONE, localization.getLanguage("menu_about")); aboutItem.setShortcut('0', 'A'); aboutItem.setIcon(android.R.drawable.ic_menu_info_details); // This code is here only for the test recording build if (BuildInfo.TEST_RECORDING_ENABLED) { MenuItem startTestItem = menu.add(0, START_TEST_ID, Menu.NONE, "Start new test"); MenuItem endTestItem = menu.add(0, END_TEST_ID, Menu.NONE, "End test"); } return true; } @Override public boolean onPrepareOptionsMenu(Menu menu) { return super.onPrepareOptionsMenu(menu); } @Override protected void onPause() { super.onPause(); homeScreenController.setForegroundStatus(false); Log.trace(TAG, "Paused activity (foreground status off)"); } @Override protected void onResume() { super.onResume(); homeScreenController.setForegroundStatus(true); Log.trace(TAG, "Resumed activity (foreground status on)"); } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle all of the possible menu actions switch (item.getItemId()) { case SETTINGS_ID: homeScreenController.showConfigurationScreen(); break; case LOGOUT_ID: homeScreenController.logout(); finish(); break; case ABOUT_ID: homeScreenController.showAboutScreen(); break; //// This code is for test recording mode only /////////////// case START_TEST_ID: PimTestRecorder.getInstance().startTestPressed(this); break; case END_TEST_ID: PimTestRecorder.getInstance().endTestPressed(); break; //// This code is for test recording mode only /////////////// } return super.onOptionsItemSelected(item); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); v.requestFocus(); AppSyncSource appSource = appSyncSourceManager.getSource(v.getId()); createContextMenuForSource(appSource, menu); } public void createContextMenuForSource(AppSyncSource appSource, ContextMenu menu) { if (appSource != null) { if (!appSource.isEnabled() || !appSource.isWorking()) { // If we get a requirement to allow sources to be enabled via // context menu, this can be done here return; } if (homeScreenController.isSynchronizing()) { // If a sync is in progress, the context menu can only be used // to stop the current sync of the current source AppSyncSource currentSource = homeScreenController.getCurrentSource(); if (currentSource != null && currentSource.getId() == appSource.getId()) { int cancelId = appSource.getId() << 16 | CANCEL_SOURCE_ID; menu.add(0, cancelId, 0, localization.getLanguage("menu_cancel_sync")); } } else { // This works if the number of sources is < 16 which is a fairly // safe assumption int syncId = appSource.getId() << 16 | SYNC_SOURCE_ID; int gotoId = appSource.getId() << 16 | GOTO_SOURCE_ID; int settingsId = appSource.getId() << 16 | SETTINGS_SOURCE_ID; StringBuffer label = new StringBuffer(); label.append(localization.getLanguage("menu_sync")).append(" ").append(appSource.getName()); menu.add(0, syncId, 0, label.toString()); // Add goto menu option only if an external app manager is set if (appSource.getAppManager() != null) { label = new StringBuffer(); label.append(localization.getLanguage("menu_goto")).append(" ").append(appSource.getName()); menu.add(0, gotoId, 0, label.toString()); } menu.add(0, settingsId, 0, localization.getLanguage("menu_settings")); } } } @Override public boolean onContextItemSelected(MenuItem item) { AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); int id = item.getItemId(); int sourceId = id >> 16; int itemId = id & 0xFFFF; AppSyncSource appSource = appSyncSourceManager.getSource(sourceId); if (appSource == null) { Log.error(TAG, "Cannot find view associated to this context menu"); return super.onContextItemSelected(item); } switch (itemId) { case SYNC_SOURCE_ID: homeScreenController.syncMenuSelected(); return true; case GOTO_SOURCE_ID: homeScreenController.gotoMenuSelected(); return true; case SETTINGS_SOURCE_ID: homeScreenController.showConfigurationScreen(); return true; case CANCEL_SOURCE_ID: homeScreenController.cancelMenuSelected(); return true; default: Log.error(TAG, "Unknwon context menu id " + id); return super.onContextItemSelected(item); } } /**************** Home Screen Implementation **********************/ public void initialize(HomeScreenController controller) { if (Log.isLoggable(Log.INFO)) { Log.info(TAG, "Initializing"); } // We force the controller to recompute the available sources homeScreenController.updateAvailableSources(); homeScreenController.redraw(); // Now update the list of visible items in the UI updateVisibleItems(); } public void lock() { screenLocked = true; } public void unlock() { screenLocked = false; } public boolean isLocked() { return screenLocked; } public void setSelectedIndex(int index) { // We can receive events before the list is actually populated. Just // ignore them if (listItems.isEmpty()) { return; } AndroidUISyncSource button = listItems.get(index); // Show the given element as selected button.setSelection(true, false); button.requestFocus(); } public void deselectIndex(int index) { // We can receive events before the list is actually populated. Just // ignore them if (listItems.isEmpty()) { return; } AndroidUISyncSource button = listItems.get(index); // Show the given element as selected button.setSelected(false); } ////////////////////////////////////////////////////////////////////// public Object getUiScreen() { return this; } public void setSyncMenuText(String text) { syncItemText = text; } private int adaptSizeToDensity(int size) { return (int) (size * getResources().getDisplayMetrics().density); } @Override public void addSyncAllButton(String arg0, Bitmap arg1, Bitmap arg2, Bitmap arg3) { // TODO Auto-generated method stub } @Override public void redraw() { // TODO Auto-generated method stub } @Override public void setSyncAllEnabled(boolean arg0) { // TODO Auto-generated method stub } @Override public void setSyncAllSelected(boolean arg0) { // TODO Auto-generated method stub } @Override public void setSyncAllText(String arg0) { // TODO Auto-generated method stub } @Override public void updateVisibleItems() { // TODO Auto-generated method stub } /** * SyncSource * @param syncMode * @return true-SyncSource; false-SyncSource */ public boolean setSingleSourceSyncMode(int syncMode) { Vector appSources = homeScreenController.getVisibleItems(); Enumeration iter = appSources.elements(); int idx = 0; while (iter.hasMoreElements()) { AppSyncSource appSource = (AppSyncSource) iter.nextElement(); appSource.setSyncMode(syncMode); } return false; } /** * */ public void startTimedService() { Intent timedIntent = new Intent(this, TimedUploadService.class); startService(timedIntent); } private void runContactsImport() { // Check if contacts shall be imported from other accounts if (((AndroidCustomization) customization).getContactsImportEnabled()) { AndroidController gc = AndroidController.getInstance(); AndroidAdvancedSettingsScreenController advSettingsController; advSettingsController = (AndroidAdvancedSettingsScreenController) gc .getAdvancedSettingsScreenController(); ContactsImporter importer = new ContactsImporter(Controller.HOME_SCREEN_ID, this, advSettingsController); importer.importContacts(true); } } protected static final int MSG_PROCESS_OVERVIEW_INFO_RESP = 0X1000; protected static final int MSG_REFRESH_OVERVIEW_INFO = 0X1001; /** * */ public void performCloudOverviewInfoReq() { final ResponseHandler<String> responseHandler = new ResponseHandler<String>() { public String handleResponse(HttpResponse response) { StatusLine status = response.getStatusLine(); HttpEntity entity = response.getEntity(); String result = null; try { InputStream is = entity.getContent(); BufferedReader r = new BufferedReader(new InputStreamReader(is)); StringBuilder total = new StringBuilder(); String line; while ((line = r.readLine()) != null) { total.append(line); } int startIndex = total.indexOf("{"); if (startIndex > 0) { result = total.substring(startIndex); } else { result = total.toString(); } Message message = overviewInfoHandler.obtainMessage(); Bundle bundle = new Bundle(); bundle.putString("RESPONSE", result); message.what = MSG_PROCESS_OVERVIEW_INFO_RESP; message.setData(bundle); overviewInfoHandler.sendMessage(message); } catch (IOException e) { Log.debug(TAG, e.toString()); } return result; } }; new Thread() { public void run() { try { DefaultHttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost(CgiCloudOverviewInfo); // List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); nameValuePairs.add(new BasicNameValuePair("username", configuration.getUsername())); post.setEntity(new UrlEncodedFormEntity(nameValuePairs)); client.execute(post, responseHandler); } catch (ClientProtocolException e) { Log.debug(TAG, e.toString()); } catch (IOException e) { Log.debug(TAG, e.toString()); } } }.start(); } /** * handler */ protected Handler overviewInfoHandler = new Handler() { public void handleMessage(Message m) { switch (m.what) { case MSG_PROCESS_OVERVIEW_INFO_RESP: Bundle bundle = m.getData(); String resp = bundle.getString("RESPONSE"); Log.debug(TAG, "content of resp : " + resp); try { processJsonStream(new StringBufferInputStream(resp)); } catch (IOException ioe) { ioe.printStackTrace(); } break; case MSG_REFRESH_OVERVIEW_INFO: initContactsInfo(); initSmsInfo(); break; default: break; } } }; /** * json * @param in * @throws IOException */ public void processJsonStream(InputStream in) throws IOException { JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8")); reader.beginObject(); boolean result = false; int contactsCount = 0; // int smsCount = 0; // long smsLastBakTime = 0; // while (reader.hasNext()) { String name = reader.nextName(); if ("result".equals(name)) { result = "ok".equals(reader.nextString()); } else if ("contacts_count".equals(name)) { contactsCount = Integer.valueOf(reader.nextString()); } else if ("sms_count".equals(name)) { smsCount = Integer.valueOf(reader.nextString()); } else if ("sms_last_baktime".equals(name)) { try { smsLastBakTime = Long.valueOf(reader.nextString()); } catch (NumberFormatException e) { e.printStackTrace(); } } else { reader.skipValue(); } } reader.endObject(); if (result) { //prefStore prefStore.setSmsCountInServer(this, smsCount); prefStore.setContactsCountInServer(this, contactsCount); // overviewInfoHandler.sendEmptyMessage(MSG_REFRESH_OVERVIEW_INFO); //0 if (0 == contactsCount) { contactsImportHandler.sendEmptyMessage(0); Log.debug("shawnqiu", "homeScreen : processJsonStream : showContactsImporter"); } } } /** * handler */ Handler contactsImportHandler = new Handler() { public void handleMessage(Message msg) { runContactsImport(); } }; protected void initSyncInfo() { currSource = 0; // currDirection = 0; // totalItems = 0; // } protected void initSmsReceiver() { IntentFilter fp = new IntentFilter(); fp.addAction("android.provider.Telephony.SMS_RECEIVED"); fp.setPriority(2147483647); //---when the sms is recieved--- try { registerReceiver(SmsReceiver.getInstance(), fp); } catch (Exception e) { e.printStackTrace(); Log.debug(TAG, e.toString()); } } BroadcastReceiver importFinishedReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { //TODO Log.debug(TAG, "import contacts over received."); new Thread() { public void run() { setSingleSourceSyncMode(SyncML.ALERT_CODE_REFRESH_FROM_CLIENT); homeScreenController.aloneSourcePressed(); currSource = SYNC_CONTACTS; overviewInfoHandler.sendEmptyMessage(MSG_REFRESH_OVERVIEW_INFO); } }.start(); } }; }