Back to project page MySms.
The source code is released under:
Apache License
If you think the Android project MySms listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.henningta.mysms; //from w w w. ja v a2s. c o m import android.app.Activity; import android.app.AlertDialog; import android.app.Fragment; import android.content.BroadcastReceiver; import android.content.Context; import android.content.CursorLoader; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.BaseColumns; import android.provider.ContactsContract; import android.support.v7.app.ActionBarActivity; import android.support.v7.view.ActionMode; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; import java.util.Comparator; import java.util.LinkedList; public class ConversationsFragment extends Fragment implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener { public static final String TAG = "com.henningta.mysms.ConversationsFragment"; private OnSourceSelected callback; private Activity activity; private ActionMode actionMode; private ListView lvConversations; private ConversationAdapter conversationAdapter; public static ConversationsFragment newInstance() { return new ConversationsFragment(); } @Override public void onAttach(Activity activity) { super.onAttach(activity); // This makes sure that the container activity has implemented // the callback interface. If not, it throws an exception try { callback = (OnSourceSelected)activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnConversationSelected"); } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); actionMode = null; setRetainInstance(true); setHasOptionsMenu(true); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_conversations, container, false); TextView tvNoConversations = (TextView)view.findViewById(R.id.tvNoConversations); lvConversations = (ListView)view.findViewById(R.id.lvConversations); lvConversations.setEmptyView(tvNoConversations); lvConversations.setOnItemClickListener(this); lvConversations.setOnItemLongClickListener(this); return view; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); this.activity = getActivity(); // set toolbar ((ActionBarActivity)activity).getSupportActionBar().setTitle(R.string.app_name); ((ActionBarActivity)activity).getSupportActionBar().setSubtitle(null); } @Override public void onResume() { super.onResume(); // init db DatabaseHandler dbHandler = new DatabaseHandler(activity); // initialize adapter conversationAdapter = new ConversationAdapter(activity, R.layout.conversation_list_item, dbHandler.getConversationList()); conversationAdapter.sort(new ConversationComparator()); lvConversations.setAdapter(conversationAdapter); // close db dbHandler.close(); // cancel notifications if any SmsTools.cancelNotifications(activity); activity.sendBroadcast(new Intent(activity, NotificationReceiver.class)); activity.registerReceiver(conversationReceiver, new IntentFilter(Settings.ACTION_CONVERSATION)); } @Override public void onPause() { super.onPause(); activity.unregisterReceiver(conversationReceiver); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { // Inflate the menu; this adds items to the action bar if it is present. super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.main, menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle presses on the action bar items switch (item.getItemId()) { case R.id.action_new: addConversation(); return true; case R.id.action_settings: Intent settingsIntent = new Intent(activity, SettingsActivity.class); startActivity(settingsIntent); return true; default: return super.onOptionsItemSelected(item); } } // Container Activity must implement this interface public interface OnSourceSelected { public void onSourceSelected(String source); } @Override public void onItemClick(AdapterView<?> parent, View v, int position, long id) { if (actionMode != null) { // if action mode, toggle checked state of item conversationAdapter.toggleChecked(position); actionMode.invalidate(); } else { // do item click Conversation conversation = (Conversation)parent.getItemAtPosition(position); callback.onSourceSelected(conversation.getSource()); } } @Override public boolean onItemLongClick(AdapterView<?> parent, View v, final int position, long id) { if (actionMode != null) { return false; } final Conversation conversation = conversationAdapter.getItem(position); if (conversation.isContact()) { setChecked(position); } else { String[] items = new String[] { "Add contact", "Select" }; AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setTitle(conversation.getName()) .setItems(items, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { switch (which) { case 0: Intent intent = new Intent(ContactsContract.Intents.SHOW_OR_CREATE_CONTACT, Uri.parse("tel:" + conversation.getSource())); intent.putExtra(ContactsContract.Intents.EXTRA_FORCE_CREATE, true); startActivityForResult(intent, Settings.REQUEST_ADD_CONTACT); break; case 1: setChecked(position); break; default: break; } } }); AlertDialog dialog = builder.create(); dialog.show(); } return true; } /*private void loadPreferences() { Settings.NOTIFICATIONS_ENABLED = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("notifications_new_message", true); Settings.NOTIFICATIONS_VIBRATE = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("notifications_new_message_vibrate", true); }*/ private void setChecked(int position) { // set checked selected item and enter multi selection mode conversationAdapter.setChecked(position, true); ((ActionBarActivity)activity).startSupportActionMode(new ActionModeCallback(activity)); actionMode.invalidate(); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (resultCode) { case Activity.RESULT_CANCELED: Log.d(this.getClass().getName(), "Activity cancelled"); return; case Activity.RESULT_OK: switch (requestCode) { case Settings.REQUEST_CONTACT: // retrieve contact data Uri contactData = data.getData(); // initialize cursor Cursor c = initializeCursor(activity, contactData); if (c != null && c.moveToFirst()) { ArrayList<String> nums, options; // get display name String name = c.getString(c.getColumnIndex( ContactsContract.Contacts.DISPLAY_NAME)); Log.d(this.getClass().getName(), "Selected " + name); // check for phone numbers int hasPhoneNumber = Integer.parseInt(c.getString(c.getColumnIndex( ContactsContract.Contacts.HAS_PHONE_NUMBER))); if (hasPhoneNumber == 0) { return; } else { // iterate through phone numbers String id = c.getString(c.getColumnIndex(BaseColumns._ID)); Cursor pCur = activity.getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[] { id }, null); if (pCur == null) { Toast.makeText(activity, "An unexpected error has occurred.", Toast.LENGTH_SHORT).show(); return; } options = new ArrayList<>(); nums = new ArrayList<>(); while (pCur.moveToNext()) { // add phone numbers to options int type = pCur.getInt(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE)); int typeRes = ContactsContract.CommonDataKinds.Phone.getTypeLabelResource(type); String typeStr = this.getString(typeRes); // set phone label if (type == ContactsContract.CommonDataKinds.BaseTypes.TYPE_CUSTOM) { typeStr = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LABEL)); if (typeStr == null || typeStr.equals("")) { typeStr = "Custom"; } } String number = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)) .replaceAll("[^0-9]", ""); String formattedNumber = Settings.formatSource(number); if (typeStr == null || typeStr.equals("")) { options.add("Other: " + formattedNumber); } else { options.add(typeStr + ": " + formattedNumber); } nums.add(number); } pCur.close(); } c.close(); showPhoneNumberDialog(name, options, nums); } break; case Settings.REQUEST_ADD_CONTACT: activity.sendBroadcast(new Intent(Settings.ACTION_CONVERSATION)); break; } break; default: break; } } private Cursor initializeCursor(Context context, Uri contactData) { CursorLoader cl = new CursorLoader(context, contactData, null, null, null, null); return cl.loadInBackground(); } private void showPhoneNumberDialog(final String name, final ArrayList<String> options, final ArrayList<String> nums) { final CharSequence[] items = options.toArray(new String[options.size()]); AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setTitle(name) .setItems(items, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String source = nums.get(which); callback.onSourceSelected(source); } }); AlertDialog dialog = builder.create(); dialog.show(); } private void addConversation() { Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI); startActivityForResult(intent, Settings.REQUEST_CONTACT); } /** * Compares conversations by time of last update */ class ConversationComparator implements Comparator<Conversation> { @Override public int compare(Conversation c1, Conversation c2) { return c1.getTime() < c2.getTime() ? 1 : c1.getTime() == c2.getTime() ? 0 : -1; } } /** * Broadcast receiver to update UI */ private BroadcastReceiver conversationReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { DatabaseHandler dbHandler = new DatabaseHandler(context); // update adapter conversationAdapter.clear(); conversationAdapter.addAll(dbHandler.getConversationList()); conversationAdapter.sort(new ConversationComparator()); dbHandler.close(); } }; private final class ActionModeCallback implements ActionMode.Callback { private Context context; public ActionModeCallback(Context context) { this.context = context; } @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { conversationAdapter.enterMultiMode(); // save global action mode actionMode = mode; return true; } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { // remove previous items menu.clear(); final int checked = conversationAdapter.getCheckedItemCount(); // update title with number of checked items mode.setTitle(checked + " selected"); switch (checked) { case 0: // if nothing checked - exit action mode mode.finish(); return true; default: // inflate selection menu activity.getMenuInflater().inflate(R.menu.conversations_selected, menu); return true; } } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.action_discard: int count = conversationAdapter.getCheckedItemCount(); String message = "Delete " + count; if (count == 1) { message += " conversation?"; } else { message += " conversations?"; } // initialize list of checked items and iterator starting at the end final LinkedList<Conversation> checkedList = new LinkedList<>(conversationAdapter.getCheckedItems()); AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle("Delete") .setMessage(message) .setPositiveButton("Delete", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { deleteSelectedConversations(context, checkedList); } }) .setNegativeButton("Cancel", null); AlertDialog dialog = builder.create(); dialog.show(); if (actionMode != null) { actionMode.finish(); } return true; default: return false; } } @Override public void onDestroyActionMode(ActionMode mode) { conversationAdapter.exitMultiMode(); actionMode = null; } private void deleteSelectedConversations(Context context, LinkedList<Conversation> checkedList) { DatabaseHandler dbHandler = new DatabaseHandler(context); // iterate through selected items and delete them for (Conversation conversation : checkedList) { dbHandler.deleteConversation(conversation.getSource()); dbHandler.deleteMessages(conversation.getSource()); conversationAdapter.remove(conversation); } dbHandler.close(); } } }