Hello, I want to design a two-way telephone connection using socket.io in Android and socket in node.js, which takes the sound from the source phone and sends it to the destination phone in runtime, and instantly sends the sound from the source and sends bytes to the destination. Convert the transmission to audio and play the audio ! , The voice is sent to the server, but the server does not send the information to the destination!
public class VoiceCallActivity extends AppCompatActivity {
private static final String LOG_TAG = "socket_main_act";
private static final int REQUEST_RECORD_AUDIO_PERMISSION = 200;
private static final int SAMPLING_RATE = 22050;
private MediaPlayer mediaPlayer = new MediaPlayer();
private MediaRecorder recorder = new MediaRecorder();
private boolean permissionToRecord = false;
private String[] permissions = {Manifest.permission.RECORD_AUDIO};
private Socket mSocket;
private void startRecording(Socket socket) {
Log.i(LOG_TAG, "start recording.");
try {
ParcelFileDescriptor[] descriptors = new ParcelFileDescriptor[0];
try {
descriptors = ParcelFileDescriptor.createPipe();
} catch (IOException e) {
e.printStackTrace();
}
ParcelFileDescriptor recorderRead = new ParcelFileDescriptor(descriptors[0]);
ParcelFileDescriptor recorderWrite = new ParcelFileDescriptor(descriptors[1]);
InputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream(recorderRead);
Log.i(LOG_TAG, "Setup IO.");
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC_ELD);
recorder.setOutputFile(recorderWrite.getFileDescriptor());
recorder.setAudioSamplingRate(SAMPLING_RATE);
Log.i(LOG_TAG, "Setup recorder.");
recorder.prepare();
recorder.start();
Log.i(LOG_TAG, "Start recording.");
int read = 1;
byte[] data = new byte[SAMPLING_RATE];
while (read != -1) {
read = inputStream.read(data, 0, data.length);
JSONObject obj = new JSONObject();
try {
obj.put("data", 1);
socket.emit("audio_give", obj);
} catch (JSONException e) {
e.printStackTrace();
}
}
Log.i(LOG_TAG, "Data from recorder exhausted.");
} catch (IOException e) {
e.printStackTrace();
Log.e(LOG_TAG, "Recording faults");
}
}
public Emitter.Listener onAudioBroadcast = new Emitter.Listener() {
#Override
public void call(final Object... args) {
runOnUiThread(new Runnable() {
#Override
public void run() {
byte[] data = Base64.decode(args[0].toString(), Base64.DEFAULT);
Log.e("TAG", "call: args = " + args[0]);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream os;
try {
/* os = new ObjectOutputStream(out);
for (Object arg : args) {
os.writeObject(arg);
}
data = out.toByteArray();*/
Log.i(LOG_TAG, "Read data as byte array.");
AudioDataSource src = new AudioDataSource(data);
Log.i(LOG_TAG, "Setup player and src");
AudioAttributes attr = new AudioAttributes.Builder()
.setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.build();
Log.i(LOG_TAG, "Setup attributes");
mediaPlayer.setAudioAttributes(attr);
Log.i(LOG_TAG, "Player set with attributes.");
mediaPlayer.setDataSource(src);
Log.i(LOG_TAG, "Player read from source");
mediaPlayer.prepare();
Log.i(LOG_TAG, "prepare player.");
mediaPlayer.start();
Log.i(LOG_TAG, "Start playing.");
} catch (IOException e) {
Log.e(LOG_TAG, "Player failed to stream audio: " + e.toString());
e.printStackTrace();
}
}
});
}
};
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_RECORD_AUDIO_PERMISSION:
permissionToRecord = grantResults[0] == PackageManager.PERMISSION_GRANTED;
break;
}
if (!permissionToRecord) finish();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityCompat.requestPermissions(this, permissions, REQUEST_RECORD_AUDIO_PERMISSION);
setContentView(R.layout.activity_main);
try {
IO.Options opts = new IO.Options();
opts.reconnection = true;
opts.port = 3000;
opts.timeout = 15000;
opts.reconnectionDelay = 10000;
mSocket = IO.socket("http://192.168.2.1:3000", opts);
mSocket.on("audio_receiver", onAudioBroadcast);
mSocket.on(Socket.EVENT_CONNECT, onConnect);
mSocket.on(Socket.EVENT_DISCONNECT, onDisconnect);
mSocket.on(Socket.EVENT_CONNECT_ERROR, onConnectError);
mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);
mSocket.connect();
startRecording(mSocket);
} catch (URISyntaxException e) {
Log.d(LOG_TAG, "uri is invalid.");
}
}
Emitter.Listener onConnect = new Emitter.Listener() {
#Override
public void call(Object... args) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.e("TAG", "run: onConnect");
runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
}
});
}
};
Emitter.Listener onDisconnect = new Emitter.Listener() {
#Override
public void call(Object... args) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.e("TAG", "run: onDisconnect");
}
});
}
};
Emitter.Listener onConnectError = new Emitter.Listener() {
#Override
public void call(Object... args) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.e("TAG", "run: onConnectError");
}
});
}
};
}
server socket.io node.js code :
const express = require('express');
const app = express();
let http = require('http').Server(app);
let io = require('socket.io')(http);
http.listen(3000, function () {
// Now listening
console.log("listening 3000 !");
});
io.on('connection', function (socket) {
socket.on('audio_give', function (data) {
socket.emit("audio_receiver",{data})
})
})
Related
I want to play multiple speakers at the same time.
In my apllication I'm getting audio from network, decode from C#, decode by opus and then want to play bytes. But now I can play only one speaker.
My AudioPLayer.class:
public class Player {
private static final String TAG = Player.class.getName();
private AudioTrack audioTrack;
private boolean isWorking;
public Player() {
try {
audioTrack = new AudioTrack(
AudioManager.STREAM_MUSIC,
AudioConsts.SAMPLERATE,
AudioConsts.NUM_CHANNELS == 1 ? AudioConsts.CHANNEL_OUT_MONO : AudioConsts.CHANNEL_OUT_STEREO,
AudioConsts.ENCODING_PCM_16BIT,
AudioConsts.GetPlayerBufferSize(),
AudioTrack.MODE_STREAM);
} catch (Exception e){
Log.e(TAG, e.toString());
}
}
public void play() {
new Thread(new Runnable() {
#Override
public void run() {
isWorking = true;
try {
audioTrack.play();
} catch (Exception e) {
Log.d(e.toString(), "AUDIO EXCEPTION");
return;
}
int bufferSize = AudioConsts.GetPlayerBufferSize();
while (isWorking){
int cursor = audioTrack.getPlaybackHeadPosition();
if (cursor > bufferSize){
cursor %= bufferSize;
audioTrack.flush();
audioTrack.setPlaybackHeadPosition(cursor);
}
}
}
}).start();
}
public void stopReading(){
if (!isWorking)
return;
audioTrack.release();
isWorking = false;
}
public void appendForPlayback(byte[] audioMessage, int size) {
if (size != 0){
int writen = audioTrack.write(audioMessage, 0, size);
if (writen != size) {
//audioTrack.release();
Log.d(TAG, "WTF");
}
}
}
}
Also attach my AudioPlayer's initialization:
#Override
public void onCreate() {
super.onCreate();
...
player = new Player();
player.play();
IntentFilter filter = new IntentFilter();
filter.addAction(ON_UNITY_AUDIO_MESSAGE_RECEIVED);
filter.addAction(AudioConsts.START_RECORDER);
filter.addAction(AudioConsts.STOP_RECORDER);
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ON_UNITY_AUDIO_MESSAGE_RECEIVED)) {
byte[] decryptedBytes = intent.getByteArrayExtra(UNITY_AUDIO_MESSAGE);
onUnityAudioReceivedFromNetwork(decryptedBytes);
} else if (intent.getAction().equals(AudioConsts.START_RECORDER)) {
incrementSessionCount();
recorder.startRecording();
} else if (intent.getAction().equals(AudioConsts.STOP_RECORDER)) {
recorder.stopRecording();
}
}
};
registerReceiver(broadcastReceiver, filter);
decodeMsg = new byte[AudioConsts.FRAME_SIZE * AudioConsts.ENCODING_PCM_16BIT];
opusDecoder = new OpusDecoder();
opusDecoder.init(AudioConsts.SAMPLERATE, AudioConsts.NUM_CHANNELS);
}
...
private void onUnityAudioReceivedFromNetwork(byte[] decryptedBytes) {
UnityAudioMessage audioMessage = UnityAudioMessage.fromBytesSharp(decryptedBytes);
if (audioMessage != null) {
try {
opusDecoder.decode(audioMessage.unityAudioMessage, decodeMsg, AudioConsts.FRAME_SIZE);
} catch (OpusError e) {
e.printStackTrace();
return;
}
player.appendForPlayback(decodeMsg, decodeMsg.length);
}
}
...
Can I release simultaneos playback of multiple speakers?
Also I tried release it with HaspMap of my players. But it works only like 1 audio track.
I tried a lot of things, but my solution use AsyncTask.class
Attach Player.class
public class Player {
private static final String TAG = Player.class.getName();
private AudioTrack audioTrack;
private boolean isWorking;
public Player() {
try {
audioTrack = new AudioTrack(
new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.setLegacyStreamType(AudioManager.STREAM_MUSIC)
.build(),
new AudioFormat.Builder()
.setChannelMask(AudioFormat.CHANNEL_OUT_MONO)
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
.setSampleRate(AudioConsts.SAMPLERATE)
.build(),
AudioConsts.GetPlayerBufferSize(),
AudioTrack.MODE_STREAM,
AudioManager.AUDIO_SESSION_ID_GENERATE);
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}
public void play() {
audioTrack.play();
}
public void stopReading() {
if (!isWorking)
return;
audioTrack.release();
isWorking = false;
}
public void appendForPlayback(byte[] audioMessage, int size) {
new Executor().doInBackground(audioMessage);
}
private class Executor extends AsyncTask<byte[], Void, Void> {
#Override
protected Void doInBackground(byte[]... bytes) {
for (byte[] audioMessage : bytes) {
if (audioMessage.length != 0) {
int writen = audioTrack.write(audioMessage, 0, audioMessage.length);
if (writen != audioMessage.length) {
Log.d(TAG, "WTF");
}
}
}
return null;
}
}}
I am using Network Service Discovery service to discovery peer and connected to them using socket so , so socket created successfully but i am not able to send message or receive message so below is my code
MainActivity
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private NSDHelper mNsdHelper;
private int port;
private Context mContext;
ChatConnection mConnection;
private Button mDiscover, advertise_btn, connect_btn;
private Handler mUpdateHandler;
private TextView mStatusView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mStatusView = (TextView) findViewById(R.id.status);
mContext = MainActivity.this;
mUpdateHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
String chatLine = msg.getData().getString("msg");
addChatLine(chatLine);
}
};
mConnection = new ChatConnection(mUpdateHandler);
mNsdHelper = new NSDHelper(this);
mNsdHelper.initNSD();
advertise_btn = (Button) findViewById(R.id.advertise_btn);
connect_btn = (Button) findViewById(R.id.connect_btn);
advertise_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Register service
if (mConnection.getLocalPort() > -1) {
mNsdHelper.registerService(mConnection.getLocalPort());
} else {
Log.d(TAG, "ServerSocket isn't bound.");
}
}
});
connect_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
NsdServiceInfo service = mNsdHelper.getChosenServiceInfo();
if (service != null) {
Log.d(TAG, "Connecting.");
mConnection.connectToServer(service.getHost(),
service.getPort());
} else {
Log.d(TAG, "No service to connect to!");
}
}
});
mDiscover = (Button) findViewById(R.id.discover_btn);
mDiscover.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mNsdHelper.discoverServices();
}
});
}
public void clickSend(View v) {
EditText messageView = (EditText) this.findViewById(R.id.chatInput);
if (messageView != null) {
String messageString = messageView.getText().toString();
if (!messageString.isEmpty()) {
mConnection.sendMessage(messageString);
}
messageView.setText("");
}
}
public void addChatLine(String line) {
mStatusView.append("\n" + line);
}
#Override
protected void onPause() {
if (mNsdHelper != null) {
mNsdHelper.stopDiscovery();
}
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
if (mNsdHelper != null) {
mNsdHelper.discoverServices();
}
}
#Override
protected void onDestroy() {
mNsdHelper.tearDown();
mConnection.tearDown();
super.onDestroy();
}
}
ChatConnection
public class ChatConnection {
private Handler mUpdateHandler;
private ChatServer mChatServer;
private ChatClient mChatClient;
private static final String TAG = "ChatConnection";
private Socket mSocket;
private int mPort = -1;
public ChatConnection(Handler handler) {
mUpdateHandler = handler;
mChatServer = new ChatServer(handler);
}
public void tearDown() {
mChatServer.tearDown();
mChatClient.tearDown();
}
public void connectToServer(InetAddress address, int port) {
mChatClient = new ChatClient(address, port);
}
public void sendMessage(String msg) {
if (mChatClient != null) {
mChatClient.sendMessage(msg);
}
}
public int getLocalPort() {
return mPort;
}
public void setLocalPort(int port) {
mPort = port;
}
public synchronized void updateMessages(String msg, boolean local) {
Log.e(TAG, "Updating message: " + msg);
if (local) {
msg = "me: " + msg;
} else {
msg = "them: " + msg;
}
Bundle messageBundle = new Bundle();
messageBundle.putString("msg", msg);
Message message = new Message();
message.setData(messageBundle);
mUpdateHandler.sendMessage(message);
}
private synchronized void setSocket(Socket socket) {
Log.d(TAG, "setSocket being called.");
if (socket == null) {
Log.d(TAG, "Setting a null socket.");
}
if (mSocket != null) {
if (mSocket.isConnected()) {
try {
mSocket.close();
} catch (IOException e) {
// TODO(alexlucas): Auto-generated catch block
e.printStackTrace();
}
}
}
mSocket = socket;
}
private Socket getSocket() {
return mSocket;
}
private class ChatServer {
ServerSocket mServerSocket = null;
Thread mThread = null;
public ChatServer(Handler handler) {
mThread = new Thread(new ServerThread());
mThread.start();
}
public void tearDown() {
mThread.interrupt();
try {
mServerSocket.close();
} catch (IOException ioe) {
Log.e(TAG, "Error when closing server socket.");
}
}
class ServerThread implements Runnable {
#Override
public void run() {
try {
// Since discovery will happen via Nsd, we don't need to care which port is
// used. Just grab an available one and advertise it via Nsd.
mServerSocket = new ServerSocket(0);
setLocalPort(mServerSocket.getLocalPort());
while (!Thread.currentThread().isInterrupted()) {
Log.d(TAG, "ServerSocket Created, awaiting connection");
setSocket(mServerSocket.accept());
Log.d(TAG, "Connected.");
if (mChatClient == null) {
int port = mSocket.getPort();
InetAddress address = mSocket.getInetAddress();
connectToServer(address, port);
}
}
} catch (IOException e) {
Log.e(TAG, "Error creating ServerSocket: ", e);
e.printStackTrace();
}
}
}
}
private class ChatClient {
private InetAddress mAddress;
private int PORT;
private final String CLIENT_TAG = "ChatClient";
private Thread mSendThread;
private Thread mRecThread;
public ChatClient(InetAddress address, int port) {
Log.d(CLIENT_TAG, "Creating chatClient");
this.mAddress = address;
this.PORT = port;
mSendThread = new Thread(new SendingThread());
mSendThread.start();
}
class SendingThread implements Runnable {
BlockingQueue<String> mMessageQueue;
private int QUEUE_CAPACITY = 10;
public SendingThread() {
mMessageQueue = new ArrayBlockingQueue<String>(QUEUE_CAPACITY);
}
#Override
public void run() {
try {
if (getSocket() == null) {
setSocket(new Socket(mAddress, PORT));
Log.d(CLIENT_TAG, "Client-side socket initialized.");
} else {
Log.d(CLIENT_TAG, "Socket already initialized. skipping!");
}
mRecThread = new Thread(new ReceivingThread());
mRecThread.start();
} catch (UnknownHostException e) {
Log.d(CLIENT_TAG, "Initializing socket failed, UHE", e);
} catch (IOException e) {
Log.d(CLIENT_TAG, "Initializing socket failed, IOE.", e);
}
while (true) {
try {
String msg = mMessageQueue.take();
sendMessage(msg);
} catch (InterruptedException ie) {
Log.d(CLIENT_TAG, "Message sending loop interrupted, exiting");
}
}
}
}
class ReceivingThread implements Runnable {
#Override
public void run() {
BufferedReader input;
try {
input = new BufferedReader(new InputStreamReader(
mSocket.getInputStream()));
while (!Thread.currentThread().isInterrupted()) {
String messageStr = null;
messageStr = input.readLine();
if (messageStr != null) {
Log.d(CLIENT_TAG, "Read from the stream: " + messageStr);
updateMessages(messageStr, false);
} else {
Log.d(CLIENT_TAG, "The nulls! The nulls!");
break;
}
}
input.close();
} catch (IOException e) {
Log.e(CLIENT_TAG, "Server loop error: ", e);
}
}
}
public void tearDown() {
try {
getSocket().close();
} catch (IOException ioe) {
Log.e(CLIENT_TAG, "Error when closing server socket.");
}
}
public void sendMessage(String msg) {
try {
Socket socket = getSocket();
if (socket == null) {
Log.d(CLIENT_TAG, "Socket is null, wtf?");
} else if (socket.getOutputStream() == null) {
Log.d(CLIENT_TAG, "Socket output stream is null, wtf?");
}
PrintWriter out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(getSocket().getOutputStream())), true);
out.println(msg);
out.flush();
updateMessages(msg, true);
} catch (UnknownHostException e) {
Log.d(CLIENT_TAG, "Unknown Host", e);
} catch (IOException e) {
Log.d(CLIENT_TAG, "I/O Exception", e);
} catch (Exception e) {
Log.d(CLIENT_TAG, "Error3", e);
}
Log.d(CLIENT_TAG, "Client sent message: " + msg);
}
}
}
NSDHelper
public class NSDHelper {
private static final String TAG = NSDHelper.class.getSimpleName();
NsdManager mNsdManager;
public static final String SERVICE_TYPE = "_geoStorm._tcp.";
public String mServiceName = "DROIDDEVICE";
NsdManager.DiscoveryListener mDiscoveryListener;
NsdManager.RegistrationListener mRegistrationListener;
NsdManager.ResolveListener mResolveListener;
NsdServiceInfo mService;
private Context mContext;
public NSDHelper(Context _context) {
mContext = _context;
mNsdManager = (NsdManager) mContext.getSystemService(Context.NSD_SERVICE);
}
public void initNSD() {
initializeResolveListener();
initializeDiscoveryListener();
initializeRegistrationListener();
}
/**
* This method is to register NSD
*
* #param port
*/
public void registerService(int port) {
NsdServiceInfo nsdServiceInfo = new NsdServiceInfo();
nsdServiceInfo.setPort(port);
nsdServiceInfo.setServiceName(mServiceName);
nsdServiceInfo.setServiceType(SERVICE_TYPE);
mNsdManager.registerService(nsdServiceInfo, NsdManager.PROTOCOL_DNS_SD,
mRegistrationListener);
}
public void initializeResolveListener() {
mResolveListener = new NsdManager.ResolveListener() {
#Override
public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
Log.e(TAG, "Resolve failed" + errorCode);
}
#Override
public void onServiceResolved(NsdServiceInfo serviceInfo) {
Log.e(TAG, "Resolve Succeeded. " + serviceInfo);
if (serviceInfo.getServiceName().equals(mServiceName)) {
Log.d(TAG, "Same IP.");
return;
}
mService = serviceInfo;
}
};
}
public void initializeDiscoveryListener() {
mDiscoveryListener = new NsdManager.DiscoveryListener() {
#Override
public void onStartDiscoveryFailed(String serviceType, int errorCode) {
Log.e(TAG, "Discovery failed: Error code:" + errorCode);
mNsdManager.stopServiceDiscovery(this);
}
#Override
public void onStopDiscoveryFailed(String serviceType, int errorCode) {
Log.e(TAG, "Discovery failed: Error code:" + errorCode);
mNsdManager.stopServiceDiscovery(this);
}
#Override
public void onDiscoveryStarted(String serviceType) {
Toast.makeText(mContext, "Discovery Started Successfully ",
Toast.LENGTH_LONG).show();
Log.d(TAG, "Service discovery started");
}
#Override
public void onDiscoveryStopped(String serviceType) {
Log.i(TAG, "Discovery stopped: " + serviceType);
Toast.makeText(mContext, "Discovery stopped", Toast.LENGTH_LONG).show();
}
#Override
public void onServiceFound(NsdServiceInfo serviceInfo) {
Log.d(TAG, "Service discovery success" + serviceInfo);
if (!serviceInfo.getServiceType().equals(SERVICE_TYPE)) {
Toast.makeText(mContext, "Unknown Service Type", Toast.LENGTH_LONG).show();
} else if (serviceInfo.getServiceName().equals(mServiceName)) {
Log.d(TAG, "Same machine: " + mServiceName);
} else if (serviceInfo.getServiceName().contains(mServiceName)) {
mNsdManager.resolveService(serviceInfo, mResolveListener);
}
Log.d(TAG, serviceInfo.getPort() + "");
// Log.d(TAG, new InetSocketAddress(serviceInfo.getHost());)
}
#Override
public void onServiceLost(NsdServiceInfo serviceInfo) {
Log.e(TAG, "service lost" + serviceInfo);
Toast.makeText(mContext, "service Lost" + serviceInfo, Toast.LENGTH_LONG).show();
if (mService == serviceInfo) {
mService = null;
}
}
};
}
public void initializeRegistrationListener() {
mRegistrationListener = new NsdManager.RegistrationListener() {
#Override
public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
}
#Override
public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
}
#Override
public void onServiceRegistered(NsdServiceInfo serviceInfo) {
mServiceName = serviceInfo.getServiceName();
}
#Override
public void onServiceUnregistered(NsdServiceInfo serviceInfo) {
}
};
}
public void discoverServices() {
if (mNsdManager != null)
mNsdManager.discoverServices(
SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
}
public void stopDiscovery() {
mNsdManager.stopServiceDiscovery(mDiscoveryListener);
}
public NsdServiceInfo getChosenServiceInfo() {
return mService;
}
public void tearDown() {
mNsdManager.unregisterService(mRegistrationListener);
mNsdManager.stopServiceDiscovery(mDiscoveryListener);
mNsdManager = null;
mRegistrationListener = null;
}
}
I need help in this that how i can send message using socket , coz i stuck i am not getting any nothing , any help would be appreciated.
I'm having trouble connecting my smartphone to my EV3 over bluetooth using an app.
My situation:
I'm developing an App to send simple Strings to the EV3 which runs with leJOS 0.9.1-aplu11.
My Problem is, I'm not really familiar with Bluetooth, so my app or my receiver-software doesn't work as well.
My goal:
My goal is to create a Listener on the EV3 which is permanant listening for Strings from the app and an App that sends the strings when I press a button.
I hope you can help me.
I'm from germany so don't wonder about my beautifull writing skills!
Here is my Code:
App:
public class MainActivity extends AppCompatActivity {
private final static String TAG = "MainActivity";
private BluetoothAdapter mBluetoothAdapter;
private static BluetoothDevice mDevice;
private Button mSendBN;
private final static String MY_UUID = "00001101-0000-1000-8000-00805f9b34fb";
private static BluetoothSocket mSocket = null;
private static String mMessage = "Stop";
private static PrintStream sender;
private void findBrick() {
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter
.getBondedDevices();
for (BluetoothDevice device : pairedDevices) {
if (device.getName().equals("EV3"))
this.mDevice = device;
}
}
private void initBluetooth() {
Log.d(TAG, "Checking Bluetooth...");
if (mBluetoothAdapter == null) {
Log.d(TAG, "Device does not support Bluetooth");
mSendBN.setClickable(false);
} else {
Log.d(TAG, "Bluetooth supported");
}
if (!mBluetoothAdapter.isEnabled()) {
mSendBN.setClickable(false);
Log.d(TAG, "Bluetooth not enabled");
} else {
Log.d(TAG, "Bluetooth enabled");
}
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Toast.makeText(this, "SpeechRecognizer gestartet", Toast.LENGTH_SHORT).show();
setContentView(R.layout.activity_main);
mSendBN = (Button) findViewById(R.id.button);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
initBluetooth();
findBrick();
if (mDevice == null) {
mSendBN.setClickable(false);
Toast.makeText(this, "No Devices found or BT disabled", Toast.LENGTH_SHORT).show();
Log.d("onC", "Connected to " + mDevice);
}
try {
createSocket();
} catch (IOException e) {
e.printStackTrace();
}
startService();
}
private void startService() {
if (PermissionHandler.checkPermission(this, PermissionHandler.RECORD_AUDIO)) {
Intent i = new Intent(this, BackgroundRecognizerService.class);
startService(i);
}
}
public void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PermissionHandler.RECORD_AUDIO && grantResults.length > 0) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startService();
}
}
}
public static void onSend(View view) throws IOException {
try {
OutputStream os = mSocket.getOutputStream();
sender = new PrintStream(os);
Log.d("onSend", "Message = " + mMessage);
sender.println(mMessage);
sender.flush();
Log.d("onSend", "Message sent");
mSocket.close();
Log.d("onSend", "Socket closed");
} catch (IllegalStateException | NullPointerException e) {
e.printStackTrace();
}
}
public void createSocket() throws IOException {
try {
UUID uuid = UUID.fromString(MY_UUID);
mSocket = mDevice.createRfcommSocketToServiceRecord(uuid);
} catch (IOException e) {
e.printStackTrace();
}
Log.d("createSocket", "Adapter");
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
mSocket.connect();
OutputStream os = mSocket.getOutputStream();
sender = new PrintStream(os);
Log.d("createSocket", "Fertig, " + "Socket: " + mSocket + " Sender: " + sender + " OutputStream: " + os + " mDevice: " + mDevice.getName());
}
protected void onDestroy() {
super.onDestroy();
Log.d("onDestroy", "App beendet");
try {
mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
Log.d("onDestroy", "App vollständig beendet");
}
}
EV3:
public class BTJ {
public static void main(String[] args) {
BTConnector connector = new BTConnector();
System.out.println("0. Auf Signal warten");
NXTConnection conn = connector.waitForConnection(0, NXTConnection.RAW);
InputStream is = conn.openInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String message = "";
while (true){
System.out.println("1. Schleife gestartet");
message = "";
try {
message = br.readLine();
System.out.println("2. Message: " + message);
} catch (IOException e) {
e.printStackTrace(System.out);
}
}
}
}
I have the answer..!
public class BTJ {
public static void main(String[] args) {
BTConnector connector = new BTConnector();
System.out.println("0. Auf Signal warten");
NXTConnection conn = connector.waitForConnection(0, NXTConnection.RAW);
InputStream is = conn.openInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is), 1);
String message = "";
while (true){
System.out.println("1. Schleife gestartet");
message = "";
try {
message = br.readLine();
System.out.println("2. Message: " + message);
} catch (IOException e) {
e.printStackTrace(System.out);
}
}
}
I'm making a OBDII Bluetooth Android app and i'm having some issues sending out commands. I've already made a successfully connection between my mobile device and my OBDII adapter, but when I click on another activity, the Bluetooth connection seems to quit?
When you open up the app you'll see a button that says "Connect Device". When you press that, a ListAdapter will show up with paired Bluetooth devices. Then when you have succesfully connected to the device (OBDII Adapter) it will take you to another layout where there is 3 activities that are 3 different powerplatforms for cars. This is where the problem occurs. For now, I just want to be able to read the voltage from the OBDII. But when I click my button getValue inside one of the 3 activities. I get an logcat error. And I think it's because I haven't initiated my BluetoothHandler properly. I have no idea how to do this.
MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button b1;
BluetoothAdapter mAdapter;
FragmentHostCallback mHost;
BTHandler btHandler;
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case BTHandler.STATE_CONNECTED:
//setContentView(R.layout.activity_connected);
Intent intent = new Intent(MainActivity.this, Connected.class);
startActivity(intent);
Toast.makeText(getApplicationContext(), R.string.title_connected_to, Toast.LENGTH_SHORT).show();
Log.v("Log", "Connected");
break;
case BTHandler.STATE_NONE:
Toast.makeText(getApplicationContext(), R.string.title_not_connected, Toast.LENGTH_SHORT).show();
break;
}
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btHandler = new BTHandler(MainActivity.this, mHandler);
b1 = (Button) findViewById(R.id.connect);
b1.setOnClickListener(this);
mAdapter = BluetoothAdapter.getDefaultAdapter();
//init();
if (mAdapter == null) {
Toast.makeText(getApplicationContext(), R.string.device_not_supported, Toast.LENGTH_LONG).show();
finish();
} else {
if (!mAdapter.isEnabled()) {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
}
//BTHandler btHandler = new BTHandler(MainActivity.this, mHandler);
//btHandler.connect("");
}
public void onClick(View v) {
int id = v.getId();
//String voltage = ("ATRV");
switch (id) {
case R.id.connect:
onConnect(); //Operation
Log.v("Log", "Pressed onClick");
break;
/*case R.id.getValue:
btHandler.write(voltage);
Log.v("Log", "getValue" + voltage);
break;*/
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_CANCELED) {
Toast.makeText(getApplicationContext(), R.string.enable_bluetooth, Toast.LENGTH_SHORT).show();
finish();
}
}
private void onConnect() {
ArrayList deviceStrs = new ArrayList();
final ArrayList<String> devices = new ArrayList();
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
Set pairedDevices = mAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (Object device : pairedDevices) {
BluetoothDevice bdevice = (BluetoothDevice) device;
deviceStrs.add(bdevice.getName() + "\n" + bdevice.getAddress());
devices.add(bdevice.getAddress());
}
}
// show list
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.select_dialog_singlechoice,
deviceStrs.toArray(new String[deviceStrs.size()]));
alertDialog.setSingleChoiceItems(adapter, -1, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
int position = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
String deviceAddress = devices.get(position);
btHandler.connect(deviceAddress);
//btHandler.write();
}
});
alertDialog.setTitle("Paired devices");
alertDialog.show();
}
BTHandler:
public class BTHandler {
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3; // now connected to a remote device
final ArrayList<String> devices = new ArrayList();
private final Handler mHandler;
private BluetoothAdapter mAdapter;
private BluetoothDevice device;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private BluetoothSocket socket;
private String status;
private int mState;
private boolean connectionStatus = false;
public BTHandler(Context context, Handler handler) { // Konstruktor
mAdapter = BluetoothAdapter.getDefaultAdapter();
mHandler = handler;
}
public void write(String s) {
mConnectedThread.sendRawCommand(s);
Log.v("write", "write");
}
/*
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
}
}
*/
public void connect(String deviceAddress) {
mConnectThread = new ConnectThread(deviceAddress);
mConnectThread.start();
}
private void guiHandler(int what, int arg1, String obj) {
Message msg = mHandler.obtainMessage();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.sendToTarget();
}
private class ConnectThread extends Thread {
BluetoothSocket tmp = null;
private BluetoothSocket mmSocket;
public ConnectThread(String deviceAddress) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
device = mAdapter.getRemoteDevice(deviceAddress);
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = mAdapter.getRemoteDevice(deviceAddress);
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
try {
tmp = device.createRfcommSocketToServiceRecord(uuid);
//socket.connect();
//Log.v("connect", "connect");
} catch (IOException e) {
//e.printStackTrace();
//Log.v("exception", "e");
}
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
mAdapter.cancelDiscovery();
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes;
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
Log.v("connect", "connect");
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
Log.v("close", "close");
} catch (IOException closeException) {
}
guiHandler(Constants.TOAST, Constants.SHORT, "Connection Failed");
return;
}
guiHandler(Constants.CONNECTION_STATUS, Constants.STATE_CONNECTED, "");
mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private ObdMultiCommand multiCommand;
public ConnectedThread(BluetoothSocket socket) {
connectionStatus = true;
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
try {
//RPMCommand engineRpmCommand = new RPMCommand();
//SpeedCommand speedCommand = new SpeedCommand();
ModuleVoltageCommand voltageCommand = new ModuleVoltageCommand();
while (!Thread.currentThread().isInterrupted()) {
//engineRpmCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
//speedCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
voltageCommand.run(socket.getInputStream(), socket.getOutputStream());
// TODO handle commands result
//Log.d("Log", "RPM: " + engineRpmCommand.getFormattedResult());
//Log.d("Log", "Speed: " + speedCommand.getFormattedResult());
Log.v("Log", "Voltage: " + voltageCommand.getFormattedResult());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
OBDcmds();
// Keep listening to the InputStream until an exception occurs
while (connectionStatus) {
sendMultiCommand();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// CALL this to MainActivity
public void sendRawCommand(String command) {
try {
new OdbRawCommand(command);
} catch (Exception e) {
Log.v("sendRawCommand", "e");
}
}
private void OBDcmds() { // execute commands
try {
new EchoOffCommand().run(socket.getInputStream(), socket.getOutputStream());
new LineFeedOffCommand().run(socket.getInputStream(), socket.getOutputStream());
new TimeoutCommand(100).run(socket.getInputStream(), socket.getOutputStream());
new SelectProtocolCommand(ObdProtocols.AUTO).run(socket.getInputStream(), socket.getOutputStream()); //ISO_15765_4_CAN
} catch (Exception e) {
Log.v("OBDcmds", "e");
// handle errors
}
}
/*
// Call this from the main activity to send data to the remote device
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
}
}
*/
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
public void sendMultiCommand() {
try {
// RUN some code here
} catch (Exception e) {
}
}
}
}
SPA: One of the power platforms mentioned before.
public class SPA extends AppCompatActivity implements View.OnClickListener {
Button b2;
BTHandler btHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sp);
b2 = (Button) findViewById(R.id.getValue);
b2.setOnClickListener(this);
}
public void onClick(View v) {
int id = v.getId();
String voltage = ("AT RV");
switch (id) {
case R.id.getValue:
btHandler.write(voltage);
Log.v("Log", "getValue" + voltage);
break;
}
}
}
Logcat:
The reason of the error is here:
BTHandler btHandler;
and you are doing this:
btHandler.write(voltage);
but the object is null referenced....
you need to initialize the BTHandler in the oncreate...
or maybe better:
use a service so you can Bind all the activities to that...
PS:
Note that the BTHandler of the MainActivity is not the same as the one declared in the SPA Class... so although that btHandler is constructed and works in MainActivity doesnt mean it will work in other activities/classes
So i have a registration Android app that in main activity creates a socket connection on create opensocket(). Everything runs perfectly on the first submit, the debugger out put looks great and it sends/recieves data back from my WPF app. Now It goes to a thanks activity which onclick leads back to my mainactivity. Now when i hit submit, it works fine, but is showing its hitting my socket methods twice (only inserts the records once on my WPF app) , and so on as many times i submit. I realize i'm not closing or reusing my socket connection correctly?! I've tried several things, but can't seem to get this to either reuse the same opensocket instance or can't just close and reopen on reload. I'm quite new to android and sockets all together, any help is greatly appreciated!
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
settingsCheck();
openSocket();
sett.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
launchSettings();
}
});
mainLogo.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
RefreshMain();
}
});
btn_register.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
tv_errors.setText("");
errorMsg = "";
nameCheck(et_lName.getText().toString(),et_fName.getText().toString());
emailCheck(et_email.getText().toString());
partnerCheck();
mobileCheck(et_mobile.getText().toString());
if (SocketHandler.SocketConnected){
if(errorMsg == ""){
//tv_errors.setText("");
if(checkForSD() == true){
sendRegistrantInfo(et_fName.getText() + "," + et_lName.getText() + "," + et_email.getText() + "," + et_mobile.getText() + "," + et_partEmail.getText() + "," + cb_terms1.isChecked() + "," + cb_terms2.isChecked() );
}
else{
tv_errors.setText("**Please insert an SD Card.");
}
}
else{
//tv_errors.setText(errorMsg);
}
}
else
{
connectionStatus.setText("Connection Error.");
tv_errors.setText("**Connection lost, please try again.");
//openSocket();
}
}
});
}
public void RefreshMain()
{
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
}
public void launchLogin()
{
Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
}//end launchLogin
public void launchSettings()
{
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
}//end launchSettings
public void settingsCheck()
{
SharedPreferences settings = getSharedPreferences("prefs",MODE_PRIVATE);
String currentIP = settings.getString("IPSetting", "");
String currentPort = settings.getString("PORTSetting", "");
currentMem = settings.getString("SDSize", "");
if (currentIP == "" || currentPort == ""){
Intent myIntent = new Intent(this,SettingsActivity.class);
startActivity(myIntent);
}
}//end settingsCheck()
public void launchRingDialog(String id) {
final String idYo = id;
final ProgressDialog ringProgressDialog = ProgressDialog.show(MainActivity.this, "Formatting SD Card","Formatting SD Card, please wait this could take several minutes...", true);
new Thread(new Runnable() {
#Override
public void run() {
try {
fileToSD(idYo);
Thread.sleep(10000);
} catch (Exception e) {
}
ringProgressDialog.dismiss();
}
}).start();
}
public boolean checkForSD()
{
String root = "/storage/removable/sdcard1/";
double memInGigs = round(sizeMatters(root),2);
if(memInGigs >0){
return true;
}
else
{
return false;
}
}
private double sizeMatters(String path)
{
StatFs stat = new StatFs(path);
double availSize = (double)stat.getAvailableBlocks() * (double)stat.getBlockSize();
double ingigs = availSize/ 1073741824;
return ingigs;
}//end sizeMatters()
private void sendRegistrantInfo(String reg){
_sh.sendMessage(reg);
}
private void openSocket(){
_sh = new SocketHandler();
_sh.setSocketHandlerListener(this);
SharedPreferences settings = getSharedPreferences("prefs",MODE_PRIVATE);
String currentIP = settings.getString("IPSetting", "");
String currentPort = settings.getString("PORTSetting", "");
_sh.open(currentIP, currentPort);
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
}
#Override
public void onSocketConnected() {
Log.v(TAG, "onSocketConnected");
connectionStatus.setText("CONNECTED");
}
#Override
public void onSocketData(String msg) {
Log.v(TAG, "onSocketData - " + msg );
int usrID = Integer.parseInt(msg.trim());
if (msg != null & usrID > 0){
launchRingDialog(msg);
Intent intent = new Intent(this, ThanksActivity.class);
startActivity(intent);
}
else if(msg.trim().equals("-2") == true)
{
tv_errors.setText("**This email has already been registered for this event, please click Already Registered button to sign in.");
}
else{
tv_errors.setText("**Error, Please try submitting again.");
errorMsg = "-1";
}
}
#Override
public void onSocketDisconnected() {
Log.v(TAG, "onSocketDisconnected");
connectionStatus.setText("DISCONNECTED");
}
public class SocketHandler {
Socket sc;
public static boolean SocketConnected = false;
private static ClientThread cThread;
public String prefsFile = "prefs";
public String port = "8888";
public String ip = "192.168.1.4";
private String TAG = "SocketHandler";
protected SocketHandlerListener socketHandlerListener;
public interface SocketHandlerListener{
public void onSocketConnected();
public void onSocketData(String msg);
public void onSocketDisconnected();
}
public SocketHandler(){
}
public void setSocketHandlerListener(SocketHandlerListener shl){
socketHandlerListener = shl;
}
public void open(String ip, String port){
this.ip = ip;
this.port = port;
cThread = new ClientThread();
try{
cThread.start();
}catch (Exception ex){
Log.v(TAG, "Error connecting to socket");
}
}
public void close(){
if (cThread != null){
if (cThread.socket != null){
try {
cThread.socket.close();
} catch (Exception e) {
Log.v(TAG, "Error closing socket");
}
cThread.socket = null;
}
}
}
public void sendMessage(String msg){
cThread.sendMessage(msg);
}
public void messageRecieved(String msg){
dispatchSocketData(msg);
}
private void dispatchSocketConnected(){
if (socketHandlerListener != null){
socketHandlerListener.onSocketConnected();
}
}
private void dispatchSocketDisconnected(){
if (socketHandlerListener != null){
socketHandlerListener.onSocketDisconnected();
}
}
private void dispatchSocketData(String msg){
if (socketHandlerListener != null){
socketHandlerListener.onSocketData(msg);
}
}
public class ClientThread extends Thread {
public Socket socket;
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(ip);
Log.v(TAG, "C: Connecting..." + ip + ":" + port);
socket = new Socket(serverAddr, Integer.parseInt(port));
socket.setSoTimeout(0);
socket.setKeepAlive(true);
SocketConnected = true;
handler.post(new Runnable() {
#Override
public void run() {
dispatchSocketConnected();
}
});
// BLOCKING THE THREAD
while (SocketConnected) {
InputStream in = socket.getInputStream();
byte[] buffer = new byte[4096];
int line = in.read(buffer, 0, 4096);
while (line != -1) {
byte[] tempdata = new byte[line];
System.arraycopy(buffer, 0, tempdata, 0, line);
final String data = new String(tempdata);
handler.post(new Runnable() {
#Override
public void run() {
messageRecieved(data);
SocketConnected = false;
}
});
line = in.read(buffer, 0, 4096);
}
// break;
}
socket.close();
Log.v("Socket", "C: Closed.");
handler.post(new Runnable() {
#Override
public void run() {
dispatchSocketDisconnected();
}
});
SocketConnected = false;
} catch (Exception e) {
Log.v("Socket", "C: Error", e);
handler.post(new Runnable() {
#Override
public void run() {
dispatchSocketDisconnected();
}
});
SocketConnected = false;
}
}
Handler handler = new Handler();
public void sendMessage(String msg){
if (socket != null){
if (socket.isConnected()){
PrintWriter out;
try {
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), false);
out.print(msg);
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}