the following is my code. Editor: Eclipse, Platform: Windows.
Its a chat application where 2 android emulators connect through a tcp socket.
UI consists of a send button, a text view and a text box.
Problem: As soon as I type text and hit send, the application crashes.
server port is 8000.
So my redirection is redir add tcp:8081:8000 and redir add tcp:8082:8000.
I donno what is wrong in my code. Please suggest me somthing I need to change.
public class HelloandroidActivity extends Activity
{
/** Called when the activity is first created. */
public int serverport=8000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final EditText nameField = (EditText) findViewById(R.id.editText1);
final Button button2 = (Button) findViewById(R.id.button1);
Integer severport=8000;
new Server().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,severport);
button2.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
final String name = nameField.getText().toString();
final TextView tv = (TextView) findViewById(R.id.textView1);
//tv.setText(name);
String s=null;
new Client().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,s);
}
});// end onclicklis
}//end oncreate
class Server extends AsyncTask <Integer, String, String>
{
public InetAddress byIpAsName ;
int r=0;
#Override
protected String doInBackground(Integer... serverport) {
//i[0]=serverport;
Integer[] sp=serverport;
BufferedReader in=null;
ServerSocket s=null;
r=sp[0];
String cIn="";
try {
//byIpAsName = InetAddress.getByName("10.2.2.15");
s=new ServerSocket(r);
while(true)
{
Socket client = s.accept();
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String line=in.readLine();
cIn=null;
while(line!=null){cIn=cIn.concat(line);}
}//while
} catch (IOException e) {
e.printStackTrace();
}
try {
s.close();
in.close();
}
catch (IOException e) {
e.printStackTrace();
}
return cIn;
}//end inBackground
//#SuppressWarnings("null")
protected void onPostExecute(String... cIn)
{
}//onpost execute
}//server class
public class Client extends AsyncTask<String, String, String>
{
PrintWriter out = null;
BufferedReader in=null;
String sIn=null;
//Server s1=new Server();
//int q=s1.r;
TelephonyManager tel = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String portStr = tel.getLine1Number().substring(tel.getLine1Number().length() - 4);
int q = Integer.parseInt(portStr);
Socket socket;
#Override
protected String doInBackground(String... params) {
try
{
//q=8080;
InetAddress byIpAsName1=InetAddress.getByName("10.0.2.2");
socket = new Socket(byIpAsName1, q);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line=in.readLine();
sIn=null;
while(line!=null){sIn=sIn.concat(line);}
}
catch (IOException e) {
e.printStackTrace();
}//catch
return sIn;
}//in background
protected void onPostExecute(String... sIn)
{
String c=null;
final TextView tv = (TextView) findViewById(R.id.textView1);
c=c.concat(sIn[0]);
tv.setText(c);
}
}
}//main class
From your logcat, what is important is this line:
03-16 23:12:23.434: E/AndroidRuntime(571): java.lang.SecurityException: Requires READ_PHONE_STATE: Neither user 10040 nor current process has android.permission.READ_PHONE_STATE.
This indicates that in order to run your code, you need the READ_PHONE_STATE permission in the android manifest.xml.
Add this line to the manifest, outside of the <application> tag but inside the <manifest> tag.
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
If this does not solve the issue, the problem could be related to this answer.
Related
Code first:
public class MyActivity extends Activity {
Button send;
TextView textv;
String answer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
send = (Button)findViewById(R.id.sendButton);
textv = (TextView)findViewById(R.id.textViewv);
send.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
MyClientTask myClientTask = new MyClientTask("localhost", 1234, "QUESTION");
myClientTask.execute();
}
});
}
void processAnswer() {
Log.i("DEBUG", "in processAnswer - before setting text");
Log.i("DEBUG", "ANSWER");
textv.setText("ANSWER\n"); // <-------- H E R E -----------
Log.i("DEBUG", "in processAnswer - after setting text");
}
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String message;
String response;
MyClientTask(String addr, int port, String msg){
dstAddress = addr;
dstPort = port;
message = msg;
response = "";
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
InetAddress serverAddr = InetAddress.getByName(dstAddress);
socket = new Socket(serverAddr, dstPort);
OutputStream out = socket.getOutputStream();
out.write(message.getBytes());
out.flush();
String msgrc = "";
int charsRead = 0;
char[] inputBuf = new char[4096];
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader in = new BufferedReader(isr);
while ((charsRead = in.read(inputBuf)) != -1) {
msgrc += new String(inputBuf).substring(0, charsRead);
}
// outer class variable
MyActivity.this.answer = msgrc;
out.close();
is.close();
socket.close();
Log.i("DEBUG", "before processing answer");
MyActivity.this.processAnswer();
Log.i("DEBUG", "after processing answer");
} catch (Exception e) {
}
return null;
}
}
}
The code above simply sends some message to a server and receives an answer. This answer should then be displayed in the TextView (see marked line). However, the app hangs at that line, i.e, LogCat displays
[...]
before processing answer
in processAnswer - before setting text
ANSWER
Then no more lines are written to LogCat. Has anybody an explanation for that? If the marked line is commented out, LogCat looks like
[...]
before processing answer
in processAnswer - before setting text
ANSWER
in processAnswer - after setting text
after processing answer
If you move your call to MyActivity.this.processAnswer() to onPostExecute() instead, perhaps that might work - IIRC, items on the UI thread should only be updated from the UI thread.
First inialize your text view by following , then add onPostExecute method bellow the doInBackground
method . And set your text there . Bellow is code which i change.
public class MyActivity extends Activity {
Button send;
TextView textv;
String answer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
send = (Button)findViewById(R.id.sendButton);
textv = (TextView)findViewById(R.id.textview);
send.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
MyClientTask myClientTask = new MyClientTask("localhost", 1234, "QUESTION");
myClientTask.execute();
}
});
}
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String message;
String response;
MyClientTask(String addr, int port, String msg){
dstAddress = addr;
dstPort = port;
message = msg;
response = "";
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
InetAddress serverAddr = InetAddress.getByName(dstAddress);
socket = new Socket(serverAddr, dstPort);
OutputStream out = socket.getOutputStream();
out.write(message.getBytes());
out.flush();
String msgrc = "";
int charsRead = 0;
char[] inputBuf = new char[4096];
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader in = new BufferedReader(isr);
while ((charsRead = in.read(inputBuf)) != -1) {
msgrc += new String(inputBuf).substring(0, charsRead);
}
// outer class variable
MyActivity.this.answer = msgrc;
out.close();
is.close();
socket.close();
Log.i("DEBUG", "before processing answer");
MyActivity.this.processAnswer();
Log.i("DEBUG", "after processing answer");
} catch (Exception e) {
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
textv.setText(msgrc);
}
}
}
i'm new in Android. I have the following code:
public class SettingsActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tcp_settings);
Button buttonConnect = (Button) findViewById(R.id.buttonConnect);
buttonConnect.setOnClickListener(new View.OnClickListener() {
EditText server_ip = (EditText) findViewById(R.id.set_server_ip);
EditText port = (EditText) findViewById(R.id.set_port);
#Override
public void onClick(View view) {
String serverAddr = server_ip.getText().toString();
String serverPort = port.getText().toString();
new connectTask().execute(serverAddr, serverPort);
}
});
}
class connectTask extends AsyncTask<String, Void, String> {
Socket socket;
#Override
protected String doInBackground(String... params) {
int servport = Integer.parseInt(params[1]);
try {
socket = new Socket(params[0], servport);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return params[0] + " : " + params[1];
}
}
}
I want to set a socket with server ip and port getting from EditTexts server_ip and port. In the connectTask I make a conversion from string to int in: int servport but i'm still getting error:
Caused by: java.lang.NumberFormatException: Invalid int "".
i have to make serverAddr to String because i have to put it in :
new connectTask().execute(serverAddr, serverPort);
But then socket require port as Int so conversion is required.
Could You help me and tell what i'm doing wrong ?
Your problem lies here within your code. You are passing in multiple parameters into a function that only receives one. Here is the def of execute: execute (Params... params)
new connectTask().execute(serverAddr, serverPort);
Change line to this:
new connectTask().execute(new String[]{serverAddr,serverPort});
Although the documentation does not say it, it is wanting an array of the first template object being passed in IF you are passing in more than one parameter.
I have 1 EditText 1Button and 1TextView, when I type url in Edittext and click button, the textView will be show the Html from website that i type the url in edittext. I want to get html from web by using url.
Problem
When I using this code in ( AVD Target version 2.3.3). AndroidManifest (minSdkVersion="10" targetSdkVersion="10") and I also change targetSdkVersion="15") both are work correct. but when I change it to run in (AVD target version 4.0.3) it's not work. Y? This is my code
final EditText et = (EditText) findViewById(R.id.editText1);
final Button b = (Button) findViewById(R.id.button1);
final TextView tv = (TextView) findViewById(R.id.textView1);
b.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
try {
URL url = null;
url = new URL(et.getText().toString());
URLConnection conn = url.openConnection();
BufferedReader buff = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line ="";
while((line = buff.readLine())!= null){
tv.append(line);
}
} catch (Exception e) {
}
You're getting a NetworkOnMainThreadException, you can't access the network on the UI thread when using Honeycomb or later. You need to do your work in an AsycnTask. See this question for more info.
//before OnCreate() method
URL url = null;
final TextView tv;
////////
b.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
try {
url = new URL(et.getText().toString());
new YourAsyncTask.execute();
}
} catch (Exception e) {
}
//after onCreate() method
class YourAsyncTask extends AsyncTask<Void, Void, Void>
{
private ProgressDialog progressDialog;
#Override
protected void onPreExecute()
{
//show your dialog here
progressDialog = ProgressDialog.show(YourActivity.this,"Please wait...", "Loading ...", true);
}
#Override
protected Void doInBackground(Void... params)
{
//make your request here - it will run in a different thread
try
{
URLConnection conn = url.openConnection();
BufferedReader buff = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line ="";
while((line = buff.readLine())!= null){
tv.append(line);
}
catch (Exception e)
{
// TODO: handle exception
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
try
{
progressDialog.dismiss();
///Show your Data here
}
catch (Exception e)
{
// TODO: handle exception
}
}
}
Check INTERNET PERMISSION in Menifest.
I am working on a basic client-server application to send messages between an android app (client) and a java server on the pc. The messages are being sent and received fine when I use the emulator but does not work when i try to use the app on my mobile. I connect my phone to a wifi network hosted by my laptop using connectify. I wonder whats preventing my phone from connecting...
Here is the code :
SERVER
public class ServerMain {
public static void main(String argv[]) throws Exception
{
String clientSentence;
String capitalizedSentence;
int sock = 1234;
ServerSocket welcomeSocket = new ServerSocket(sock);
while(true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
clientSentence = inFromClient.readLine();
System.out.println("Received: " + clientSentence);
if(clientSentence.equalsIgnoreCase("QUIT"))
break;
}
welcomeSocket.close();
}
}
CLIENT
public class Message extends Activity {
EditText et;
String msg1 = "";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et = (EditText)findViewById(R.id.etTest);
}
// TODO Auto-generated method stub
class GetMessages extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
final String msg = et.getText().toString();
try{
Socket clientSocket = new Socket("*myip*", 1234);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
String sentence = msg;
outToServer.writeBytes(sentence + '\n');
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
public void readWebpage(View view) { //The button on click calls this function (from xml)
new GetMessages().execute();
}
}
Hi I am building an app which requires the user to press buttons (total 8 buttons). These buttons used to send strings to the server onclick . The problem here I'm having is when i press any of the button after connecting to the server it sends the string as it should but the 2nd time nothing happens. I was suggested to use doInBackground() from AsyncTask, to run keep running the socket and write to it each time the buttons are pressed. But i am unable to do so. What should I do ? I don't know where is the problem. Here I'm putting my code.
This is my Activity
public class Acontroller extends Activity {
Button bForward;
Button bBackward;
Button bRight;
Button bLeft;
Button bSelect;
Button bStart;
Button bB;
Button bA;
Socket s;
DataOutputStream os;
String ip;
// MyAppActivity ip = new MyAppActivity();
MyThread start = new MyThread();
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.nesskin);
bForward = (Button) findViewById(R.id.bForward);
bBackward = (Button) findViewById(R.id.bBackward);
bRight = (Button) findViewById(R.id.bRight);
bLeft = (Button) findViewById(R.id.bLeft);
bSelect = (Button) findViewById(R.id.bSelect);
bStart = (Button) findViewById(R.id.bStart);
bA = (Button) findViewById(R.id.bA);
bB = (Button) findViewById(R.id.bB);
Bundle gotIP = getIntent().getExtras();
ip = gotIP.getString("ipAddress");
// start.doInBackground(ip);
//start.execute(ip);
// sock.start();
}
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
bForward.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
start.execute(ip);
}
});
And from the thread.
public class MyThread extends AsyncTask <String, Void, String>{
Socket s;
DataOutputStream os;
String ip;
String cmd;
#Override
protected void onPreExecute() {
Log.i("AsyncTask", "onPreExecute");
}
#Override
protected String doInBackground(String... params) {
int port = 2222;
// TODO Auto-generated method stub
if(s.isConnected()){
try {
os.writeUTF("forward");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
try {
s= new Socket(ip, port);
os = new DataOutputStream(s.getOutputStream());
os.writeUTF("forward");
}catch(Exception e){
e.printStackTrace();
}
finally{
if (s!= null){
try {
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (os != null){
try {
os.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
return null;
}
My objective is as many times the user clicks the buttons the respective strings must be send to the server. Here is my server code I'm using PC as server.
public class Server
public static void main(String[] args) throws AWTException {
String msg_received = null;
String fw = "forward";
String bw = "backward";
String l = "left";
String r = "right";
String se = "select";
String st = "start";
String a = "a";
String b = "b";
String fin = "finish";
// Boolean finish = (msg_received.equal(fin));
Robot robot = new Robot();
try {
ServerSocket ss = new ServerSocket(2222);
System.out.println("Server Started...");
while (true) {
Socket s = ss.accept();
System.out.println("Connection Request Received");
DataInputStream DIS = new DataInputStream(s.getInputStream());
msg_received = DIS.readUTF();
System.out.println(msg_received);
// s.close();
// ss.close();
if (msg_received.equals(fw)) {
// tu yeh kerna
robot.keyPress(KeyEvent.VK_UP);
robot.keyRelease(KeyEvent.VK_UP);
}
Please help me it really important to me. Thanks in advance.
You can't re-use an AsyncTask. You have to create a new object and call execute.
Replace
start.execute();
with
start = new MyThread();
start.execute(ip);
or if you can get away with removing the instance when it's done, then you can just do this:
(new MyThread()).start();
EDIT:
To send parameters to AsyncTask, do this:
start.execute(ip, cmd, param3, param4, param5);
in doInBackground collect the parameters like so:
protected Void doInBackground(String... params)
{
String ipParam = params[0];
String cmdParam = params[1];
String thirdParam = params[2];
String fourthParam = params[3];
String fifthParam = params[4];
}
You can pass as many Strings as you want into params and it will automatically create a new array containing all the parameters at runtime. Just note that if you only pass in two, then the params size will only be two. If you pass in 100 parameters, then params will be 100 units in size.