i am trying to make an android application which includes : Text and Audio chat + File transfer over Wifi connection (WLAN), i found a Source code of the Audio chat and i managed to get it work after few struggles, and i was wondering if i could some how add the Text Chat and the file transfer to This code here the source Code : UDP Audio Chat and these are the classes :
AudioCall.java
package hw.dt83.udpchat;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.util.Log;
public class AudioCall {
private static final String LOG_TAG = "AudioCall";
private static final int SAMPLE_RATE = 8000; // Hertz
private static final int SAMPLE_INTERVAL = 20; // Milliseconds
private static final int SAMPLE_SIZE = 2; // Bytes
private static final int BUF_SIZE = SAMPLE_INTERVAL * SAMPLE_INTERVAL * SAMPLE_SIZE * 2; //Bytes
private InetAddress address; // Address to call
private int port = 50000; // Port the packets are addressed to
private boolean mic = false; // Enable mic?
private boolean speakers = false; // Enable speakers?
public AudioCall(InetAddress address) {
this.address = address;
}
public void startCall() {
startMic();
startSpeakers();
}
public void endCall() {
Log.i(LOG_TAG, "Ending call!");
muteMic();
muteSpeakers();
}
public void muteMic() {
mic = false;
}
public void muteSpeakers() {
speakers = false;
}
public void startMic() {
// Creates the thread for capturing and transmitting audio
mic = true;
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
// Create an instance of the AudioRecord class
Log.i(LOG_TAG, "Send thread started. Thread id: " + Thread.currentThread().getId());
AudioRecord audioRecorder = new AudioRecord (MediaRecorder.AudioSource.MIC, SAMPLE_RATE,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,
AudioRecord.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT)*10);
int bytes_read = 0;
int bytes_sent = 0;
byte[] buf = new byte[BUF_SIZE];
try {
// Create a socket and start recording
Log.i(LOG_TAG, "Packet destination: " + address.toString());
DatagramSocket socket = new DatagramSocket();
audioRecorder.startRecording();
while(mic) {
// Capture audio from the mic and transmit it
bytes_read = audioRecorder.read(buf, 0, BUF_SIZE);
DatagramPacket packet = new DatagramPacket(buf, bytes_read, address, port);
socket.send(packet);
bytes_sent += bytes_read;
Log.i(LOG_TAG, "Total bytes sent: " + bytes_sent);
Thread.sleep(SAMPLE_INTERVAL, 0);
}
// Stop recording and release resources
audioRecorder.stop();
audioRecorder.release();
socket.disconnect();
socket.close();
mic = false;
return;
}
catch(InterruptedException e) {
Log.e(LOG_TAG, "InterruptedException: " + e.toString());
mic = false;
}
catch(SocketException e) {
Log.e(LOG_TAG, "SocketException: " + e.toString());
mic = false;
}
catch(UnknownHostException e) {
Log.e(LOG_TAG, "UnknownHostException: " + e.toString());
mic = false;
}
catch(IOException e) {
Log.e(LOG_TAG, "IOException: " + e.toString());
mic = false;
}
}
});
thread.start();
}
public void startSpeakers() {
// Creates the thread for receiving and playing back audio
if(!speakers) {
speakers = true;
Thread receiveThread = new Thread(new Runnable() {
@Override
public void run() {
// Create an instance of AudioTrack, used for playing back audio
Log.i(LOG_TAG, "Receive thread started. Thread id: " + Thread.currentThread().getId());
AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, BUF_SIZE, AudioTrack.MODE_STREAM);
track.play();
try {
// Define a socket to receive the audio
DatagramSocket socket = new DatagramSocket(port);
byte[] buf = new byte[BUF_SIZE];
while(speakers) {
// Play back the audio received from packets
DatagramPacket packet = new DatagramPacket(buf, BUF_SIZE);
socket.receive(packet);
Log.i(LOG_TAG, "Packet received: " + packet.getLength());
track.write(packet.getData(), 0, BUF_SIZE);
}
// Stop playing back and release resources
socket.disconnect();
socket.close();
track.stop();
track.flush();
track.release();
speakers = false;
return;
}
catch(SocketException e) {
Log.e(LOG_TAG, "SocketException: " + e.toString());
speakers = false;
}
catch(IOException e) {
Log.e(LOG_TAG, "IOException: " + e.toString());
speakers = false;
}
}
});
receiveThread.start();
}
}
}
MainActivity.java
package hw.dt83.udpchat;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.HashMap;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.ScrollView;
import android.widget.TextView;
public class MainActivity extends Activity {
static final String LOG_TAG = "UDPchat";
private static final int LISTENER_PORT = 50003;
private static final int BUF_SIZE = 1024;
private ContactManager contactManager;
private String displayName;
private boolean STARTED = false;
private boolean IN_CALL = false;
private boolean LISTEN = false;
public final static String EXTRA_CONTACT = "hw.dt83.udpchat.CONTACT";
public final static String EXTRA_IP = "hw.dt83.udpchat.IP";
public final static String EXTRA_DISPLAYNAME = "hw.dt83.udpchat.DISPLAYNAME";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(LOG_TAG, "UDPChat started");
// START BUTTON
// Pressing this buttons initiates the main functionality
final Button btnStart = (Button) findViewById(R.id.buttonStart);
btnStart.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.i(LOG_TAG, "Start button pressed");
STARTED = true;
EditText displayNameText = (EditText) findViewById(R.id.editTextDisplayName);
displayName = displayNameText.getText().toString();
displayNameText.setEnabled(false);
btnStart.setEnabled(false);
TextView text = (TextView) findViewById(R.id.textViewSelectContact);
text.setVisibility(View.VISIBLE);
Button updateButton = (Button) findViewById(R.id.buttonUpdate);
updateButton.setVisibility(View.VISIBLE);
Button callButton = (Button) findViewById(R.id.buttonCall);
callButton.setVisibility(View.VISIBLE);
ScrollView scrollView = (ScrollView) findViewById(R.id.scrollView);
scrollView.setVisibility(View.VISIBLE);
contactManager = new ContactManager(displayName, getBroadcastIp());
startCallListener();
}
});
// UPDATE BUTTON
// Updates the list of reachable devices
final Button btnUpdate = (Button) findViewById(R.id.buttonUpdate);
btnUpdate.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
updateContactList();
}
});
// CALL BUTTON
// Attempts to initiate an audio chat session with the selected device
final Button btnCall = (Button) findViewById(R.id.buttonCall);
btnCall.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
RadioGroup radioGroup = (RadioGroup) findViewById(R.id.contactList);
int selectedButton = radioGroup.getCheckedRadioButtonId();
if(selectedButton == -1) {
// If no device was selected, present an error message to the user
Log.w(LOG_TAG, "Warning: no contact selected");
final AlertDialog alert = new AlertDialog.Builder(MainActivity.this).create();
alert.setTitle("Oops");
alert.setMessage("You must select a contact first");
alert.setButton(-1, "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
alert.dismiss();
}
});
alert.show();
return;
}
// Collect details about the selected contact
RadioButton radioButton = (RadioButton) findViewById(selectedButton);
String contact = radioButton.getText().toString();
InetAddress ip = contactManager.getContacts().get(contact);
IN_CALL = true;
// Send this information to the MakeCallActivity and start that activity
Intent intent = new Intent(MainActivity.this, MakeCallActivity.class);
intent.putExtra(EXTRA_CONTACT, contact);
String address = ip.toString();
address = address.substring(1, address.length());
intent.putExtra(EXTRA_IP, address);
intent.putExtra(EXTRA_DISPLAYNAME, displayName);
startActivity(intent);
}
});
}
private void updateContactList() {
// Create a copy of the HashMap used by the ContactManager
HashMap<String, InetAddress> contacts = contactManager.getContacts();
// Create a radio button for each contact in the HashMap
RadioGroup radioGroup = (RadioGroup) findViewById(R.id.contactList);
radioGroup.removeAllViews();
for(String name : contacts.keySet()) {
RadioButton radioButton = new RadioButton(getBaseContext());
radioButton.setText(name);
radioButton.setTextColor(Color.BLACK);
radioGroup.addView(radioButton);
}
radioGroup.clearCheck();
}
private InetAddress getBroadcastIp() {
// Function to return the broadcast address, based on the IP address of the device
try {
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
String addressString = toBroadcastIp(ipAddress);
InetAddress broadcastAddress = InetAddress.getByName(addressString);
return broadcastAddress;
}
catch(UnknownHostException e) {
Log.e(LOG_TAG, "UnknownHostException in getBroadcastIP: " + e);
return null;
}
}
private String toBroadcastIp(int ip) {
// Returns converts an IP address in int format to a formatted string
return (ip & 0xFF) + "." +
((ip >> 8) & 0xFF) + "." +
((ip >> 16) & 0xFF) + "." +
"255";
}
private void startCallListener() {
// Creates the listener thread
LISTEN = true;
Thread listener = new Thread(new Runnable() {
@Override
public void run() {
try {
// Set up the socket and packet to receive
Log.i(LOG_TAG, "Incoming call listener started");
DatagramSocket socket = new DatagramSocket(LISTENER_PORT);
socket.setSoTimeout(1000);
byte[] buffer = new byte[BUF_SIZE];
DatagramPacket packet = new DatagramPacket(buffer, BUF_SIZE);
while(LISTEN) {
// Listen for incoming call requests
try {
Log.i(LOG_TAG, "Listening for incoming calls");
socket.receive(packet);
String data = new String(buffer, 0, packet.getLength());
Log.i(LOG_TAG, "Packet received from "+ packet.getAddress() +" with contents: " + data);
String action = data.substring(0, 4);
if(action.equals("CAL:")) {
// Received a call request. Start the ReceiveCallActivity
String address = packet.getAddress().toString();
String name = data.substring(4, packet.getLength());
Intent intent = new Intent(MainActivity.this, ReceiveCallActivity.class);
intent.putExtra(EXTRA_CONTACT, name);
intent.putExtra(EXTRA_IP, address.substring(1, address.length()));
IN_CALL = true;
//LISTEN = false;
//stopCallListener();
startActivity(intent);
}
else {
// Received an invalid request
Log.w(LOG_TAG, packet.getAddress() + " sent invalid message: " + data);
}
}
catch(Exception e) {}
}
Log.i(LOG_TAG, "Call Listener ending");
socket.disconnect();
socket.close();
}
catch(SocketException e) {
Log.e(LOG_TAG, "SocketException in listener " + e);
}
}
});
listener.start();
}
private void stopCallListener() {
// Ends the listener thread
LISTEN = false;
}
@Override
public void onPause() {
super.onPause();
if(STARTED) {
contactManager.bye(displayName);
contactManager.stopBroadcasting();
contactManager.stopListening();
//STARTED = false;
}
stopCallListener();
Log.i(LOG_TAG, "App paused!");
}
@Override
public void onStop() {
super.onStop();
Log.i(LOG_TAG, "App stopped!");
stopCallListener();
if(!IN_CALL) {
finish();
}
}
@Override
public void onRestart() {
super.onRestart();
Log.i(LOG_TAG, "App restarted!");
IN_CALL = false;
STARTED = true;
contactManager = new ContactManager(displayName, getBroadcastIp());
startCallListener();
}
}
MaleCallActivity
package hw.dt83.udpchat;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MakeCallActivity extends Activity {
private static final String LOG_TAG = "MakeCall";
private static final int BROADCAST_PORT = 50002;
private static final int BUF_SIZE = 1024;
private String displayName;
private String contactName;
private String contactIp;
private boolean LISTEN = true;
private boolean IN_CALL = false;
private AudioCall call;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_make_call);
Log.i(LOG_TAG, "MakeCallActivity started!");
Intent intent = getIntent();
displayName = intent.getStringExtra(MainActivity.EXTRA_DISPLAYNAME);
contactName = intent.getStringExtra(MainActivity.EXTRA_CONTACT);
contactIp = intent.getStringExtra(MainActivity.EXTRA_IP);
TextView textView = (TextView) findViewById(R.id.textViewCalling);
textView.setText("Calling: " + contactName);
startListener();
makeCall();
Button endButton = (Button) findViewById(R.id.buttonEndCall);
endButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Button to end the call has been pressed
endCall();
}
});
}
private void makeCall() {
// Send a request to start a call
sendMessage("CAL:"+displayName, 50003);
}
private void endCall() {
// Ends the chat sessions
stopListener();
if(IN_CALL) {
call.endCall();
}
sendMessage("END:", BROADCAST_PORT);
finish();
}
private void startListener() {
// Create listener thread
LISTEN = true;
Thread listenThread = new Thread(new Runnable() {
@Override
public void run() {
try {
Log.i(LOG_TAG, "Listener started!");
DatagramSocket socket = new DatagramSocket(BROADCAST_PORT);
socket.setSoTimeout(15000);
byte[] buffer = new byte[BUF_SIZE];
DatagramPacket packet = new DatagramPacket(buffer, BUF_SIZE);
while(LISTEN) {
try {
Log.i(LOG_TAG, "Listening for packets");
socket.receive(packet);
String data = new String(buffer, 0, packet.getLength());
Log.i(LOG_TAG, "Packet received from "+ packet.getAddress() +" with contents: " + data);
String action = data.substring(0, 4);
if(action.equals("ACC:")) {
// Accept notification received. Start call
call = new AudioCall(packet.getAddress());
call.startCall();
IN_CALL = true;
}
else if(action.equals("REJ:")) {
// Reject notification received. End call
endCall();
}
else if(action.equals("END:")) {
// End call notification received. End call
endCall();
}
else {
// Invalid notification received
Log.w(LOG_TAG, packet.getAddress() + " sent invalid message: " + data);
}
}
catch(SocketTimeoutException e) {
if(!IN_CALL) {
Log.i(LOG_TAG, "No reply from contact. Ending call");
endCall();
return;
}
}
catch(IOException e) {
}
}
Log.i(LOG_TAG, "Listener ending");
socket.disconnect();
socket.close();
return;
}
catch(SocketException e) {
Log.e(LOG_TAG, "SocketException in Listener");
endCall();
}
}
});
listenThread.start();
}
private void stopListener() {
// Ends the listener thread
LISTEN = false;
}
private void sendMessage(final String message, final int port) {
// Creates a thread used for sending notifications
Thread replyThread = new Thread(new Runnable() {
@Override
public void run() {
try {
InetAddress address = InetAddress.getByName(contactIp);
byte[] data = message.getBytes();
DatagramSocket socket = new DatagramSocket();
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
socket.send(packet);
Log.i(LOG_TAG, "Sent message( " + message + " ) to " + contactIp);
socket.disconnect();
socket.close();
}
catch(UnknownHostException e) {
Log.e(LOG_TAG, "Failure. UnknownHostException in sendMessage: " + contactIp);
}
catch(SocketException e) {
Log.e(LOG_TAG, "Failure. SocketException in sendMessage: " + e);
}
catch(IOException e) {
Log.e(LOG_TAG, "Failure. IOException in sendMessage: " + e);
}
}
});
replyThread.start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.make_call, menu);
return true;
}
}
ReceiveCallActivity
package hw.dt83.udpchat;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class ReceiveCallActivity extends Activity {
private static final String LOG_TAG = "ReceiveCall";
private static final int BROADCAST_PORT = 50002;
private static final int BUF_SIZE = 1024;
private String contactIp;
private String contactName;
private boolean LISTEN = true;
private boolean IN_CALL = false;
private AudioCall call;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_receive_call);
Intent intent = getIntent();
contactName = intent.getStringExtra(MainActivity.EXTRA_CONTACT);
contactIp = intent.getStringExtra(MainActivity.EXTRA_IP);
TextView textView = (TextView) findViewById(R.id.textViewIncomingCall);
textView.setText("Incoming call: " + contactName);
final Button endButton = (Button) findViewById(R.id.buttonEndCall1);
endButton.setVisibility(View.INVISIBLE);
startListener();
// ACCEPT BUTTON
Button acceptButton = (Button) findViewById(R.id.buttonAccept);
acceptButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
// Accepting call. Send a notification and start the call
sendMessage("ACC:");
InetAddress address = InetAddress.getByName(contactIp);
Log.i(LOG_TAG, "Calling " + address.toString());
IN_CALL = true;
call = new AudioCall(address);
call.startCall();
// Hide the buttons as they're not longer required
Button accept = (Button) findViewById(R.id.buttonAccept);
accept.setEnabled(false);
Button reject = (Button) findViewById(R.id.buttonReject);
reject.setEnabled(false);
endButton.setVisibility(View.VISIBLE);
}
catch(UnknownHostException e) {
Log.e(LOG_TAG, "UnknownHostException in acceptButton: " + e);
}
catch(Exception e) {
Log.e(LOG_TAG, "Exception in acceptButton: " + e);
}
}
});
// REJECT BUTTON
Button rejectButton = (Button) findViewById(R.id.buttonReject);
rejectButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Send a reject notification and end the call
sendMessage("REJ:");
endCall();
}
});
// END BUTTON
endButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
endCall();
}
});
}
private void endCall() {
// End the call and send a notification
stopListener();
if(IN_CALL) {
call.endCall();
}
sendMessage("END:");
finish();
}
private void startListener() {
// Creates the listener thread
LISTEN = true;
Thread listenThread = new Thread(new Runnable() {
@Override
public void run() {
try {
Log.i(LOG_TAG, "Listener started!");
DatagramSocket socket = new DatagramSocket(BROADCAST_PORT);
socket.setSoTimeout(1500);
byte[] buffer = new byte[BUF_SIZE];
DatagramPacket packet = new DatagramPacket(buffer, BUF_SIZE);
while(LISTEN) {
try {
Log.i(LOG_TAG, "Listening for packets");
socket.receive(packet);
String data = new String(buffer, 0, packet.getLength());
Log.i(LOG_TAG, "Packet received from "+ packet.getAddress() +" with contents: " + data);
String action = data.substring(0, 4);
if(action.equals("END:")) {
// End call notification received. End call
endCall();
}
else {
// Invalid notification received.
Log.w(LOG_TAG, packet.getAddress() + " sent invalid message: " + data);
}
}
catch(IOException e) {
Log.e(LOG_TAG, "IOException in Listener " + e);
}
}
Log.i(LOG_TAG, "Listener ending");
socket.disconnect();
socket.close();
return;
}
catch(SocketException e) {
Log.e(LOG_TAG, "SocketException in Listener " + e);
endCall();
}
}
});
listenThread.start();
}
private void stopListener() {
// Ends the listener thread
LISTEN = false;
}
private void sendMessage(final String message) {
// Creates a thread for sending notifications
Thread replyThread = new Thread(new Runnable() {
@Override
public void run() {
try {
InetAddress address = InetAddress.getByName(contactIp);
byte[] data = message.getBytes();
DatagramSocket socket = new DatagramSocket();
DatagramPacket packet = new DatagramPacket(data, data.length, address, BROADCAST_PORT);
socket.send(packet);
Log.i(LOG_TAG, "Sent message( " + message + " ) to " + contactIp);
socket.disconnect();
socket.close();
}
catch(UnknownHostException e) {
Log.e(LOG_TAG, "Failure. UnknownHostException in sendMessage: " + contactIp);
}
catch(SocketException e) {
Log.e(LOG_TAG, "Failure. SocketException in sendMessage: " + e);
}
catch(IOException e) {
Log.e(LOG_TAG, "Failure. IOException in sendMessage: " + e);
}
}
});
replyThread.start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.receive_call, menu);
return true;
}
}
Aucun commentaire:
Enregistrer un commentaire