com.bccs.bsecure.Conversation.java Source code

Java tutorial

Introduction

Here is the source code for com.bccs.bsecure.Conversation.java

Source

package com.bccs.bsecure;

import android.app.DialogFragment;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.DataSetObserver;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

/*
 * This file is part of Bsecure. A open source, freely available, SMS encryption app.
 * Copyright (C) 2015 Dr Kevin Coogan, Shane Nalezyty, Lucas Burdell
 * <p/>
 * Bsecure is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * <p/>
 * Bsecure 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.
 * <p/>
 * You should have received a copy of the GNU General Public License
 * along with Bsecure.  If not, see <http://www.gnu.org/licenses/>.
 */

/** Created by lucas.burdell 6/4/2015.
 * Handles conversation between user and another phone. Sent messages are
 * displayed using the "sentmessage.xml" layout and received messages are
 * displayed using the "receivedmessage.xml" layout.
 *
 * Modified by lucas.burdell 6/12/2015.
 * Now checks whether a message was encrypted or not when it was sent/received.
 * Sent and received messages that were not encrypted are displayed using the
 * "sentmessagenoenc.xml" and "receivedmessagenoenc.xml" layouts.
 */

public class Conversation extends ActionBarActivity
        implements WipeConversationDialog.WipeConversationDialogListener {
    Contact currentNumber;
    boolean receiversRegistered = false; // track if receivers are registered or not
    ArrayList<String> conversation;
    EditText typeMessage;
    Button send;

    private ListView listView;
    private chatAdapter chatAdapter;

    //Receiver for detecting if a message was received by the main smsBroadcastReceiver.
    //Subclassed the smsBroadcastReceiver rather than BroadcastReceiver
    //for some convenience that is no longer apparent.
    SmsBroadcastReceiver onNewMsg = new SmsBroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getLongExtra("contactid", -1) == currentNumber.getId()) {
                updateConvo();
            }
        }
    };

    //Filter to catch broadcasts from the main smsBroadcastReceiver when an SMS is received.
    IntentFilter onNewMsgFilter = new IntentFilter("com.bccs.bsecure.msgReceived");

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        //If convo was opened from the main view, it will have a number value in the intent
        //currentNumber variable is used when loading messages from the DB.
        if (getIntent().hasExtra("contactid")) {
            currentNumber = new Contact(getIntent().getLongExtra("contactid", -1));
            //Cancel any notifications for this number
            if (currentNumber.getId() == SmsBroadcastReceiver.recentID)
                MessageReceivedNotification.cancel(this);
        } else {
            //If it was not opened from the main view, use the most recent number an SMS
            //was received from.
            currentNumber = new Contact(SmsBroadcastReceiver.recentID);
        }

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_conversation);
        setTitle(currentNumber.getName());

        conversation = new ArrayList<>();
        typeMessage = (EditText) findViewById(R.id.messageEditText);
        listView = (ListView) findViewById(R.id.contactListView);
        send = (Button) findViewById(R.id.sendButton);

        chatAdapter = new chatAdapter();
        listView.setAdapter(chatAdapter);
        // Create the on-click listener for the send button
        send.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                String message = typeMessage.getText().toString();
                typeMessage.setText("");

                if (currentNumber.getNumber().length() > 0 && message.length() > 0) {
                    MyMessage msgObj = HandleMessage.send(currentNumber.getId(), message, getApplicationContext());
                    ConversationManager.ConversationHelper helper = ConversationManager
                            .getConversation(Conversation.this, currentNumber.getId());
                    helper.addMessage(msgObj);
                    updateConvo();
                }
            }
        });

        // Scrolls to the bottom in the event of data change.
        listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
        chatAdapter.registerDataSetObserver(new DataSetObserver() {
            @Override
            public void onChanged() {
                super.onChanged();
                listView.setSelection(chatAdapter.getCount());
            }
        });

        findViewById(R.id.wipeConversation).setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                WipeConversationDialog dialog = new WipeConversationDialog();
                dialog.show(getFragmentManager(), "conversation_option");
            }
        });

        //Register our receiver in the LocalBroadcastManager.
        //NOTE this is different from calling registerReceiver from the contextWrapper.
        LocalBroadcastManager.getInstance(this).registerReceiver(onNewMsg, onNewMsgFilter);
        receiversRegistered = true;

        updateConvo();
    }

    /*
                dbHelper helper = new dbHelper(Conversation.this);
            helper.clearMessagesFromNumber(currentNumber);
            helper.close();
            Intent intent = new Intent(Conversation.this, Main.class);
            startActivity(intent);
     */

    /**
     * This method updates the chat with new messages and will filter out duplicates.
     */
    private void updateConvo() {

        ConversationManager.ConversationHelper helper = ConversationManager.getConversation(this,
                currentNumber.getId());
        ArrayList<MyMessage> checkConversation = helper.getMessages(chatAdapter.getCount());

        for (MyMessage m : checkConversation) {
            chatAdapter.addItem(m, m.getSent(), m.is_encrypted());
        }
    }

    protected void onStart() {

        if (!receiversRegistered) {
            LocalBroadcastManager.getInstance(this).registerReceiver(onNewMsg, onNewMsgFilter);
            receiversRegistered = true;
        }
        super.onStart();
    }

    protected void onResume() {

        if (!receiversRegistered) {
            LocalBroadcastManager.getInstance(this).registerReceiver(onNewMsg, onNewMsgFilter);
            receiversRegistered = true;
        }
        super.onResume();
    }

    protected void onPause() {

        if (receiversRegistered) {
            LocalBroadcastManager.getInstance(this).unregisterReceiver(onNewMsg);
            receiversRegistered = false;
        }

        super.onPause();
    }

    protected void onStop() {

        if (receiversRegistered) {
            LocalBroadcastManager.getInstance(this).unregisterReceiver(onNewMsg);
            receiversRegistered = false;
        }
        super.onStop();
    }

    protected void onDestroy() {

        if (receiversRegistered) {
            LocalBroadcastManager.getInstance(this).unregisterReceiver(onNewMsg);
            receiversRegistered = false;
        }
        super.onDestroy();
    }

    @Override
    public void onOKPressed(DialogFragment dialog) {
        ConversationManager.ConversationHelper helper = ConversationManager.getConversation(this,
                currentNumber.getId());
        helper.deleteConversation();
        dialog.dismiss();
        Intent intent = new Intent(Conversation.this, Main.class);
        startActivity(intent);
    }

    @Override
    public void onCancelPressed(DialogFragment dialog) {
        dialog.dismiss();
    }

    // Custom Adapter to display the differing layouts for chat.
    private class chatAdapter extends BaseAdapter {

        //Possibility to add more types
        private static final int SENT = 0;
        private static final int RECEIVED = 1;
        private static final int SENT_NOENC = 2;
        private static final int RECEIVED_NOENC = 3;
        private static final int MAX_TYPES = 4;

        private ArrayList<MyMessage> chatArray = new ArrayList<>();
        private LayoutInflater inflater;
        private ArrayList<Integer> typeArray = new ArrayList<>();

        public chatAdapter() {
            //create inflater that will hold the chat boxes
            inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        }

        public void addItem(MyMessage message, boolean isSent, boolean isEncrypted) {
            chatArray.add(message);
            int type;
            if (!isEncrypted) {
                type = isSent ? SENT_NOENC : RECEIVED_NOENC;
            } else {
                type = isSent ? SENT : RECEIVED;
            }
            typeArray.add(type);
            notifyDataSetChanged();
        }

        public ArrayList<MyMessage> getChatArray() {
            ArrayList<MyMessage> newChat = new ArrayList<>();
            for (MyMessage m : chatArray) {
                newChat.add(m);
            }
            return newChat;
        }

        @Override
        public int getItemViewType(int position) {
            return typeArray.get(position);
        }

        @Override
        public int getViewTypeCount() {
            return MAX_TYPES;
        }

        @Override
        public int getCount() {
            return chatArray.size();
        }

        @Override
        public MyMessage getItem(int position) {
            return chatArray.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            FrameLayout holder = null;
            int type = getItemViewType(position);
            if (convertView == null) {
                switch (type) {
                case SENT:
                    convertView = inflater.inflate(R.layout.sentmessage, null);
                    holder = (FrameLayout) ((LinearLayout) convertView).getChildAt(0);
                    break;
                case RECEIVED:
                    convertView = inflater.inflate(R.layout.receivedmessage, null);
                    holder = (FrameLayout) ((LinearLayout) convertView).getChildAt(0);
                    break;
                case SENT_NOENC:
                    convertView = inflater.inflate(R.layout.sentmessagenoenc, null);
                    holder = (FrameLayout) ((LinearLayout) convertView).getChildAt(0);
                    break;
                case RECEIVED_NOENC:
                    convertView = inflater.inflate(R.layout.receivedmessagenoenc, null);
                    holder = (FrameLayout) ((LinearLayout) convertView).getChildAt(0);
                    break;
                }
            } else {
                holder = (FrameLayout) ((LinearLayout) convertView).getChildAt(0);
            }
            MyMessage msg = getItem(position);
            TextView text = (TextView) ((LinearLayout) holder.getChildAt(0)).getChildAt(0);
            TextView date = (TextView) holder.getChildAt(1);
            String dateText = (SimpleDateFormat.getDateTimeInstance()).format(new Date(msg.get_time()));
            text.setText(msg.getBody());
            date.setText(dateText);
            return convertView;
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        //getMenuInflater().inflate(R.menu.menu_conversation, menu);
        getMenuInflater().inflate(R.menu.menu_conservative, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        onBackPressed();
        return true;
    }
}