I am creating my socket program on my main activity on Android Studio. Now I want to separate the socket portion by creating another class that will be called by my main activity. Need help. This is some part of my codes:
public class MainActivity extends Activity {
private Socket client;
private Button Connect,Disconnect;
EditText editTextAddress;
private TextView textResponse;
private BufferedReader BufferIn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Connect = (Button) findViewById(R.id.connect);
Disconnect = (Button) findViewById(R.id.disconnect);
editTextAddress = (EditText) findViewById(R.id.address);
textResponse = (TextView) findViewById(R.id.response);
Disconnect.setOnClickListener(DisconnectOnClickListener);
Connect.setOnClickListener(ConnectOnClickListener);
}
//Button Disconnect
OnClickListener DisconnectOnClickListener = new OnClickListener() {
public void onClick(View v) {
if(client !=null) {
Toast.makeText(getApplicationContext(), "disconnected", Toast.LENGTH_LONG).show();
try {
client.close();
} catch (IOException e) { /* failed */ }
}else{
Toast.makeText(getApplicationContext(), "socket not found", Toast.LENGTH_LONG).show();
}
}
};
//Button Connect
OnClickListener ConnectOnClickListener = new OnClickListener() {
public void onClick(View v) {
Toast.makeText(getApplicationContext(),"connected", Toast.LENGTH_LONG).show();
mConnectAndPoll.start();
}
};
private final Thread mConnectAndPoll = new Thread(new Runnable() {
String serverm = null;
#Override
public void run() {
try {
final String address = editTextAddress.getText().toString();
client = new Socket(address, 8080);
mBufferIn = new BufferedReader(
new InputStreamReader(client.getInputStream()));
while (mRun) {
serverm = mBufferIn.readLine();
if (serverm != null) {
System.out.println(serverm);
}
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
EDIT:
Write Thread code in separate class like:
MyThread
public class MyThread extends Thread{
String serverm = null;
String address;
Socket client;
Context context;
public MyThread (String address, Context context )
{
this.address = address;
this.context = context;
}
public void stopSocket()
{
if(client !=null)
{
Toast.makeText(context, "disconnected", Toast.LENGTH_LONG).show();
try {
client.close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else{
Toast.makeText(context, "socket not found", Toast.LENGTH_LONG).show();
}
}
#Override
public void run() {
try {
client = new Socket(address, 8080);
BufferedReader mBufferIn = new BufferedReader(
new InputStreamReader(client.getInputStream()));
while (mRun) {
serverm = mBufferIn.readLine();
if (serverm != null) {
System.out.println(serverm);
}
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
MainActivity
public class MainActivity extends Activity {
private Button Connect,Disconnect;
EditText editTextAddress;
private TextView textResponse;
private BufferedReader BufferIn;
MyThread thread;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Connect = (Button) findViewById(R.id.connect);
Disconnect = (Button) findViewById(R.id.disconnect);
editTextAddress = (EditText) findViewById(R.id.address);
textResponse = (TextView) findViewById(R.id.response);
Disconnect.setOnClickListener(DisconnectOnClickListener);
Connect.setOnClickListener(ConnectOnClickListener);
}
//Button Disconnect
OnClickListener DisconnectOnClickListener = new OnClickListener() {
public void onClick(View v) {
thread.stopSocket();
}
};
//Button Connect
OnClickListener ConnectOnClickListener = new OnClickListener() {
public void onClick(View v) {
Toast.makeText(getApplicationContext(),"connected", Toast.LENGTH_LONG).show();
thread = new MyThread(editTextAddress.getText().toString(), getApplicationContext());
thread.start();
}
};
}
Related
I am beginner and making my first project on android studio. I want to exchange a unique string between devices over Bluetooth without pairing whenever devices are near. Following is the code I tried but did not work. The code I mention is of scanning part only when click on scan it search for the device and exchange the keys but it is not working.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ON = (Button) findViewById(R.id.button3);
OFF = (Button) findViewById(R.id.button5);
Scan = (Button) findViewById(R.id.search);
myBT = BluetoothAdapter.getDefaultAdapter();
Interaction = (Button) findViewById(R.id.intr);
intentON = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
other = (TextView)findViewById(R.id.textView4);
bluelist = (ListView) findViewById(R.id.btList);
//IntView = (ListView) findViewById(R.id.InList);
arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
pAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
bluelist.setAdapter(arrayAdapter);
random = UUID.randomUUID();
getUUID = random.toString();
code = (TextView) findViewById(R.id.textView6);
data = getIntent().getExtras().getString("SomeNumbers");
code.setText(data);
send = (String) code.getText();
checkPermission();
ON.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(myBT.isEnabled())
Toast.makeText(getApplicationContext(), "Bluetooth already Enabled", Toast.LENGTH_SHORT).show();
else
bluetoothOn();
}
});
OFF.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
bluetoothOff();
}
});
Scan.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
discover();
}
});
bluelist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//pairDevice(device);
}
});
Interaction.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent getInteractions = new Intent(MainActivity.this, Interactions.class);
//Bundle args = new Bundle();
//args.putSerializable("Exposure", (Serializable)arrayList);
getInteractions.putStringArrayListExtra("Exposure", arrayList);
startActivity(getInteractions);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == BLUETOOTH_REQ_CODE) {
if (resultCode == RESULT_OK) {
Toast.makeText(getApplicationContext(), "Bluetooth is Enabled", Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(getApplicationContext(), "Bluetooth Disabled", Toast.LENGTH_LONG).show();
}
}
}
private void discover(){
if(myBT.isDiscovering()){
myBT.cancelDiscovery();
Toast.makeText(getApplicationContext(),"Discovery stopped",Toast.LENGTH_SHORT).show();
}
else{
if(myBT.isEnabled()) {
arrayAdapter.clear(); // clear items
myBT.startDiscovery();
Toast.makeText(getApplicationContext(), "Discovery started", Toast.LENGTH_SHORT).show();
registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
}
else{
bluetoothOn();
}
}
}
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action)){
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// add the name to the list
arrayAdapter.add(device.getName() + "\n" + device.getAddress());
arrayAdapter.notifyDataSetChanged();
ServerClass serverClass = new ServerClass();
serverClass.start();
ClientClass clientClass = new ClientClass(pairing);
clientClass.start();
sendReceive.write(send.getBytes());
}
}
};
Handler handler = new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(#NonNull Message msg) {
switch(msg.what)
{
case STATE_LISTENING:
Toast.makeText(getApplicationContext(), "Listening", Toast.LENGTH_SHORT).show();
break;
case STATE_CONNECTING:
Toast.makeText(getApplicationContext(), "Connecting", Toast.LENGTH_SHORT).show();
break;
case STATE_CONNECTED:
Toast.makeText(getApplicationContext(), "Connected", Toast.LENGTH_SHORT).show();
break;
case STATE_CONNECTION_FAILED:
Toast.makeText(getApplicationContext(), "Connection Failed", Toast.LENGTH_SHORT).show();
break;
case STATE_MESSAGE_RECEIVED:
byte[] readBuff = (byte[]) msg.obj ;
String tempMsg = new String(readBuff,0,msg.arg1);
other.setText(tempMsg);
break;
}
return false;
}
});
private class ServerClass extends Thread
{
private BluetoothServerSocket serverSocket;
public ServerClass()
{
try {
serverSocket = myBT.listenUsingInsecureRfcommWithServiceRecord(App_Name,random);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run()
{
BluetoothSocket socket=null;
while(socket == null)
{
try {
//Message msg = Message.obtain();
//msg.what=
//handler.sendMessage(msg);
socket=serverSocket.accept();
} catch (IOException e) {
e.printStackTrace();
//Message msg = Message.obtain();
//msg.what=
//handler.sendMessage(msg);
}
if(socket != null)
{
//Message msg = Message.obtain();
//msg.what=
//handler.sendMessage(msg);
sendReceive = new SendReceive(socket);
sendReceive.start();
break;
}
}
}
}
private class ClientClass extends Thread
{
private BluetoothDevice device;
private BluetoothSocket socket;
public ClientClass(BluetoothDevice device1)
{
device=device1;
try {
socket = device.createRfcommSocketToServiceRecord(random);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run()
{
try {
socket.connect();
sendReceive = new SendReceive(socket);
sendReceive.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private class SendReceive extends Thread
{
private final BluetoothSocket bluetoothSocket;
private final InputStream inputStream;
private final OutputStream outputStream;
public SendReceive(BluetoothSocket socket)
{
bluetoothSocket=socket;
InputStream tempIn = null;
OutputStream tempOut = null;
try {
tempIn = bluetoothSocket.getInputStream();
tempOut = bluetoothSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
inputStream = tempIn;
outputStream = tempOut;
}
public void run()
{
byte[] buffer = new byte[1024];
int bytes;
while(true)
{
try {
bytes = inputStream.read(buffer);
handler.obtainMessage(STATE_MESSAGE_RECEIVED,bytes,-1,buffer).sendToTarget();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void write(byte[] bytes)
{
try {
outputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
I'm trying to make an app reading a string coming from a socket connection, but after a few hours the app stops talking (without exceptions). I'm sure the app is still running because the server sending the string continues to detect the response echo after sending it.
public class MainActivity extends AppCompatActivity {
TextToSpeech textToSpeech;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textToSpeech = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if(status != TextToSpeech.ERROR) {
textToSpeech.setLanguage(Locale.ITALY);
}
}
});
Thread socketT = new Thread(new SocketThread());
socketT.start();
}
#Override
public void onDestroy() {
if (textToSpeech != null) {
textToSpeech.stop();
textToSpeech.shutdown();
}
super.onDestroy();
}
private class SocketThread extends Thread {
static final int socketPort = 3333;
#Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(socketPort);
try {
while(true) {
Socket clientSocket = serverSocket.accept();
try {
new ServerThread(clientSocket);
} catch(IOException e) {
clientSocket.close();
} }
}
catch (IOException e) {
}
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
class ServerThread extends Thread {
private int counter = 0;
private int id = ++counter;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public ServerThread(Socket s) throws IOException {
socket = s;
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream());
out = new PrintWriter(new BufferedWriter(osw), true);
start();
}
public void run() {
try {
while (true) {
String str = in.readLine();
textToSpeech.speak(str, TextToSpeech.QUEUE_FLUSH, null);
}
} catch (IOException e) {}
try {
socket.close();
} catch(IOException e) {}
}
}
}
}
TextToSpeech instance will be available after connect to system service, not after invoke constructor.
So, your plan need to edit like this:
Call TextToSpeech constructor.
Check your TextToSpeech instance is finish to connect to system service through TextToSpeech.OnInitListener.onInit().
Then, connect to your custom service.
Try this as below:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textToSpeech = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if(status != TextToSpeech.ERROR) {
int res = textToSpeech.setLanguage(Locale.ITALY);
if (res >= TextToSpeech.LANG_AVAILABLE) {
// TextToSpeech instance is available after connect to system service!
Thread socketT = new Thread(new SocketThread());
socketT.start();
}
}
}
});
// At this time, your TextToSpeech instance may be not available yet.
//Thread socketT = new Thread(new SocketThread());
//socketT.start();
}
I'm trying to keep a socket open during lifecycle changes in a headless fragment with setRetainInstance(true); in onCreate. However, when my app comes back the following exception occurs.
E/Client: Receiving thread loop error
java.net.SocketException: Socket closed
at libcore.io.Posix.recvfromBytes(Native Method)
at libcore.io.Posix.recvfrom(Posix.java:189)
at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:250)
at libcore.io.IoBridge.recvfrom(IoBridge.java:549)
at java.net.PlainSocketImpl.read(PlainSocketImpl.java:481)
at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:37)
at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
at java.io.InputStreamReader.read(InputStreamReader.java:233)
at java.io.BufferedReader.fillBuf(BufferedReader.java:145)
at java.io.BufferedReader.readLine(BufferedReader.java:397)
at com.gm.popper_6.ConnectionFragment$Client$ReceivingThread.run(ConnectionFragment.java:183)
at java.lang.Thread.run(Thread.java:818)
Here's the code for the fragment
public class ConnectionFragment extends Fragment {
private InetAddress mGoAddress;
private int mGoPort;
private Client mClient;
private static final String TAG = "Connection";
private Server mServer;
private Socket mSocket;
private ConnectionFragmentListener listener;
private String mMessage;
public static ConnectionFragment newInstance(InetAddress address, int port){
Bundle bundle = new Bundle();
bundle.putSerializable("GoAddress", address);
bundle.putInt("GoPort", port);
ConnectionFragment fragment = new ConnectionFragment();
fragment.setArguments(bundle);
return fragment;
}
public interface ConnectionFragmentListener{
void onMessageRcvd(String message);
}
public void setConnectionFragmentListener(ConnectionFragmentListener listener){
this.listener = listener;
}
private void readBundle(Bundle bundle){
if (bundle != null){
mGoAddress = (InetAddress)bundle.getSerializable("GoAddress");
mGoPort = bundle.getInt("GoPort");
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
readBundle(getArguments());
mGoAddress = (InetAddress) getArguments().getSerializable("GoAddress");
mGoPort = getArguments().getInt("GoPort");
mServer = new Server();
}
#Override
public void onStart() {
super.onStart();
}
// THE SERVER CLASS
private class Server{ //DECLARATION
ServerSocket mServerSocket = null;
Thread mThread = null;
public Server(){ //CONSTRUCTOR
mThread = new Thread(new ServerThread());
mThread.start();
}
public void tearDown(){
mThread.interrupt();
try {
mServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "Error closing server socket");
}
}
class ServerThread implements Runnable{
#Override
public void run() {
//REMOVE OR COMMENT OUT FOR FINAL
//android.os.Debug.waitForDebugger();
try {
mServerSocket = new ServerSocket(mGoPort, 50, mGoAddress);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()){
try {
mSocket = mServerSocket.accept();
Log.d(TAG, "Connected");
if (mClient == null){
mClient = new Client();
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
}
}
//THE CLIENT CLASS
private class Client { //DECLARATION
private final String CLIENT_TAG = "Client";
private Thread mSendThread;
private Thread mRecThread;
public Client() { //CONSTRUCTOR
Log.d(CLIENT_TAG, "Creating Client");
mSendThread = new Thread(new SendingThread());
mSendThread.start();
}
class SendingThread implements Runnable { //an inner class of Client
BlockingQueue<String> mMessageQueue;
private int QUEUE_CAPACITY = 10;
public SendingThread() {
mMessageQueue = new ArrayBlockingQueue<String>(QUEUE_CAPACITY);
}
#Override
public void run() {
mRecThread = new Thread(new ReceivingThread());
mRecThread.start();
while (true){
try {
String msg = mMessageQueue.take();
sendMessage(msg);
} catch (InterruptedException e) {
Log.d(CLIENT_TAG, "Sending loop interrupted, exiting");
}
}
}
} //closes SendingThread, an inner class of Client
class ReceivingThread implements Runnable{ //an inner class of Client
#Override
public void run() {
BufferedReader input;
try {
//android.os.Debug.waitForDebugger();
input = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
while (!Thread.currentThread().isInterrupted()){
String messageStr = null;
messageStr = input.readLine(); //Line 183
if (messageStr!= null){
Log.d(CLIENT_TAG, "Read from the stream: " + messageStr);
mMessage = messageStr;
updateMessages(false);
}
else{
Log.d(CLIENT_TAG, "The null!!!");
}
}
input.close();
} catch (IOException e) {
Log.e(CLIENT_TAG, "Receiving thread loop error", e);
e.printStackTrace();
}
} //closes run method
} //closes ReceivingThread, an inner class of Client
public void tearDown(){ //a method of Client
try {
getSocket().close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendMessage(String msg){ //a method of Client
try {
Socket socket = getSocket(); //should return mSocket
if (socket == null) {
Log.d(CLIENT_TAG, "Socket is null");
} else if (socket.getOutputStream() == null) {
Log.d(CLIENT_TAG, "Socket output stream in null");
}
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(getSocket().getOutputStream())), true);
out.println(msg);
out.flush();
mMessage = msg;
updateMessages(true);
} catch (UnknownHostException e){
Log.d(CLIENT_TAG, "Unkown host", e);
} catch (IOException e) {
Log.d(CLIENT_TAG, "I/O exception", e);
} catch (Exception e){
Log.d(CLIENT_TAG, "Error 3", e);
}
Log.d(CLIENT_TAG, "Message sent: " + msg);
} //closes sendMessage, a method of the inner Client class
} //closes Client class, an inner class of Connection
private Socket getSocket() {
return mSocket;
}
public synchronized void updateMessages(boolean local){
Log.i(TAG, "Updating message: " + mMessage);
if (local){
mMessage = "me: " + mMessage;
}
else{
mMessage = "them: " + mMessage;
}
if (listener!= null){
listener.onMessageRcvd(mMessage);
}
} //closes updateMessages
public void sendMessage(String msg){ //CALL FROM MAIN ACTIVITY
if(mClient != null){ //TO SEND A STRING MESSAGE
mClient.sendMessage(msg);
}
}
public void tearDown(){
mServer.tearDown();
mClient.tearDown();
}
#Override
public void onDestroy() {
tearDown();
super.onDestroy();
}
} //closes class declaration
And here's the main activity
public class MainActivity extends Activity implements ChannelListener, DeviceActionListener,
ConnectionInfoListener, ConnectionFragment.ConnectionFragmentListener{
//CLASS DECLARATIONS
public static final String TAG = "Popper";
private WifiP2pManager manager;
private Boolean isWifiP2pEnabled = false;
ArrayList<Target> mTargets = new ArrayList<Target>(0);
Target mTarget;
TextView rcvd;
TextView ip;
EditText mssg;
String goAddress = "";
InetAddress goInetAddress;
int prefixedPort;
//declare and initialize an intent filter
private final IntentFilter intentFilter = new IntentFilter();
//private final IntentFilter serverFilter = new IntentFilter();
private Channel channel;
private BroadcastReceiver receiver = null;
private ConnectionInfoListener infoListener;
private Intent serverServiceIntent;
ConnectionFragment mConnection;
//????
public void setIsWifiP2pEnabled(boolean isWifiP2pEnabled) {
this.isWifiP2pEnabled = isWifiP2pEnabled;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//register app w/p2p framework with call to initialize
//channel is my apps connection to the p2p framework
manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
channel = manager.initialize(this, getMainLooper(), null);
receiver = new P2pReceiver(manager, channel, this);
rcvd = (TextView)findViewById(R.id.rcvd);
rcvd.setMovementMethod(new ScrollingMovementMethod());
//initialize filter and setup to listen for the following broadcast intents
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
Resources res = getResources();
prefixedPort = res.getInteger(R.integer.GOport);
}
#Override
public void onMessageRcvd(String message) {
addLine(message);
}
#Override
protected void onResume() {
super.onResume();
receiver = new P2pReceiver(manager, channel, this);
registerReceiver(receiver, intentFilter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.action_items, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.atn_direct_discover:
if (!isWifiP2pEnabled) {
NotificationToast.showToast(MainActivity.this, "Enable P2P!!!");
return true;
}
final TargetListFragment fragment = (TargetListFragment) getFragmentManager()
.findFragmentById(R.id.frag_list);
fragment.onInitiateDiscovery();
manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
NotificationToast.showToast(MainActivity.this, "Discovery initiated");
}
#Override
public void onFailure(int reason) {
NotificationToast.showToast(MainActivity.this, "Discovery failed");
}
});
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override //this is associated with ChannelListener
public void onChannelDisconnected() { //removal causes error.
}
#Override
public void onConnectionInfoAvailable(WifiP2pInfo info) {
goAddress = info.groupOwnerAddress.getHostAddress(); //this returns a string rep of add.
goInetAddress = info.groupOwnerAddress; //this returns actual inet add.
ip = (TextView) findViewById(R.id.ip);
mssg = (EditText) findViewById(R.id.mssg);
ip.setText(goAddress + ":" + "8080"); //display GO address and IP
startConnectionFragment();
}
//this override method is triggered by TargetListFragment's DeviceActionListener
#Override
public void connect(WifiP2pConfig config) {
manager.connect(channel, config, new ActionListener() {
#Override
public void onSuccess() {
//maybe use this to gray out and disable the listview object that connected
}
#Override
public void onFailure(int reason) {
}
});}
public void startConnectionFragment(){
mConnection = ConnectionFragment.newInstance(goInetAddress, prefixedPort);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(mConnection, "TAG_1");
ft.commit();
mConnection.setConnectionFragmentListener(this);
}
public void addLine(String line){
final String msg = line;
runOnUiThread(new Runnable(){
#Override
public void run() {
rcvd.append("\n" + msg);
}
});
}
#Override
public void onTargetListClick(Target target) {
mTarget = target;
}
public void stopServer() {
if(serverServiceIntent != null)
{
stopService(serverServiceIntent);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mConnection != null){
//mConnection.tearDown();
}
stopServer();
}
public void SendMessage(View v){
EditText txt = (EditText) this.findViewById(R.id.mssg);
String str = txt.getText().toString();
mConnection.sendMessage(str);
txt.getText().clear();
}
}
Could this have something to do with detaching when the app goes on pause or stop and not re-attaching when it comes back to life? Are there other things I should be considering?
Ultimately the app needs to keep communication open to about 5 or 6 devices over p2p. if there is a better strategy I'm open to suggestions. Thanks.
Update - So I've confirmed that both the onDestroy and onDetach methods of the fragment are firing when the main activity goes onStop. Since I have a method to close the sockets on death of the fragment they are getting closed. The big question now is how to keep the fragment alive?
You should maybe create a helper class that will open/close sockets on behalf of other classes, such as that fragment, that helper class won't be subjected to any life cycle events, and can be kept running as long as the Application process is alive
I wanted to start with the basics of bluetooth connection and make a simple app capable of scanning, pairing and connecting.
I'm struggling with the last concept, i followed a lot of tutorials but I couldn't make it. I don't know if you can help me but here is my code.
ublic class MainActivity extends Activity {
private final String TAG = "Debugging";
private final static int REQUEST_CODE_ENABLE_BLUETOOTH = 0;
protected static final int SUCCESS_CONNECT = 0;
protected static final int MESSAGE_READ = 1;
public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
BluetoothAdapter btAdapter;
ArrayList<String> arrayListpaired;
ArrayAdapter<String> listAdapter,adapter;
ListView listView,listViewPaired;
Set<BluetoothDevice> deviceArray;
ArrayList<String> pairedDevices;
IntentFilter filter;
BroadcastReceiver receiver;
BluetoothDevice bdDevice;
ArrayList<BluetoothDevice> arrayListBluetoothDevices = null;
ArrayList<BluetoothDevice> arrayListPairedBluetoothDevices;
ListItemClicked listItemClicked;
ListItemClickedonPaired listItemClickedonPaired;
String tag = "debugging";
Handler mHandler= new Handler() {
public void handleMessage(Message msg){
super.handleMessage(msg);
switch(msg.what){
case SUCCESS_CONNECT:
ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket)msg.obj);
Toast.makeText(getApplicationContext(),"Connect",Toast.LENGTH_LONG).show();
String s= "Succesfully connected";
connectedThread.write(s.getBytes());
Log.i(tag, "connected");
break;
case MESSAGE_READ:
byte[] readbuff=(byte[])msg.obj;
String string= readbuff.toString();
Toast.makeText(getApplicationContext(), string,Toast.LENGTH_SHORT).show();
break;
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btAdapter = BluetoothAdapter.getDefaultAdapter();
arrayListBluetoothDevices = new ArrayList<BluetoothDevice>();
arrayListpaired = new ArrayList<String>();
arrayListPairedBluetoothDevices = new ArrayList<BluetoothDevice>();
adapter= new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, arrayListpaired);
listItemClickedonPaired = new ListItemClickedonPaired();
listViewPaired = (ListView) findViewById(R.id.listView3);
listItemClicked = new ListItemClicked();
listView = (ListView) findViewById(R.id.listView2);
listAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_activated_1);
listView.setAdapter(listAdapter);
listAdapter.notifyDataSetChanged();
listViewPaired.setAdapter(adapter);
setupMessageButton1();
setupMessageButton2();
setupMessageButton3();
setupMessageButton4();
setupMessageButton5();
init();
getPairedDevices();
}
private void init() {
listView.setOnItemClickListener(listItemClicked);
listViewPaired.setOnItemClickListener(listItemClickedonPaired);
filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String Action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(Action)) {
Toast.makeText(getApplicationContext(), "One Device Found", Toast.LENGTH_SHORT).show();
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (arrayListBluetoothDevices.size() < 1) // this checks if the size of bluetooth device is 0,then add the
{ // device to the arraylist.
listAdapter.add(device.getName() + "\n" + device.getAddress());
arrayListBluetoothDevices.add(device);
listAdapter.notifyDataSetChanged();
}
else
{
boolean flag = true; // flag to indicate that particular device is already in the arlist or not
for (int i = 0; i < arrayListBluetoothDevices.size(); i++) {
if (device.getAddress().equals(arrayListBluetoothDevices.get(i).getAddress())) {
flag = false;
}
}
if (flag == true) {
listAdapter.add(device.getName() + "\n" + device.getAddress());
arrayListBluetoothDevices.add(device);
listAdapter.notifyDataSetChanged();
}
}
}
}
};
registerReceiver(receiver, filter);
}
private void createBond(BluetoothDevice btDevice){
try
{
Method method = btDevice.getClass().getMethod("createBond", (Class[]) null);
method.invoke(btDevice, (Object[]) null);
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void unpairDevice(BluetoothDevice device) {
try {
Method method = device.getClass().getMethod("removeBond", (Class[]) null);
method.invoke(device, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
}
private void getPairedDevices() {
Set<BluetoothDevice> pairedDevice = btAdapter.getBondedDevices();
if(pairedDevice.size()>0)
{
for(BluetoothDevice device : pairedDevice)
{
arrayListpaired.add(device.getName()+"\n"+device.getAddress());
arrayListPairedBluetoothDevices.add(device);
}
}
adapter.notifyDataSetChanged();
}
public class ListItemClicked implements OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
bdDevice = arrayListBluetoothDevices.get(position);
Log.i("Log", "The device : " + bdDevice.toString());
getPairedDevices();
createBond(bdDevice);
adapter.notifyDataSetChanged();
Log.i("Log", "The bond is created: with" + bdDevice.toString());
}
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
BluetoothSocket tmp = null;
mmDevice = device;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
btAdapter.cancelDiscovery();
try {
mmSocket.connect();
} catch (IOException connectException) {
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
buffer = new byte[1024];
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
break;
}
}
}
/* 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) { }
}
}
#Override
protected void onDestroy() {
super.onDestroy();
btAdapter.cancelDiscovery();
unregisterReceiver(receiver);
}
class ListItemClickedonPaired implements OnItemClickListener
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,long id) {
bdDevice = arrayListPairedBluetoothDevices.get(position);
unpairDevice(bdDevice);
//arrayListPairedBluetoothDevices.clear();
}
}
private void makeDiscoverable() {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 150);
startActivity(discoverableIntent);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_CANCELED) {
Toast.makeText(MainActivity.this, "Bluetooth must be enabled to start scanning", Toast.LENGTH_SHORT).show();
} else
{
Toast.makeText(MainActivity.this, "Click on TURN_OFF to disable bluetooth", Toast.LENGTH_LONG).show();
}
}
private void setupMessageButton1() {
//1.get a reference for my button
Button messageButton = (Button) findViewById(R.id.button1);
//2. Set the click to run my code
messageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listAdapter.clear();
arrayListBluetoothDevices.clear();
btAdapter.startDiscovery();
}
});
}
private void setupMessageButton2() {
//1.get a reference to the button.
Button messageButton = (Button) findViewById(R.id.button2);
//2. set the click listener to run my code.
messageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (btAdapter.isEnabled()) {
listAdapter.clear();
btAdapter.disable();
} else
{
Toast.makeText(MainActivity.this, "Dont worry it's already off", Toast.LENGTH_SHORT).show();
}
}
});
}
private void setupMessageButton3() {
//1.get a reference for my button
Button messageButton = (Button) findViewById(R.id.button3);
//2. Set the click to run my code
messageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
private void setupMessageButton4() {
//1.get a reference for my button
Button messageButton = (Button) findViewById(R.id.button4);
//2. Set the click to run my code
messageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
btAdapter.enable();
}
});
}
private void setupMessageButton5() {
//1.get a reference for my button
Button messageButton = (Button) findViewById(R.id.button5);
//2. Set the click to run my code
messageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
makeDiscoverable();
}
});
}
}
Concerning the log i have that message :
"D/BluetoothUtils﹕ isSocketAllowedBySecurityPolicy start : device null"
"W/BluetoothAdapter﹕ getBluetoothService() called with no BluetoothManagerCallback"
"D/BluetoothSocket﹕ connect(), SocketState: INIT, mPfd: {ParcelFileDescriptor: FileDescriptor[75]} "
public class ListItemClicked implements OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
bdDevice = arrayListBluetoothDevices.get(position);
Log.i("Log", "The device : " + bdDevice.toString());
createBond(bdDevice);
adapter.notifyDataSetChanged();
ConnectThread connect = new ConnectThread(bdDevice);
connect.start();
}
}
For the connection, i use the ConnectThread found in Bluetooth APi developer Website:
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
BluetoothSocket tmp = null;
mmDevice = device;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
btAdapter.cancelDiscovery();
try {
mmSocket.connect();
} catch (IOException connectException) {
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
it's ok i found the solution, i had the problem with the phone i'm using, he is not supporting SPP.
Thank you anyway
I had to establish a socket in ActivityA in normal and ready to send data,
but now I want to also be able to use the same socket connection to transmit the data in ActivityB.I have looked for information on the Internet, it seems can use the singleton.I studied for a few days, I still don't know how to start, even find some examples of exercises too, but still do not know how to use my original program.
I want to first establish between ActivityA and SERVER connection, and to pass a value to the SERVER, then press the button to switch to ActivityB, and also transmit values to SERVER
Give me some advice or teaching sites can be, so that I can continue to study it, thank you very much
Establish socket methods:
public class MainActivity extends Activity {
Button Btn_Wifi,Btn_Power,Btn_Flame;
Boolean connected=false;
Boolean powerstatus=false;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null ;
Socket socket = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainView();
setListensers();
setButtonStatus();
}
private void mainView(){
Btn_Wifi = (Button) findViewById(R.id.Btn_Wifi);
Btn_Power = (Button) findViewById(R.id.Btn_Power);
Btn_Flame = (Button) findViewById(R.id.Btn_Flame);
}
private void setListensers(){
Btn_Wifi.setOnClickListener(BtnWifiOnClickListener);
Btn_Power.setOnClickListener(BtnPowerOnClickListener);
Btn_Flame.setOnClickListener(BtnFlameOnClickListener);
}
private void setButtonStatus(){
Btn_Power.setEnabled(false);
Btn_Flame.setEnabled(false);
}
Button.OnClickListener BtnWifiOnClickListener = new Button.OnClickListener(){
#Override
public void onClick(View view) {
if(!connected){
try {
socket = new Socket("IP", PORT);
dataOutputStream = new DataOutputStream(socket.getOutputStream());//and stream
changeConnectionStatus(true);//change the connection status
}catch (UnknownHostException e) {
changeConnectionStatus(false);
}catch (IOException e) {
changeConnectionStatus(false);
}
}else{
try {//try to close the socket
socket.close();
changeConnectionStatus(false);//change the connection status
} catch (UnknownHostException e) {//catch and
changeConnectionStatus(false);
} catch (IOException e) {//catch and
changeConnectionStatus(false);
}
}
}
};
Button.OnClickListener BtnPowerOnClickListener = new Button.OnClickListener(){
#Override
public void onClick(View view) {
if(!powerstatus){
try {
byte[] pon ={(byte) 0x10,(byte) 0x10};
dataOutputStream.write(pon);
dataOutputStream.flush();
PowerStatus(true);
}catch(Exception obj){
PowerStatus(false);
}
}else{
try {
byte[] poff ={(byte) 0x11,(byte) 0x11};
dataOutputStream.write(poff); //writeBytes(String str)
dataOutputStream.flush();
PowerStatus(false);
}catch(Exception obj){
PowerStatus(true);
}
PowerStatus(false);
}
}
};
Button.OnClickListener BtnFlameOnClickListener = new Button.OnClickListener(){
#Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setClass(MainActivity.this, FlameActivity.class);
startActivity(intent);
}
};
public void changeConnectionStatus(Boolean isConnected) {
connected=isConnected;//change variable
if(isConnected){//if connection established
Btn_Wifi.setText("CONNECTED");
Btn_Power.setEnabled(true);
}else{
Btn_Wifi.setText("NOT WIFI");
Btn_Power.setText("POWER OFF");
Btn_Power.setEnabled(false);
PowerStatus(false);
}
}
public void PowerStatus(Boolean isPowerOn) {
powerstatus=isPowerOn;//change variable
if(isPowerOn){//if connection established
Btn_Power.setText("POWER ON");
Btn_Flame.setText("SET FLAME");
Btn_Flame.setEnabled(true);
}else{
Btn_Power.setText("POWER OFF");
Btn_Flame.setText("CANT SET FLAME");
Btn_Flame.setEnabled(false);
}
}
}
You can certainly use it by declaring,i.e: in MainActivity which creates socket connection,static YourSocketClass objSocket // which creates connection and to use it in another Activity just called it as follow i.e:MainActivity.objSocket.yourMethod(any_param). by declaring static you can access it.
public static CommunicationClient objCommunicationClient;
public boolean setConnection(final String ipAddress, final Context context,
final boolean isFromSearch) {
class EstablishConnection extends AsyncTask<Void, Void, Boolean> {
ProgressDialog objDialog;
#Override
protected void onPreExecute() {
objDialog = new ProgressDialog(context);
objDialog.setMessage(context.getResources().getString(
R.string.strConnecting));
objDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
objDialog.show();
objDialog.setCancelable(false);
objDialog.setCanceledOnTouchOutside(false);
super.onPreExecute();
}
#Override
protected Boolean doInBackground(Void... params) {
boolean isConnected = false;
boolean isValid = false;
StrictMode.setThreadPolicy(policy);
objCommunicationClient = new CommunicationClient(ipAddress);
isSocketInitiated = objCommunicationClient.initSocket();
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo info = wifiManager.getConnectionInfo();
CommonUtils.SSID = info.getSSID();
if (!isSocketInitiated) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(
getApplicationContext(),
getResources().getString(
R.string.strCantConnect),
Toast.LENGTH_LONG).show();
}
});
} else {
isConnected = true;
if (!isFromSearch) {
CommonUtils.IP = ipAddress;
try {
objCommunicationClient.sendRequest(context,
"<APP_SPECIFIC>");
} catch (Exception e) {
e.printStackTrace();
}
} else {
isValid = isFromSearch;
}
if (isValid) {
final Intent objIntentToGraph = new Intent(context,
GraphDataActivity.class);
objIntentToGraph
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
runOnUiThread(new Runnable() {
#Override
public void run() {
startActivity(objIntentToGraph);
overridePendingTransition(
R.anim.slide_in_right,
R.anim.slide_out_left);
finish();
}
});
}
}
return isConnected;
}
#Override
protected void onPostExecute(Boolean result) {
try {
objDialog.cancel();
} catch (Exception err) {
err.printStackTrace();
}
super.onPostExecute(result);
}
}
boolean status = false;
try {
status = new EstablishConnection().execute().get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return status;
}
}
// and in my other Activity i called it as
MainActivity_HomePage.objCommunicationClient.sendRequest(
context, CommonUtils.STOP_COMMAND); //send request is method which send message to server.