I make a client in Java, and make some test on Eclipse IDE and work perfectly, on localhost, external server, etc.
When I export the code to android, it doesn't work, the server don't receive nothing ...
Class code:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
/**
* Jose Manuel R---- ----
* Java version 2.0
*/
public class ClienteTCP {
private CharSequence TCP_HOST = "localhost";
private int TCP_PORT = 5000;
volatile private CharSequence SSID, PASS, SERVER_IP;
volatile private int SERVER_PORT;
final private String START = "START";
// Constructor vacio
public ClienteTCP( ) {
}
// Constructor con argumentos
public ClienteTCP(CharSequence tcp_host, int tcp_port, CharSequence ssid, CharSequence pass, CharSequence ip, int port) {
this.TCP_HOST = tcp_host;
this.TCP_PORT = tcp_port;
this.SSID = ssid;
this.PASS = pass;
this.SERVER_PORT = port;
this.SERVER_IP = ip;
}
// CONF METHODS
public void setServerTCPConf(CharSequence host, int port) {
setTCP_HOST(host);
setTCP_PORT(port);
}
public void setApConf(CharSequence ssid, CharSequence pass) {
setSSID(ssid);
setPASS(pass);
}
public void setServerConf(CharSequence ip, int port) {
setSERVER_IP(ip);
setSERVER_PORT(port);
}
// PUBLIC METHODS
public String configureMC() {
sendMessage( createMessage("AP="+SSID.toString()+","+PASS.toString().toString()) );
sendMessage( createMessage("SERVER="+SERVER_IP.toString()+","+SERVER_PORT) );
return sendMessage( createMessage(START) );
}
public String sendMessage(String msg) {
String msgRec = null;
Socket s;
try {
s = new Socket(TCP_HOST.toString(), TCP_PORT);
BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
writer.write(msg, 0, msg.length());
writer.flush();
msgRec = reader.readLine();
reader.close();
writer.close();
s.close();
} catch (IOException e) {
android.util.Log.d("log", e.getMessage());
// e.printStackTrace();
}
return msgRec;
}
// PRIVATE METHODS
private String createMessage(String msg) {
char _AF = ((char)175);
char _FA = (char)250;
return (_AF+msg+_FA);
}
}
MainActivity:
/*
Jose Manuel adad adsasd
TCP client for Android
v1.2-alpha
*/
import android.os.StrictMode;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.net.Socket;
public class MainActivity extends ActionBarActivity {
private volatile EditText debugText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Button button = (Button) findViewById(R.id.SEND);
EditText ssid = (EditText) findViewById(R.id.textSsid);
EditText pass = (EditText) findViewById(R.id.textPass);
debugText = (EditText) findViewById(R.id.debugText);
debugText.setText("Version 1-alpha");
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Do something in response to button click
demo();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void demo() {
ClienteTCP cliente = new ClienteTCP();
CharSequence cs = cliente.sendMessage("Hola Mundo");
if ( cs != null)
debugText.setText(cs);
else
debugText.setText("ERROR OCURRED");
}
}
I'm sorry due to big code, but I'm going to cry ://///
If you try to connect to "localhost" from the Android device, it will try to connect to a service on the Android device because, on whatever device you are running, that is the "local host".
Since the service is running on your machine, it needs to be referenced via an IP address that is reachable by the Android device. That means that if the phone/tablet/whatever is connected to your local WiFi, any 192.168.*.* (private network) address should connect just fine but if it's on the public Internet (via a cellular network, for example) then it'll require the public IP address of your machine or of another device, such as a firewall, that will forward the port to your machine on your internal network.
Try change TCP_HOST from localhost to 10.0.2.2
Related
This is the simple code where i'll use me Android phone to send the password to the ArduinoMKR1000 over a network which will in turn check your password and unlock the gift. I use UDP sockets. The Arduino code is:
#include <SPI.h>
#include <WiFi101.h>
#include <WiFiUdp.h>
// TODO change this
int status = WL_IDLE_STATUS;
char ssid[] = "yourNetwork"; // your network SSID (name)
char pass[] = "secretPassword"; // your network password (use for WPA, or use
// as key for WEP)
unsigned int localPort = 2390; // local port to listen on
char packetBuffer[255]; // buffer to hold incoming packet
char replyRight[] = "you have your gift!"; // a string to send back
char replyWrong[] = "try again!";
WiFiUDP Udp;
// Array of passwords to choose from, expand it or fetch some words from the
// internet!
const int PasswordArrayLength=5;
String passwords[PasswordArrayLength] = {
"Merry",
"Christmas",
"42", // The meaning of everything must be here!
"Santa",
"HoHo"
};
bool checkPassword(); // Checks for the received password
void openGift(); // Unlocks the gift
void showWarning(); // Locks the gift and displays the warning
const int lockPin = 4;
const int warningLedPin = 5;
String guess; // password guess
void setup() {
// Initialize serial
Serial.begin(9600);
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to Wifi: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.println("Connected to wifi");
// print your WiFi shield's IP address, your phone will connect to this IP Address
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// if you get a connection, report back via serial:
Udp.begin(localPort);
}
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if (!packetSize)
{
// read the packet into packetBufffer
int len = Udp.read(packetBuffer, 255);
if (len > 0) packetBuffer[len] = 0; // Null terminate the string to avoid data corruption
Serial.println("Entered password:");
Serial.println(packetBuffer);
guess=String(packetBuffer); // Put the char array in a string to compare easily
if (checkPassword())
{
// Open the gift
openGift();
// Send the reply
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(replyRight);
Udp.endPacket();
}
else
{
// Show alert
showWarning();
// Tell the sender to try again
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(replyWrong);
Udp.endPacket();
}
}
}
void openGift()
{
digitalWrite(lockPin,HIGH); // Unlock the gift
digitalWrite(warningLedPin,LOW); // Turn of the warning if it was on
}
void showWarning()
{
digitalWrite(warningLedPin,LOW); // Turn on the warning led
digitalWrite(lockPin,HIGH); // Lock the gift
}
bool checkPassword()
{
for(int i =0; i < PasswordArrayLength; i++)
{
if(guess.equals(passwords[i]))
{
return true;
}
}
return false;
}
while the code of android is:
package com.example.ahmed.udpsender;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.Toast;
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 java.util.regex.Pattern;
public class MainActivity extends AppCompatActivity
private DatagramSocket socket;
private EditText ipEditText;
private EditText portEditText;
private EditText messageEditText;
// Socket operation time out in milliseconds
private static final int TIMEOUT_MILLIS = 2000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
// Get the handles of the text fields to use them in validation later
// NOTE: this must exist after "setContentView(R.layout.activity_main);"
ipEditText = ((EditText) findViewById(R.id.editTextIp));
portEditText = ((EditText) findViewById(R.id.editTextPort));
messageEditText = ((EditText) findViewById(R.id.textAreaMessage));
try {
socket = new DatagramSocket(); // Create a UDP socket
socket.setBroadcast(true); // Enable broadcasts
socket.setSoTimeout(TIMEOUT_MILLIS); // Set timeout for socket operations
} catch (SocketException e) {
showToast(e.getMessage());
}
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onSendButtonClick();
}
});
}
#Override
public void onDestroy() {
super.onDestroy();
this.socket.close(); // Destroy the socket when the app closes
}
private void onSendButtonClick() {
final String ipString = ipEditText.getText().toString();
final String portString = portEditText.getText().toString();
boolean ipValidated = validateIp(ipString);
boolean portValidated = validatePort(portString);
if (!ipValidated && !portValidated) {
showToast("Ip and Port are invalid");
} else if (!ipValidated) {
showToast("IP is invalid");
} else if (!portValidated) {
showToast("Port number is invalid");
} else { // Parameters are syntactically correct
Editable editable = messageEditText.getText();
final String message = editable.toString(); // Get the text in the EditText
// Network operations must be started on a separate
// thread other than the UI thread
new Thread() {
public void run() {
if (sendPacket(message, ipString, Short.parseShort(portString))) {
String reply = receivePacket();
showToastOnUiThread(reply);
}
}
}.start();
editable.clear(); // Clear the message edit text
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private boolean validateIp(String ip) {
if (ip.length() == 0) return false;
if (!IP_ADDRESS.matcher(ip).matches()) {
// Show a message
showToast("Please enter a valid IP Address");
return false;
} else {
return true;
}
}
private boolean validatePort(String text) {
if (text.length() == 0) return false;
try {
Short.parseShort(text); // If this succeeds, then it's a valid port
return true;
} catch (NumberFormatException e) {
showToast("A valid port number is between 1 and " + Short.MAX_VALUE);
return false;
}
}
private boolean sendPacket(String message, String ipString, short portNumber) {
byte messageBytes[] = message.getBytes();
if (message.isEmpty()) return false;
try {
// Create the packet containing the message, IP and port number
final DatagramPacket packet = new DatagramPacket(messageBytes, messageBytes.length,
InetAddress.getByName(ipString), portNumber);
socket.send(packet);
// The UDP packet left the pc safely, we don't know if it was received somewhere
return true;
} catch (final UnknownHostException e) {
showToastOnUiThread("Couldn't find host");
return false;
} catch (final IOException e) {
showToastOnUiThread(e.getMessage());
return false; // Something went wrong
}
}
private String receivePacket() {
try {
byte buffer[] = new byte[255];
DatagramPacket p = new DatagramPacket(buffer, buffer.length);
socket.receive(p);
return new String(p.getData()); // Convert the packet to a string and return it
} catch (IOException ignored) {
}
// Nobody replied to the packet, maybe the address didn't exist in the network
return "Nothing received, timeout";
}
// A toast is the tiny message you see on the screen
private void showToastOnUiThread(final String text) {
runOnUiThread(new Runnable() {
#Override
public void run() {
showToast(text);
}
});
}
private void showToast(String message) {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
//--------------------------------------------------------------------------------------
// Regex for validating IP addresses
private static final Pattern IP_ADDRESS
= Pattern.compile(
"((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]"
+ "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]"
+ "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
+ "|[1-9][0-9]|[0-9]))");
}
THE PROBLEM IS: when i try to input the password android return toast "Nothing received, timeout" while arduino stop the void loop(). What is the problem? Ps I have conneted arduino and android at the same external hotspot
i have Resolved replace //Send the reply with a brodcast ip: Udp.remoteIP() change in IPAddress ip(255, 255, 255, 255);
I am fairly new to Android, i want to write a telnet client app for my Android. I have written the code using Apache commons library for telnet. Now i am able to connect to telnet server (for that i have used Asyctask concept) and able to read login banner after a long time i don't know what is causing that. I have modified the example given in Apache commons to work with my android code.I have two java codes in my "src" folder (MainActivity.java and TelnetClientExample.java). First, i want to get the login prompt and then i want user to interact with it please help, Thanks in advance :)
I am posting my screen capture of what i am getting.
MainActivity.java
package com.example.telnetapp;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.io.PrintWriter;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity{
public static int port_int_address;
private EditText server,port;
private Button connect;
public static String ip,port_address;
public PrintWriter out;
public static TextView textResponse;
static String response;
public InputStream instr;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
server = (EditText)findViewById(R.id.edittext1);
port = (EditText)findViewById(R.id.edittext2);
connect = (Button)findViewById(R.id.connect);
textResponse = (TextView)findViewById(R.id.response);
connect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ip = server.getText().toString();
port_address = port.getText().toString();
port_int_address = Integer.parseInt(port_address);
try{
MyClientTask task = new MyClientTask(ip, port_int_address);
task.execute();
}
catch(Exception e){Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
TelnetClientExample job;
MyClientTask(String inetAddress, int port){
dstAddress = inetAddress;
dstPort = port;
}
#Override
protected Void doInBackground(Void... arg0) {
try {
job = new TelnetClientExample();
job.backgroundjob();
}
catch (Exception e)
{
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
try {
instr = TelnetClientExample.tc.getInputStream();
byte[] buff = new byte[1024];
int ret_read = 0;
do
{
ret_read = instr.read(buff);
if(ret_read > 0)
{
MainActivity.response += new String(buff, 0, ret_read);
}
}
while (ret_read >= 0);
}
catch (Exception e) {
MainActivity.response += e.toString();
MainActivity.response += "From reading from telnet server ! \n";
}
textResponse.setText(response);
super.onPostExecute(result);
}
}
}
TelnetClientExample.java
package com.example.telnetapp;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.net.telnet.TelnetClient;
public class TelnetClientExample {
public String remoteip = MainActivity.ip;
public int remoteport= MainActivity.port_int_address;
public static TelnetClient tc = null;
public void backgroundjob() throws IOException {
tc = new TelnetClient();
try {
tc.connect(remoteip, remoteport);
}
catch (Exception e) {
}
}
public void close_con(){
try {
tc.disconnect();
}
catch (Exception e) {
MainActivity.response += e.toString();
MainActivity.response += "From reading from disconnecting telnet server ! \n";
}
}
}
The problem is in this code snippet . please look into this and help me to get an interactive session.
protected void onPostExecute(Void result) {
try {
instr = TelnetClientExample.tc.getInputStream();
byte[] buff = new byte[1024];
int ret_read = 0;
do
{
ret_read = instr.read(buff);
if(ret_read > 0)
{
MainActivity.response += new String(buff, 0, ret_read);
}
}
while (ret_read >= 0);
}
catch (Exception e) {
MainActivity.response += e.toString();
MainActivity.response += "From reading from telnet server ! \n";
}
textResponse.setText(response);
super.onPostExecute(result);
}
The problem i am getting -
This question already has answers here:
NetworkOnMainThreadException [duplicate]
(5 answers)
Closed 7 years ago.
On Being a Duplicate: Please note that I have acknowledged other Q&As (Thread UI) but my case is different as I have tried to use the solution but it doesn't work at all instances (as it works for writing but doesn't for reading.
Updated: I know exactly what is going wrong please read the bold My Question part
I'm trying to make an Android Socket Client that connects to a Java server via WiFi.The final client will send and receive commands and logs as there will be a textbox that user can write SQL commands in it and by hitting a button command will be sent from the app to the Desktop server and show the log in another textbox.
so far I have been trying to use This Answer from another question to make that Client, and adding following lines in the TCP client.
Scanner in = new Scanner(socket.getInputStream());//in doInBackground
//also changed send method a little
public String send(String command)
{
if ( connected ){
out.println(command);
out.flush();
String back = in.nextLine().toString();
return back;
}
return "not Connected";
}
The connection is made successfully and the send method does send the command while server receives it.but the String that server writes back throw the mentioned exception in the title despite the fact that I am using the AsyncTask.
My Question
Why Scanner throws this exception while PrintWriter works correctly ?
Main Activity
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
EditText serverIP, servMsg;
String ip, serverOut;
Button connectBtn;
TcpClient tcpClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
serverIP = (EditText) findViewById(R.id.serverIP);
connectBtn = (Button) findViewById(R.id.connectBtn);
servMsg = (EditText) findViewById(R.id.servMsg);
}
public void onConnectBtn(View view){
try{
ip = serverIP.getText().toString();
tcpClient = new TcpClient();
tcpClient.connect(getApplicationContext(), ip, 8082);
serverOut = tcpClient.send("HELLO FROM cat:123");
servMsg.setText(serverOut);
tcpClient.disconnect(getApplicationContext());
}
catch (Exception e){
Toast.makeText(getApplicationContext(),
"Exception on runnning thread: " + e.getMessage().toString(), Toast.LENGTH_LONG).show();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
TCP Client
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;
public class TcpClient {
private static final String TAG = TcpClient.class.getSimpleName();
private Socket socket;
private PrintWriter out;
private Scanner in;
private boolean connected;
public TcpClient() {
socket = null;
out = null;
connected = false;
}
public void connect(Context context, String host, int port) {
new ConnectTask(context).execute(host, String.valueOf(port));
}
private class ConnectTask extends AsyncTask<String, Void, Void> {
private Context context;
public ConnectTask(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
showToast(context, "Connecting..");
super.onPreExecute();
}
#Override
protected void onPostExecute(Void result) {
if (connected) {
showToast(context, "Connection successful");
}
super.onPostExecute(result);
}
private String host;
private int port;
#Override
protected Void doInBackground(String... params) {
try {
String host = params[0];
int port = Integer.parseInt(params[1]);
socket = new Socket(host, port);
out = new PrintWriter(socket.getOutputStream(), true);
in = new Scanner(socket.getInputStream());
} catch (UnknownHostException e) {
showToast(context, "Don't know about host: " + host + ":" + port);
Log.e(TAG, e.getMessage());
} catch (IOException e) {
showToast(context, "Couldn't get I/O for the connection to: " + host + ":" + port);
Log.e(TAG, e.getMessage());
}
connected = true;
return null;
}
}
public void disconnect(Context context) {
if (connected) {
try {
out.close();
socket.close();
connected = false;
} catch (IOException e) {
showToast(context, "Couldn't get I/O for the connection");
Log.e(TAG, e.getMessage());
}
}
}
/**
* Send command to a Pure Data audio engine.
*/
public String send(String command)
{
if ( connected ){
out.println(command);
out.flush();
String back = in.nextLine().toString();
return back;
}
return "not Connected";
}
private void showToast(final Context context, final String message) {
new Handler(context.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
});
}
}
Also the Layout right now consist of two TextEdits one in which user types IP of the computer(which I checked with correct IPs) and the second one is going to show Server response.
I believe you are not "flushing", which is essentially forcing the buffer to empty out its contents. Please take a look at this working chat server/client code that uses TCP/IP. On a side note, I would recommend not extending ActionBarActivity because it is deprecated (Google says they will move away from it and won't be supporting it soon). Please see 3rd link.
ChatServer.java
ChatClient.java
ActionBar Activity deprecation
I have the following code which is working without any errors, but I get this
Skipped 116 frames. The application may be doing too much work on its main thread.
That happens when I press the Single button and the init() method is executed.
How can I execute the method in another thread so it won't break like that ?
package com.apppppp.pampam;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Set;
import android.support.v7.app.ActionBarActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Bundle;
import android.os.ParcelUuid;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends ActionBarActivity {
Button singleButton;
BluetoothAdapter mBluetoothAdapter;
BluetoothAdapter blueAdapter ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
blueAdapter = BluetoothAdapter.getDefaultAdapter();
singleButton = (Button) findViewById(R.id.button1);
setButtonOnClickListeners();
return true;
}
private void setButtonOnClickListeners(){
singleButton.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
try {
write("Salut");
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("No luck");
}
}
});
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private OutputStream outputStream;
private InputStream inStream;
private void init() throws IOException {
if (blueAdapter != null) {
if (blueAdapter.isEnabled()) {
Set<BluetoothDevice> bondedDevices = blueAdapter.getBondedDevices();
System.out.println(bondedDevices);
if(bondedDevices.size() > 0){
Iterator iter = bondedDevices.iterator();
BluetoothDevice device = (BluetoothDevice) iter.next();
ParcelUuid[] uuids = device.getUuids();
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(uuids[0].getUuid());
socket.connect();
outputStream = socket.getOutputStream();
inStream = socket.getInputStream();
}
else{
Log.e("error", "No appropriate paired devices.");
}
}else{
Log.e("error", "Bluetooth is disabled.");
}
}
}
public void write(String s) throws IOException{
init();
outputStream.write(s.getBytes());
}
public void run() {
final int BUFFER_SIZE = 1024;
byte[] buffer = new byte[BUFFER_SIZE];
int bytes = 0;
int b = BUFFER_SIZE;
while (true) {
try {
bytes = inStream.read(buffer, bytes, BUFFER_SIZE - bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Thank you
You are doing the Bluetooth related calls on the UI thread and you blocking the UI thread with these calls.
I made a program which can connect bluetooth to my device and getting byte from my device.
But the program cannot running in the background.
I only want to get byte in the background.
I made another class which extend Service and trying to make my program run.
public class NickyService extends Service {
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent,flags,startId);
//Wrong code
MainActivity a1 = new MainActivity();
return START_NOT_STICKY;
}
}
I have no idea with fixing this.
How do I fix this big problem?
The following codes is right!
It can get byte and connect to device,but cannot running in the background!!
MainActivity.java
package com.example.bluetooth10;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;
import org.apache.http.util.ByteArrayBuffer;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Vibrator;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
// textview for connection status
ListView pairedListView;
private ArrayAdapter<String> mPairedDevicesArrayAdapter;
TextView sensorView0, title_paired_devices;
String paired = "";
Handler bluetoothIn;
private TextView connecting_str;
private TextView textView1;
final int handlerState = 0; // used to identify handler message
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private ByteArrayBuffer baf1 = new ByteArrayBuffer(32);
String path = Environment.getExternalStorageDirectory().toString();
private ConnectedThread mConnectedThread;
private static final UUID BTMODULEUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); // SPP UUID service - this should work for most devices
private static String address; // String for MAC address
protected void onHandleIntent(Intent workIntent) {
// Gets data from the incoming Intent
String dataString = workIntent.getDataString();
// Do work here, based on the contents of dataString
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView1 = (TextView) findViewById(R.id.textView1);
title_paired_devices = (TextView) findViewById(R.id.title_paired_devices);
...
bluetoothIn = new Handler() {
public void handleMessage(android.os.Message msg) {
connecting_str.setText("Connection!!");
byte[] readBuf = (byte[]) msg.obj; // obj = buffer from connect thread
for (int i=0; i<msg.arg1; i++) {
baf1.append((byte)readBuf[i]);
if (baf1.length()>1){
String str1 = String.format("%02X",(byte)baf1.byteAt(baf1.length()-2));
String str2 = String.format("%02X",(byte)baf1.byteAt(baf1.length()-1));
if (str1.equals("01") && str2.equals("FF")){
int tmpb = (byte)baf1.byteAt(13);
baf1.clear();
}
}
}
}
int toInt( byte[] bytes ) {
int result = 0;
for (int i=0; i<bytes.length; i++) {
result = ( result << 8 ) - Byte.MIN_VALUE + (int) bytes[i];
}
return result;
}
};
btAdapter = BluetoothAdapter.getDefaultAdapter(); // get Bluetooth adapter
checkBTState();
}
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException
{
return device.createRfcommSocketToServiceRecord(BTMODULEUUID);
//creates secure outgoing connecetion with BT device using UUID
}
public void onResume() {
super.onResume();
checkBTState();
btAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedDevices = btAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);//make title viewable
for (BluetoothDevice device : pairedDevices) {
if (!paired.equals("")) paired = paired + ",";
paired = paired + device.getName() + ";" + device.getAddress();
}
} else {
paired = "no devices paired";
}
String str0[] = paired.split(",");
String str1 = str0[0]; //pairedListView.getItemAtPosition(0).toString(); //Get MAC address from DeviceListActivity
String str2[] = str1.split(";");
address = str2[1]; //Get the MAC address from the DeviceListActivty via EXTRA
BluetoothDevice device = btAdapter.getRemoteDevice(address); //create device and set the MAC address
try {
btSocket = createBluetoothSocket(device);
} catch (IOException e) {
Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_LONG).show();
}
try {
btSocket.connect();
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) { }
}
mConnectedThread = new ConnectedThread(btSocket);
mConnectedThread.start();
}
public void onPause() {
super.onPause();
try {
btSocket.close(); //Don't leave Bluetooth sockets open when leaving activity
} catch (IOException e2) { }
}
private void checkBTState() {
btAdapter = BluetoothAdapter.getDefaultAdapter(); // CHECK THIS OUT THAT IT WORKS!!!
if(btAdapter==null) {
Toast.makeText(getBaseContext(), "Device does not support Bluetooth", Toast.LENGTH_SHORT).show();
finish();
} else {
if (!btAdapter.isEnabled()) {
//Prompt user to turn on Bluetooth
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
// ***********************************************************
// create new class for connect thread
// ***********************************************************
private class ConnectedThread extends Thread {
private final InputStream mmInStream;
private final OutputStream mmOutStream;
//creation of the connect thread
public ConnectedThread(BluetoothSocket socket) {
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
//Create I/O streams for connection
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[40]; //The arduino is sending a small amount of data so a large buffer is not needed
int bytes;
// Keep looping to listen for received messages
while (true) {
try {
bytes = mmInStream.read(buffer); //read bytes from input buffer
bluetoothIn.obtainMessage(handlerState, bytes, -1, buffer).sendToTarget(); //Send message to handler
} catch (IOException e) {
break;
}
}
}
}
}