/* * 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 my.home.lehome.fragment; import android.animation.Animator; import android.animation.AnimatorSet; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Point; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.preference.PreferenceManager; import android.support.v4.app.Fragment; import android.text.Editable; import android.text.Selection; import android.text.TextUtils; import android.text.TextWatcher; import android.text.format.DateFormat; import android.util.Log; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.Display; import android.view.GestureDetector; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MenuInflater; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.view.ViewGroup; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.AdapterView; import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; import android.widget.Toast; import com.doomonafireball.betterpickers.calendardatepicker.CalendarDatePickerDialog; import com.doomonafireball.betterpickers.radialtimepicker.RadialTimePickerDialog; import java.lang.ref.WeakReference; import java.util.Calendar; import java.util.List; import my.home.common.util.ComUtil; import my.home.common.util.PrefUtil; import my.home.common.util.UIUtil; import my.home.lehome.R; import my.home.lehome.activity.LocationActivity; import my.home.lehome.activity.MainActivity; import my.home.lehome.activity.NFCDetectDialog; import my.home.lehome.adapter.AutoCompleteAdapter; import my.home.lehome.adapter.ChatItemArrayAdapter; import my.home.lehome.adapter.ChatItemArrayAdapter.ResendButtonClickListener; import my.home.lehome.adapter.ShortcutArrayAdapter; import my.home.lehome.asynctask.LoadMoreChatItemAsyncTask; import my.home.lehome.helper.MessageHelper; import my.home.lehome.mvp.presenters.ChatFragmentPresenter; import my.home.lehome.mvp.views.ChatItemListView; import my.home.lehome.mvp.views.ChatSuggestionView; import my.home.lehome.mvp.views.SaveLocalHistoryView; import my.home.lehome.util.CommonUtils; import my.home.lehome.util.Constants; import my.home.lehome.view.DelayAutoCompleteTextView; import my.home.lehome.view.OnSwipeTouchListener; import my.home.lehome.view.PhotoViewerDialog; import my.home.lehome.view.SimpleAnimationListener; import my.home.lehome.view.SpeechDialog; import my.home.model.entities.AutoCompleteItem; import my.home.model.entities.AutoCompleteToolItem; import my.home.model.entities.ChatItem; import my.home.model.entities.Shortcut; import my.home.model.manager.DBStaticManager; public class ChatFragment extends Fragment implements SpeechDialog.SpeechDialogListener , ResendButtonClickListener , ChatItemArrayAdapter.ImageClickListener , ChatItemArrayAdapter.LongMsgListener , AutoCompleteAdapter.onLoadConfListener , SaveLocalHistoryView , ChatItemListView , ChatSuggestionView , CalendarDatePickerDialog.OnDateSetListener , RadialTimePickerDialog.OnTimeSetListener { public static final String TAG = ChatFragment.class.getName(); public static final String BUNDLE_KEY_SCROLL_TO_BOTTOM = "BUNDLE_KEY_SCROLL_TO_BOTTOM"; private static final String FRAG_TAG_TIME_PICKER = "timePickerDialogFragment"; private static final String FRAG_TAG_DATE_PICKER = "calendarDatePickerDialog"; /* * common UI */ private ChatItemArrayAdapter mAdapter; private Button mSwitchButton; private Button mSuggestionButton; private Toast mToast; private OnGlobalLayoutListener mKeyboardListener; private ListView mCmdListview; private RelativeLayout mSendCmdLayout; // private WeakReference<ActionBarControlView> mActionBarControlViewRf; private DelayAutoCompleteTextView mSendCmdEdittext; private ChatFragmentPresenter mChatFragmentPresenter; /* * common variables */ public static Handler PublicHandler; private int mNewMsgNum = 0; private boolean mNeedShowUnread = false; private boolean mScrollViewInButtom = false; private boolean mKeyboard_open = false; private boolean mInSpeechMode = false; /* * history */ private AutoCompleteAdapter mAutoCompleteAdapter; /* * speech */ SpeechDialog mSpeechDialog; private boolean scriptInputMode; private boolean inRecogintion = false; private int mScreenWidth = 0; private int mScreenHeight = 0; /* * photo */ private PhotoViewerDialog mPhotoDialog = null; /* * constant */ public static final int MSG_TYPE_CHATITEM = 1; public static final int MSG_TYPE_TOAST = 2; public static final int MSG_TYPE_VOICE_CMD = 3; private static final int SCROLL_DIR_DOWN = 1; private static final int SCROLL_DIR_UP = -1; private static final int SCROLL_DIR_RIGHT = 1; private static final int SCROLL_DIR_LEFT = -1; private int mScrollYDirection = 0; private int mScrollXDirection = 0; private boolean mSuggestionButtonShown; @SuppressLint("HandlerLeak") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); if (mAdapter == null) { mAdapter = new ChatItemArrayAdapter(this.getActivity(), R.layout.chat_item_client); mAdapter.setResendButtonClickListener(this); mAdapter.setImageClickListener(this); mAdapter.setLongMsgListener(this); } PublicHandler = new MyHandler(this); mChatFragmentPresenter = new ChatFragmentPresenter(this, this, this); mChatFragmentPresenter.start(); mPhotoDialog = new PhotoViewerDialog(getActivity()); } public boolean isScrollViewInButtom() { return mScrollViewInButtom; } public void setScrollViewInButtom(boolean mScrollViewInButtom) { this.mScrollViewInButtom = mScrollViewInButtom; } public int getNewMsgNum() { return mNewMsgNum; } public void setNewMsgNum(int mNewMsgNum) { this.mNewMsgNum = mNewMsgNum; } public boolean isNeedShowUnread() { return mNeedShowUnread; } public void setNeedShowUnread(boolean mNeedShowUnread) { this.mNeedShowUnread = mNeedShowUnread; } @Override public void onImageViewClicked(Bundle bundle) { ChatItemArrayAdapter.ClickableImageType type = (ChatItemArrayAdapter.ClickableImageType) bundle.getSerializable("type"); if (type != null) { switch (type) { case IMAGE: if (mPhotoDialog != null) { String imageURL = bundle.getString("imageURL"); String extraTitle = bundle.getString("extraTitle"); Intent intent = bundle.getParcelable("extraIntent"); mPhotoDialog.setTarget(imageURL, intent, extraTitle); mPhotoDialog.show(); } break; case LOCATION: Intent locIntent = new Intent(getContext(), LocationActivity.class); locIntent.putExtras(bundle); startActivity(locIntent); break; } } } @Override public void onImageViewLongClicked(String imageURL) { } @Override public void onLongMsgSuccess(int oldState, int newState, Bundle what) { this.scrollToBottom(); } @Override public void onLongMsgFail(int oldState, int newState, Bundle what) { this.scrollToBottom(); } @Override public void onLongMsgPending(int oldState, int newState, Bundle what) { } @Override public void onLongMsgIdle(int oldState, int newState, Bundle what) { } private static class MyHandler extends Handler { private final WeakReference<ChatFragment> mFragment; private final WeakReference<Context> mAppplicationContext; private Runnable mToastRunnable = new Runnable() { @Override public void run() { ChatFragment fragment = mFragment.get(); if (fragment.getActivity() == null) { return; } if (!fragment.isScrollViewInButtom()) { fragment.showTip(fragment.getString( R.string.chat_new_message, fragment.getNewMsgNum() )); fragment.setNeedShowUnread(true); } else { fragment.setNewMsgNum(0); fragment.scrollToBottom(); } } }; public MyHandler(ChatFragment fragment) { mFragment = new WeakReference<>(fragment); mAppplicationContext = new WeakReference<>(fragment.getActivity().getApplicationContext()); } @Override public void handleMessage(Message msg) { final ChatFragment fragment = mFragment.get(); if (fragment != null) { switch (msg.what) { case MSG_TYPE_CHATITEM: ChatItem newItem = (ChatItem) msg.obj; if (newItem != null) { Log.d(TAG, "onSubscribalbeReceiveMsg : " + newItem.getContent()); fragment.getAdapter().add(newItem); fragment.getAdapter().notifyDataSetChanged(); if (!fragment.isScrollViewInButtom()) { fragment.setNewMsgNum(fragment.getNewMsgNum() + 1); fragment.getCmdListView().removeCallbacks(mToastRunnable); fragment.getCmdListView().postDelayed(mToastRunnable, 200); } else { fragment.setNewMsgNum(0); fragment.scrollToBottom(); } } break; case MSG_TYPE_TOAST: if (mAppplicationContext.get() != null) { Context context = mAppplicationContext.get(); if (context != null) { Toast.makeText( context , (String) msg.obj , Toast.LENGTH_SHORT) .show(); } } break; case MSG_TYPE_VOICE_CMD: fragment.startRecognize(); break; default: break; } } } } @Override public void onDestroy() { super.onDestroy(); mAutoCompleteAdapter.destory(); mChatFragmentPresenter.stop(); } public static boolean sendMessage(Message msg) { if (ChatFragment.PublicHandler != null) { ChatFragment.PublicHandler.sendMessage(msg); return true; } return false; } @SuppressLint("ShowToast") @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.chat_fragment, container, false); setupViews(rootView); mSuggestionButton.setVisibility(View.GONE); mSendCmdEdittext.setCanShowDropdown(false); mToast = Toast.makeText(getActivity(), "", Toast.LENGTH_SHORT); // mActionBarControlViewRf = new WeakReference<ActionBarControlView>((MainActivity)getActivity()); // for retainning fragment setRetainInstance(true); // for user experience if (getArguments() != null && getArguments().getBoolean(BUNDLE_KEY_SCROLL_TO_BOTTOM)) { scrollToBottom(); getArguments().clear(); } return rootView; } @Override public void setupViews(View rootView) { mCmdListview = (ListView) rootView.findViewById(R.id.chat_list); mCmdListview.setAdapter(mAdapter); mCmdListview.setOnScrollListener(new OnScrollListener() { int topVisibleIndex; @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (mKeyboard_open && scrollState == SCROLL_STATE_TOUCH_SCROLL && mScrollYDirection == SCROLL_DIR_DOWN) { mSendCmdEdittext.postDelayed(new Runnable() { @Override public void run() { InputMethodManager inputManager = (InputMethodManager) getActivity(). getSystemService(Context.INPUT_METHOD_SERVICE); inputManager.hideSoftInputFromWindow( getActivity().getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } }, 100); } else if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) { if (topVisibleIndex == 0 && mAdapter.getItem(0).getId() > Constants.CHATITEM_LOWEST_INDEX) { new LoadMoreChatItemAsyncTask(ChatFragment.this).execute(Constants.CHATITEM_LOAD_LIMIT); } } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (visibleItemCount == 0) return; topVisibleIndex = firstVisibleItem; int vH = view.getHeight(); View childView = view.getChildAt(visibleItemCount - 1); if (firstVisibleItem + visibleItemCount == totalItemCount && vH >= childView.getBottom()) { // Log.d(TAG, "reach buttom"); mScrollViewInButtom = true; if (mNeedShowUnread) { mNeedShowUnread = false; } } else { // Log.d(TAG, "leave buttom"); if (mScrollViewInButtom == true) { mScrollViewInButtom = false; } } } }); mCmdListview.setOnTouchListener(new OnTouchListener() { private final GestureDetector gestureDetector = new GestureDetector( getContext(), new GestureDetector.SimpleOnGestureListener() { @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { mScrollYDirection = distanceY >= 0 ? SCROLL_DIR_UP : SCROLL_DIR_DOWN; mScrollXDirection = distanceX >= 0 ? SCROLL_DIR_RIGHT : SCROLL_DIR_LEFT; return false; } }); @Override public boolean onTouch(View v, MotionEvent event) { if (mScrollViewInButtom) { return gestureDetector.onTouchEvent(event); } return false; } }); mSuggestionButton = (Button) rootView.findViewById(R.id.cmd_suggestion_button); mSuggestionButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { AutoCompleteItem item = (AutoCompleteItem) v.getTag(); if (item instanceof AutoCompleteToolItem) { Log.d(TAG, "selected AutoCompleteToolItem: " + item.getContent()); AutoCompleteToolItem toolItem = (AutoCompleteToolItem) item; performToolItem(toolItem); } else { setSendCmdEditText(item.getCmd()); } } }); // mSuggestionButton.setOnLongClickListener(new View.OnLongClickListener() { // @Override // public boolean onLongClick(View v) { // mSendCmdEdittext.setCanShowDropdown(true); // mSendCmdEdittext.showDropDown(); // onShowSuggestion(null); // return true; // } // }); mSuggestionButton.setOnTouchListener(new OnSwipeTouchListener(getActivity()) { // private final Animation leftAnim = AnimationUtils.loadAnimation(getActivity(), R.anim.shake_left); // private final Animation rightAnim = AnimationUtils.loadAnimation(getActivity(), R.anim.shake_right); @Override public void onSwipeTop() { Animation upAnim = AnimationUtils.loadAnimation(getActivity(), R.anim.shake_up); upAnim.setAnimationListener(new SimpleAnimationListener() { @Override public void onAnimationEnd(Animation animation) { mChatFragmentPresenter.showPreCmdSuggestion( mAutoCompleteAdapter.getResultList(), (AutoCompleteItem) mSuggestionButton.getTag() ); } }); mSuggestionButton.startAnimation(upAnim); } @Override public void onSwipeLeft() { mSendCmdEdittext.setCanShowDropdown(true); mSendCmdEdittext.showDropDown(); onShowSuggestion(null); } @Override public void onSwipeBottom() { Animation downAnim = AnimationUtils.loadAnimation(getActivity(), R.anim.shake_down); downAnim.setAnimationListener(new SimpleAnimationListener() { @Override public void onAnimationEnd(Animation animation) { mChatFragmentPresenter.showNextCmdSuggestion( mAutoCompleteAdapter.getResultList(), (AutoCompleteItem) mSuggestionButton.getTag() ); } }); mSuggestionButton.startAnimation(downAnim); } @Override public void onClick() { Animation clickAnim = AnimationUtils.loadAnimation(getActivity(), R.anim.shake_click); clickAnim.setAnimationListener(new SimpleAnimationListener() { @Override public void onAnimationEnd(Animation animation) { mSuggestionButton.performClick(); } }); mSuggestionButton.startAnimation(clickAnim); } }); mSpeechDialog = SpeechDialog.getInstance(getActivity()); final Button speechButton = (Button) rootView.findViewById(R.id.speech_button); speechButton.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View arg0, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { speechButton.setSelected(true); if (!mSpeechDialog.isShowing()) { startRecognize(); } return true; } else if (event.getAction() == MotionEvent.ACTION_UP) { speechButton.setSelected(false); if (event.getRawY() / mScreenHeight <= Constants.DIALOG_CANCEL_Y_PERSENT) { Log.d(TAG, "cancelListening."); mSpeechDialog.cancelListening(); } else { Log.d(TAG, "finishListening."); mSpeechDialog.finishListening(); } return true; } else if (event.getAction() == MotionEvent.ACTION_MOVE) { // Log.d(TAG, String.valueOf(event.getRawY()/mScreenHeight)); if (mSpeechDialog != null) { if (event.getRawY() / mScreenHeight <= Constants.DIALOG_CANCEL_Y_PERSENT) { mSpeechDialog.setReleaseCancelVisible(true); } else { mSpeechDialog.setReleaseCancelVisible(false); } } return true; } return false; } }); mSendCmdEdittext = (DelayAutoCompleteTextView) rootView.findViewById(R.id.send_cmd_edittext); mSendCmdEdittext.setOnEditorActionListener(new OnEditorActionListener() { public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_DONE) { // Perform action on key press String messageString = mSendCmdEdittext.getText().toString(); if (!messageString.trim().equals("")) { mChatFragmentPresenter.markAndSendCurrentInput(messageString, shouldUseLocalMsg()); mSendCmdEdittext.setText(""); mSendCmdEdittext.setCanShowDropdown(false); } return true; } else { return false; } } }); mAutoCompleteAdapter = new AutoCompleteAdapter(getActivity()); mAutoCompleteAdapter.setOnLoadConfListener(this); mAutoCompleteAdapter.initAutoCompleteItem(); mSendCmdEdittext.setAdapter(mAutoCompleteAdapter); mSendCmdEdittext.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { AutoCompleteItem item = (AutoCompleteItem) parent.getItemAtPosition(position); if (item instanceof AutoCompleteToolItem) { Log.d(TAG, "selected AutoCompleteToolItem: " + item.getContent()); AutoCompleteToolItem toolItem = (AutoCompleteToolItem) item; performToolItem(toolItem); } else { setSendCmdEditText(item.getCmd()); } } }); mSendCmdEdittext.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { if (mSendCmdEdittext.getText() != null && mSendCmdEdittext.getText().length() != 0) { mSendCmdEdittext.performFiltering(mSendCmdEdittext.getText()); } } }); mSendCmdEdittext.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View view, boolean hasFocus) { if (hasFocus && mSendCmdEdittext.getText() != null && mSendCmdEdittext.getText().length() != 0) { mSendCmdEdittext.performFiltering(mSendCmdEdittext.getText()); } } }); mSendCmdEdittext.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { if (s.toString().trim().length() == 0) { if (mSendCmdEdittext.isAutoCompleteEnable()) { onShowSuggestion(null); } mSendCmdEdittext.setCanShowDropdown(false); } } }); mSendCmdEdittext.setAutoCompleteEnable(PrefUtil.getbooleanValue(getActivity(), "pref_cmd_autocomplete", true)); mKeyboardListener = (new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { int heightDiff = getView().getRootView().getHeight() - getView().getHeight(); // Log.v(TAG, "height" + String.valueOf(heightDiff)); if (heightDiff > 250) { // if more than 100 pixels, its probably a keyboard... Log.v(TAG, "keyboard show."); if (!mKeyboard_open) { ChatFragment.this.scrollToBottom(); } mKeyboard_open = true; } else if (mKeyboard_open) { mKeyboard_open = false; mSendCmdEdittext.clearFocus(); mCmdListview.requestFocus(); Log.d(TAG, "keyboard hide."); } } }); rootView.getViewTreeObserver().addOnGlobalLayoutListener(mKeyboardListener); mSendCmdLayout = (RelativeLayout) rootView.findViewById(R.id.send_cmd_layout); mSwitchButton = (Button) rootView.findViewById(R.id.switch_input_button); mSwitchButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (!mInSpeechMode) { Button switch_btn = (Button) getView().findViewById(R.id.switch_input_button); switch_btn.setBackgroundResource(R.drawable.chatting_setmode_voice_btn); getView().findViewById(R.id.speech_button).setVisibility(View.VISIBLE); mSendCmdEdittext.setVisibility(View.INVISIBLE); if (mSuggestionButtonShown) { mSuggestionButton.setVisibility(View.INVISIBLE); } mInSpeechMode = true; // AnimatorSet animatorSet = UIUtils.getDismissViewScaleAnimatorSet(toolButton); // toolButton.setVisibility(View.GONE); // animatorSet.start(); // Animation animation = new ResizeHeightAnim(mSendCmdLayout, mSendCmdLayout.getHeight()*2); // animation.setDuration(300); // animation.setRepeatCount(0); // animation.setInterpolator(new AccelerateDecelerateInterpolator()); // mSendCmdLayout.startAnimation(animation); if (mKeyboard_open) { mSendCmdEdittext.post(new Runnable() { @Override public void run() { InputMethodManager inputManager = (InputMethodManager) getActivity(). getSystemService(Context.INPUT_METHOD_SERVICE); inputManager.hideSoftInputFromWindow( getActivity().getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } }); } } else { Button switch_btn = (Button) getView().findViewById(R.id.switch_input_button); switch_btn.setBackgroundResource(R.drawable.chatting_setmode_msg_btn); getView().findViewById(R.id.speech_button).setVisibility(View.INVISIBLE); mSendCmdEdittext.setVisibility(View.VISIBLE); if (mSuggestionButtonShown) { mSuggestionButton.setVisibility(View.VISIBLE); } // Animation animation = new ResizeHeightAnim(mSendCmdLayout, mSendCmdLayout.getHeight()/2); // animation.setDuration(300); // animation.setRepeatCount(0); // animation.setInterpolator(new AccelerateDecelerateInterpolator()); // mSendCmdLayout.startAnimation(animation); mSendCmdEdittext.requestFocus(); mSendCmdEdittext.postDelayed(new Runnable() { @Override public void run() { InputMethodManager keyboard = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); keyboard.showSoftInput(mSendCmdEdittext, 0); } }, 200); mInSpeechMode = false; } } }); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); if (v.getId() == mCmdListview.getId()) { AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; MenuInflater inflater = getActivity().getMenuInflater(); ChatItem chatItem = mAdapter.getItem(info.position); if (chatItem.isClient()) { inflater.inflate(R.menu.chat_item_is_me, menu); MenuItem item = menu.getItem(menu.size() - 1); // nfc menuitem index item.setEnabled(PrefUtil.getbooleanValue(getContext(), "pref_nfc_cmd_enable", true)); } else if (chatItem.isServer()) { inflater.inflate(R.menu.chat_item_not_me, menu); } else if (chatItem.isServerImageItem()) { inflater.inflate(R.menu.chat_item_server_image, menu); } else if (chatItem.isServerLocItem()) { inflater.inflate(R.menu.chat_item_server_loc, menu); } } } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.voice_input: scriptInputMode = true; startRecognize(); return true; default: return super.onOptionsItemSelected(item); } } @Override public boolean onContextItemSelected(MenuItem item) { AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); String selectedString = mAdapter.getItem(info.position).getContent(); switch (item.getItemId()) { case R.id.add_chat_item_to_shortcut: MainActivity activity = (MainActivity) getActivity(); if (activity.getShortcurFragment() == null) { Shortcut shortcut = new Shortcut(); shortcut.setContent(selectedString); shortcut.setInvoke_count(0); shortcut.setWeight(1.0); DBStaticManager.addShortcut(this.getActivity(), shortcut); } else { activity.getShortcurFragment().addShortcut(selectedString); } return true; case R.id.resend_item: mChatFragmentPresenter.markAndSendCurrentInput(selectedString, shouldUseLocalMsg()); return true; case R.id.copy_item: CommonUtils.copyStringToClipboard(getActivity(), getString(R.string.app_name), selectedString); this.showTip(getString(R.string.msg_copyed_to_clipboard)); return true; case R.id.copy_to_input: if (!TextUtils.isEmpty(selectedString)) { if (mInSpeechMode) { mSwitchButton.performClick(); } mSendCmdEdittext.append(selectedString); mSendCmdEdittext.requestFocus(); mSendCmdEdittext.postDelayed(new Runnable() { @Override public void run() { InputMethodManager keyboard = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); keyboard.showSoftInput(mSendCmdEdittext, 0); } }, 200); } return true; case R.id.save_item: mChatFragmentPresenter.saveImageItem(mAdapter.getItem(info.position)); return true; case R.id.copy_loc_item_info: mChatFragmentPresenter.copyLocationInfo( mAdapter.getItem(info.position), getString(R.string.app_name) ); this.showTip(getString(R.string.msg_copyed_to_clipboard)); return true; case R.id.action_photo_extra_intent: mChatFragmentPresenter.openLocationInBrowser(mAdapter.getItem(info.position)); return true; case R.id.write_to_nfc_item: Intent nfcIntent = new Intent(getActivity(), NFCDetectDialog.class); nfcIntent.putExtra(NFCDetectDialog.EXTRA_TEXT_CONTENT, selectedString); startActivity(nfcIntent); case R.id.action_show_location: default: return super.onContextItemSelected(item); } } public void switchInputMode() { mSwitchButton.performClick(); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); registerForContextMenu(mCmdListview); setHasOptionsMenu(true); Display display = getActivity().getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getSize(size); mScreenWidth = size.x; mScreenHeight = size.y; } @Override public void onDestroyView() { super.onDestroyView(); if (mKeyboard_open && getActivity() != null) { InputMethodManager inputManager = (InputMethodManager) getActivity(). getSystemService(Context.INPUT_METHOD_SERVICE); inputManager.hideSoftInputFromWindow( getActivity().getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } mToast.cancel(); if (null != mSpeechDialog && mSpeechDialog.isShowing()) { mSpeechDialog.dismiss(); } if (null != mPhotoDialog && mPhotoDialog.isShowing()) { mPhotoDialog.dismiss(); } View rootView = getView(); rootView.getViewTreeObserver().removeOnGlobalLayoutListener(mKeyboardListener); } @Override public void onResume() { super.onResume(); Log.d(TAG, "onResume"); MessageHelper.resetUnreadCount(); mChatFragmentPresenter.resetDatas(getActivity()); RadialTimePickerDialog rtpd = (RadialTimePickerDialog) getFragmentManager().findFragmentByTag( FRAG_TAG_TIME_PICKER); if (rtpd != null) { rtpd.setOnTimeSetListener(this); } CalendarDatePickerDialog cdpd = (CalendarDatePickerDialog) getFragmentManager() .findFragmentByTag(FRAG_TAG_DATE_PICKER); if (cdpd != null) { cdpd.setOnDateSetListener(this); } } @Override public void onPause() { super.onPause(); Log.d(TAG, "onPause"); } @Override public void onStart() { super.onStart(); } @Override public void onStop() { super.onStop(); // mChatFragmentPresenter.saveSaveLocalHistory(); } // ========================================================================================= @Override public void onLoadComplete(boolean loadSuccess) { Log.i(TAG, "load autocomplete conf: " + loadSuccess); } private void showTip(String str) { if (!TextUtils.isEmpty(str)) { mToast.setText(str); mToast.show(); } } public void scrollToBottom() { mCmdListview.clearFocus(); mCmdListview.setSelection(mAdapter.getCount() - 1); // another scroll runnable for sroll to 'real' buttom mCmdListview.post(new Runnable() { @Override public void run() { mCmdListview.smoothScrollToPosition(mAdapter.getCount() - 1); } }); } // public void scrollToBottomAnimate() { // mCmdListview.clearFocus(); //// mCmdListview.smoothScrollToPosition(mAdapter.getCount() - 1); // mCmdListview.setSelection(mAdapter.getCount() - 1); // mCmdListview.post(new Runnable() { // @Override // public void run() { // mCmdListview.smoothScrollToPosition(mAdapter.getCount() - 1); // } // }); // } public ChatItemArrayAdapter getAdapter() { return mAdapter; } public ListView getCmdListView() { return mCmdListview; } /** * ========================s2t=========================== */ /* * Speech Dialog */ public boolean isRecognizing() { return inRecogintion; } public void startRecognize() { Log.d(TAG, "show mSpeechDialog"); SharedPreferences mySharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext()); boolean auto_sco = mySharedPreferences.getBoolean("pref_auto_connect_sco", true); Log.d(TAG, "auto_sco: " + auto_sco); inRecogintion = true; mSpeechDialog.setmUseBluetooth(auto_sco); mSpeechDialog.setup(getContext(), ChatFragment.this); mSpeechDialog.show(); } public void finishVoiceRecognize() { if (mSpeechDialog.isShowing() && inRecogintion) { mSpeechDialog.finishListening(); } } public void cancelVoiceRecognize() { if (mSpeechDialog.isShowing() && inRecogintion) { mSpeechDialog.cancelListening(); } } @Override public void onResult(List<String> results) { Log.d(TAG, "onResult: " + results.toString()); if (results.size() == 0) { showTip(getString(R.string.speech_no_result)); return; } String resultString = results.get(0); if (scriptInputMode == true) { resultString = "运行脚本#" + resultString + "#"; scriptInputMode = false; } final String msgString = resultString; final Context context = getActivity(); Log.d(TAG, "result: " + msgString); if (!msgString.trim().equals("")) { SharedPreferences mySharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); boolean need_confirm = mySharedPreferences.getBoolean("pref_speech_cmd_need_confirm", true); if (!need_confirm) { mChatFragmentPresenter.markAndSendCurrentInput(msgString, shouldUseLocalMsg()); inRecogintion = false; } else { AlertDialog.Builder alert = new AlertDialog.Builder(context); alert.setMessage(msgString); alert.setTitle(getResources().getString(R.string.speech_cmd_need_confirm)); alert.setNeutralButton(getResources().getString(R.string.com_send_to_edittext) , new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { mSendCmdEdittext.append(msgString); if (mInSpeechMode) { mSwitchButton.performClick(); } inRecogintion = false; } }); alert.setPositiveButton(getResources().getString(R.string.com_comfirm) , new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { mChatFragmentPresenter.markAndSendCurrentInput(msgString, shouldUseLocalMsg()); inRecogintion = false; } }); alert.setNegativeButton(getResources().getString(R.string.com_cancel), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { inRecogintion = false; } }); alert.show(); } } else { inRecogintion = false; } } @Override public void onDissmiss(int state) { inRecogintion = false; } @Override public void onResendButtonClicked(int pos) { ChatItem item = this.getAdapter().getItem(pos); mChatFragmentPresenter.markAndSendCurrentChatItem(item, shouldUseLocalMsg()); } @Override public void onSaveLocalHistoryFinish(boolean success) { if (!success) { Toast.makeText( getActivity() , getString(R.string.save_local_history_error) , Toast.LENGTH_SHORT) .show(); } } private void updateRequestChatItemState(ArrayAdapter<ChatItem> adapter, Long id, int state) { for (int i = adapter.getCount() - 1; i >= 0; i--) { if (adapter.getItem(i).getId().equals(id)) { adapter.getItem(i).setState(state); break; } } adapter.notifyDataSetChanged(); } @Override public void onResetDatas(List<ChatItem> chatItems) { mAdapter.setData(chatItems); } @Override public void onChatItemRequest(ChatItem reqItem, boolean isUpdate) { if (isUpdate) { updateRequestChatItemState(getAdapter(), reqItem.getId(), reqItem.getState()); } else { getAdapter().add(reqItem); getAdapter().notifyDataSetChanged(); scrollToBottom(); } } @Override public void onChatItemResponse(int repCode, long reqID, int reqState, ChatItem repItem) { if (repCode == 200) { updateRequestChatItemState(getAdapter(), reqID, reqState); } else { getAdapter().add(repItem); updateRequestChatItemState(getAdapter(), reqID, reqState); scrollToBottom(); } } @Override public Context getContext() { return getActivity(); } private void appendSendCmdEditText(String content) { setSendCmdEditText(mSendCmdEdittext.getText() + content); } private void setSendCmdEditText(String content) { mSendCmdEdittext.setText(content); mSendCmdEdittext.requestFocus(); Editable editable = mSendCmdEdittext.getText(); Selection.setSelection(editable, editable.length()); } /* * Date Time picker callback */ // @Override // public void onTimeSelected(TimePicker view, int hourOfDay, int minute) { // appendSendCmdEditText(Utils.TimeToCmdString(hourOfDay, minute)); // } // // @Override // public void onDateSelected(DatePicker view, int year, int month, int day) { // appendSendCmdEditText(Utils.DateToCmdString(year, month, day)); // } @Override public void onDateSet(CalendarDatePickerDialog calendarDatePickerDialog, int year, int month, int day) { appendSendCmdEditText(ComUtil.DateToCmdString(year, month, day)); } @Override public void onTimeSet(RadialTimePickerDialog radialTimePickerDialog, int hourOfDay, int minute) { appendSendCmdEditText(ComUtil.TimeToCmdString(hourOfDay, minute)); } private void showTimeDialog() { // TimePickerFragment timeFragment = new TimePickerFragment(); // timeFragment.setDateTimePickerFragmentListener(this); // timeFragment.show(getFragmentManager(), "timePicker"); final Calendar c = Calendar.getInstance(); int hour = c.get(Calendar.HOUR_OF_DAY); int minute = c.get(Calendar.MINUTE); RadialTimePickerDialog timePickerDialog = RadialTimePickerDialog .newInstance(this, hour, minute, DateFormat.is24HourFormat(getActivity())); timePickerDialog.show(getFragmentManager(), FRAG_TAG_TIME_PICKER); } private void showDateDialog() { // DatePickerFragment dateFragment = new DatePickerFragment(); // dateFragment.setDateTimePickerFragmentListener(this); // dateFragment.show(getFragmentManager(), "datePicker"); final Calendar c = Calendar.getInstance(); int year = c.get(Calendar.YEAR); int month = c.get(Calendar.MONTH); int day = c.get(Calendar.DAY_OF_MONTH); // Create a new instance of DatePickerDialog and return it // return new DatePickerDialog(getActivity(), this, year, month, day); CalendarDatePickerDialog calendarDatePickerDialog = CalendarDatePickerDialog .newInstance(this, year, month, day); calendarDatePickerDialog.show(getFragmentManager(), FRAG_TAG_DATE_PICKER); } private void showShortcutDialog(List<Shortcut> items) { if (items == null || items.size() == 0) { showTip(getString(R.string.menu_tool_favor_empty)); return; } AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setTitle(R.string.menu_tool_favor_title); builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); final ShortcutArrayAdapter adapter = new ShortcutArrayAdapter(getActivity(), R.layout.shortcut_item); adapter.setData(items); builder.setAdapter(adapter, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String selectedContent = adapter.getItem(which).getContent(); Log.d(TAG, "selected shortcut: " + selectedContent); appendSendCmdEditText(selectedContent); } }); builder.show(); } private void performToolItem(AutoCompleteToolItem item) { switch (item.getSpecType()) { case AutoCompleteToolItem.SPEC_TYPE_DATE: showDateDialog(); break; case AutoCompleteToolItem.SPEC_TYPE_TIME: showTimeDialog(); break; case AutoCompleteToolItem.SPEC_TYPE_FAVOR: List<Shortcut> items = DBStaticManager.getAllShortcuts(this.getActivity()); showShortcutDialog(items); break; } } /* * onShowSuggestion(AutoCompleteItem item) */ @Override public void onShowSuggestion(AutoCompleteItem item) { if (item == null || mSendCmdEdittext.getText() == null || mSendCmdEdittext.getText().length() == 0) { if (mSuggestionButton.getVisibility() != View.GONE) { AnimatorSet animatorSet = UIUtil.getDismissViewScaleAnimatorSet(mSuggestionButton, 200); mSuggestionButton.setVisibility(View.VISIBLE); animatorSet.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { mSuggestionButton.setVisibility(View.GONE); mSuggestionButton.setText(""); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); animatorSet.start(); } else { mSuggestionButton.setText(""); } // disable autocomplete dropdown mSuggestionButton.setTag(null); mSuggestionButtonShown = true; } else if (!mSendCmdEdittext.isCanShowDropdown()) { if (mSuggestionButton.getVisibility() != View.VISIBLE) { AnimatorSet animatorSet = UIUtil.getShowViewScaleAnimatorSet(mSuggestionButton, 200); mSuggestionButton.setVisibility(View.VISIBLE); animatorSet.start(); } mSuggestionButton.setTag(item); mSuggestionButton.setText(item.getContent()); mSuggestionButtonShown = true; } } // @Override // public void onGetAutoCompleteItems(List<AutoCompleteItem> item) { // if (item == null || item.size() == 0) { // mSendCmdEdittext.setCanShowDropdown(false); // } // } private boolean shouldUseLocalMsg() { return ((MainActivity) getActivity()).shouldUseLocalMsg(); } }