calling php web service from an android client? - android

I'm very new to android programming and I tried to call a php web service from android using HttpClient. But while app is running it's stopped saying "Unfortunately ServiceTest is stopped" and terminated.
Following is my code.
public class ServiceTestActivity extends Activity {
private Button btn;
private TextView txt;
String result = "";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.button1);
txt = (TextView) findViewById(R.id.txt_name);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
callWebErvice("http://localhost/mvc/login/test");
}
});
}
public void callWebErvice(String serviceURL) {
HttpClient httpclient = new DefaultHttpClient();
HttpGet request = new HttpGet(serviceURL);
ResponseHandler<String> handler = new BasicResponseHandler();
try {
result = httpclient.execute(request, handler);
txt.setText(result);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
httpclient.getConnectionManager().shutdown();
Log.i("my result", result);
} // end callWebServe
}
Can anybody find out the reason for this?

There are three types of operations which we should never perform on UI thread.
Network operations.
DB operations
File operations.
From your code I can see that you are performing network operation on UI thread and it will definitely lead you into ANR (Application Not Responding).
Whenever ANR happens of application, android just kills the application.
You will have to use worker thread to perform Network Operation.

Related

Webservice call from Android failing

Very new at Android development. Trying to call a webservice in Android Studio and getting this: java.net.SocketTimeoutException: SSL handshake timed out. I dont see traffic with wireshark and am not sure at what point its failing. Does not seem to leave the emulator.
EDIT: The webservice contains three methods, for lack of better term. I am not sure how to call the proper method in android. In powershell I call like this:
Powershell:
$myname = New-WebServiceProxy -Uri $URI -Namespace myname-class ssl
$myname.webservicemethod($qualifications,0,30)
Android:
public class MainActivity extends AppCompatActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button2);
final TextView textview = findViewById(R.id.textView);
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
AsyncTask asyncTask = new AsyncTask()
{
#Override
protected Object doInBackground(Object[] objects)
{
OkHttpClient client = new OkHttpClient();
HttpUrl.Builder urlBuilder = HttpUrl.parse("https://ip of webservice/pathvalue/WSDL/public/hostname/name").newBuilder();
urlBuilder.addQueryParameter("username", "someuser");
urlBuilder.addQueryParameter("password", "somepass");
urlBuilder.addQueryParameter("qualification", "Assigned Group=Admin Group");
String url = urlBuilder.build().toString();
Request request = new Request.Builder().url(url).build();
Response response = null;
try
{
response = client.newCall(request).execute();
return response.body().string();
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Object o)
{
textview.setText(o.toString());
}
}.execute();
}
});
}
}
I suspect preventing SocketTimeoutException is beyond our limit. One way to effectively handle it is to define a connection timeout and later handle it by using a try catch block. Hope this will helps
HttpUrlConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(7000); //set the timeout in milliseconds

Android socket client not receiving from java server

My app is sending data to the java socket server but it is only displaying the first message it receives from the server and not the other messages.
The Server is multi threaded.
I have created two clients in java both are sending and receiving messages through the server but in android app I am having problem receiving data.
This is the complete code of the Android client.
public class MainActivity extends AppCompatActivity {
Socket client;
EditText writeMsg;
TextView displayMsg;
String userInput;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
writeMsg = (EditText) findViewById(R.id.editText1);
displayMsg = (TextView) findViewById(R.id.textView);
ReceiveMsg obj = new ReceiveMsg();
Thread tr = new Thread(obj);
tr.start();
}
// A button to send msg to server when clicked
public void sendBtn(View view){
userInput = writeMsg.getText().toString();
SendMessage object = new SendMessage();
object.execute();
}
private class SendMessage extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try {
client = new Socket("10.0.2.2", 4444);
PrintWriter output = new PrintWriter(client.getOutputStream(), true);
output.print(userInput);
output.flush();
output.close();
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
class ReceiveMsg implements Runnable {
public void run() {
try {
client = new Socket("10.0.2.2", 4444);
BufferedReader in =
new BufferedReader(
new InputStreamReader(client.getInputStream()));
int i = 0;
while (i == 0) {
displayMsg.setText(in.readLine());
}
} catch (Exception e) {
}
}
}
}
I want the app to display the newly received message in the text-view and overwrite the existing message.
You create two client sockets. One for sending and one for receiving.
Normal would be only one client socket who sends a command and then receives the reply of the server.
As usual, you are reading lines, but you aren't sending lines.
Use println(), not print().
You also need to stop reading when you get an IOException, or when readLine() returns null.
Why there are two client sockets is another mystery.

Android HTTP Request Making App Irresponsive

I want to make a simple HTTP Head Request to URL which is fetched from a text box. Everytime I enter the URL and Click to get the HTTP response, the App Become Irrespnosive. Here is the code :
public void MakeRequest(View v)
{
EditText mEdit;
TextView txtresponse;
txtresponse = (TextView)findViewById(R.id.textView1);
mEdit = (EditText)findViewById(R.id.editText1);
HttpClient httpClient = new DefaultHttpClient();
HttpHead httphead = new HttpHead(mEdit.getText().toString());
try {
HttpResponse response = httpClient.execute(httphead);
txtresponse.setText(response.toString());
} catch (ClientProtocolException e) {
// writing exception to log
e.printStackTrace();
} catch (IOException e) {
// writing exception to log
e.printStackTrace();
}
}
Never perform long running tasks on the UI Thread (and HTTP Request / Response can take very long due to server latency).
Run the HTTP handling in a background thread.
There are several examples on Stackoverflow - like Make an HTTP request with android and of course read up on Android site - http://developer.android.com/training/articles/perf-anr.html
You are probably doing the request in the UI thread. This is bad practice, as it is in charge of all work done for the UI. You can read more about this here.
A better way would be to do this in another thread. This can be done with e.g.
a custom worker thread or
an AsyncTask.
Example with an AsyncTask (this goes inside your class):
public void MakeRequest(View v)
{
EditText mEdit;
mEdit = (EditText)findViewById(R.id.editText1);
new RequestTask().execute(mEdit.getText().toString());
}
private class RequestTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
HttpClient httpClient = new DefaultHttpClient();
HttpHead httphead = new HttpHead(params[0]);
try {
HttpResponse response = httpClient.execute(httphead);
return response.toString();
} catch (ClientProtocolException e) {
// writing exception to log
e.printStackTrace();
} catch (IOException e) {
// writing exception to log
e.printStackTrace();
}
return "";
}
#Override
protected void onPostExecute(String result) {
TextView txtresponse;
txtresponse = (TextView)findViewById(R.id.textView1);
txtresponse.setText(result);
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}

android code doesn't work when I added threads

I am writing an android application, I previously had a problem NetworkOnMainThreadException and I solved using threads. I now don't get any error and also I don't get any output.
here is my code: there is no errors in the LogCat
public class Currency_convert extends Activity {
public int to;
public int from;
public String [] val;
public String s;
public Handler handler;
public double am=0.0;
StringBuilder build=null ;
HttpClient client=null;
HttpGet httpGet =null;
HttpResponse response=null;
HttpEntity entity=null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.currency);
Spinner s1 = (Spinner) findViewById(R.id.spinner11);
Spinner s2 = (Spinner) findViewById(R.id.spinner22);
final EditText e=(EditText) findViewById(R.id.amountt);
// am=Double.parseDouble(e.getText().toString());
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.name, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.select_dialog_singlechoice);
val = getResources().getStringArray(R.array.value);
s1.setAdapter(adapter);
s2.setAdapter(adapter);
s1.setOnItemSelectedListener(new spinOne(1));
s2.setOnItemSelectedListener(new spinOne(2));
Button b = (Button) findViewById(R.id.button11);
b.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
TextView t = (TextView) findViewById(R.id.textView44);
if(from == to) {
Toast.makeText(getApplicationContext(), "Invalid", 4000).show();
}
else {
try {
s = getJson("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22"+val[from]+val[to]+"%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=");
//s=getJson("http://www.google.com/ig/calculator?hl=en&q=1USD=?INR");
JSONObject jObj;
jObj = new JSONObject(s);
String exResult = jObj.getJSONObject("query").getJSONObject("results").getJSONObject("rate").getString("Rate");
am=Double.parseDouble(e.getText().toString());
double totalR=(Double.parseDouble(exResult))*am;
String r=String.valueOf(totalR);
t.setText(r);
// Log.println(priority, tag, msg)
System.out.println("r =" +r);
Log.i("hello", r);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
}
public String getJson(final String url)throws ClientProtocolException, IOException {
// private String getJson(String url)throws ClientProtocolException, IOException e {
build = new StringBuilder();
client = new DefaultHttpClient();
httpGet = new HttpGet(url);
new Thread(new Runnable() {
public void run() {
try {
response = client.execute(httpGet);
entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String con;
while ((con = reader.readLine()) != null) {
build.append(con);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
// response = client.execute(httpGet);
// entity = response.getEntity();
// InputStream content = entity.getContent();
// BufferedReader reader = new BufferedReader(new InputStreamReader(content));
// String con;
// while ((con = reader.readLine()) != null) {
// build.append(con);
// }
return build.toString();
//return url;
}
private class SpinOne implements OnItemSelectedListener {
int ide;
SpinOne(int i) {
ide =i;
}
public void onItemSelected(AdapterView<?> parent, View view,
int index, long id) {
if(ide == 1) {
from = index;
}
else if(ide == 2) {
to = index;
}
}
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
}}
The way it is written, getJson() will return immediately without giving time for the thread to run completely, so the returned value will not be what you want. Use an AsyncTask so you can run your thread code in the AsyncTask's doInBackground() method and then pass the result to the onPostExecute() method where you can then perform setText() as you intend.
An alternative is to move the JSON parsing and setText() code into the thread's run() method after the HTTP request is made but since running UI-related code (in this case setText()) in a separate thread is not allowed you can use a Handler to schedule setText() to run in the UI thread.
You can read the basics on AsyncTask and Handler here.
When you spawn a thread, code execution splits into different time frames, so even though global scope is shared, you won't get objects populated in a timely fashion for your UI update task if you don't implement some logic to prevent inconsistencies.
Android provides multiple flow control and inter-thread communication patterns built-in that can help you solve such inconsistencies. One such option involves AsyncTask, in your case you can do the following:
Extended AsyncTask with your UI thread-forbidden tasks inside the doInBackground() method;
Get logic that needs to run on UI thread (such as manipulating Views) inside onPostExecute() handler from the same AsyncTask instance. This handler will only be called after doInBackground returns, so the program knows that the logic to populate the object was triggered.
You can look up a sample of AsyncTask in this answear for a practical approach.
Note: If you want to use parent class members such as findViewByID inside an AsyncTask instance, you will need to manually invoke the parent file scope using the <UIThreadName>.this., e.g. <UIThreadName>.this.findViewByID(id). You can do this freely in onPostExecute which has no restrictions due to running on the UI thread, but you are restricted to not performing UI changes in doInBackground (which doesn't run on the UI thread).
I solved it, I just added t.join after the thread declaration :)

Android HTTP GET doesn't work

I know Java but unfortunately chosen Basic4Android for Android Development. After working over an year I realized I should move in native solution. So my question might be silly but I need your advice to solve it.
My goal is to retrieve data from a GET request. I've tried tons of android http client tutorials over internet but failed with each tutorial. I'm just going to share one here so that you can help me to fix. When I'm clicking on the button, nothing is happening without tons of error message in logcat window.
Main Class is here for a quick review:
public class MainActivity extends Activity implements OnClickListener {
private Button Test;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Test = (Button) findViewById(R.id.Test);
Test.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.Test){
try {
HttpClient client = new DefaultHttpClient();
String getURL = "http://www.google.com";
HttpGet get = new HttpGet(getURL);
HttpResponse responseGet = client.execute(get);
HttpEntity resEntityGet = responseGet.getEntity();
if (resEntityGet != null) {
// do something with the response
String response = EntityUtils.toString(resEntityGet);
Log.i("GET RESPONSE", response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
And the whole project is here: https://dl.dropboxusercontent.com/u/15625012/TestHttp.zip
I'll really appreciate any sort of help/advice.
you are currently doing a network access in your main UI thread (Button click function). Android does not allow long operations such as network access in the main thread UI thread of the app. You need to do this asynchronously in a separate thread. You can use built in Async Class for this purpose.
Here is a sample code i wrote
public class Sample extends Activity
{
private ProgressDialog progress_dialog;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
progress_dialog = new ProgressDialog(this);
}
public void MyButtonClick(View view)
{
EditText usernameEditText = (EditText)findViewById(R.id.sample_username);
String username = usernameEditText.getText();
String URL = "http://SOME_WEBSITE?Username=" + username;
progress_dialog.setMessage("Loading. Please wait...");
progress_dialog.setCancelable(false);
progress_dialog.show();
new SampleAsynThread().execute(URL);
}
private class SampleAsynThreadextends AsyncTask <String, Void, String>
{
protected String doInBackground(String... urls)
{
// make your request here
return "Response";
}
protected void onPostExecute(String result)
{
// show response on ui
progress_dialog.dismiss();
}
}
protected void onDestroy()
{
progress_dialog.dismiss();
super.onDestroy();
}
#Override
protected void onPause()
{
progress_dialog.dismiss();
super.onPause();
}
}
First- always post the errors in logcat here, we almost always need them to fix the problem.
But here it's easy- you can't do network IO on the main thread. You need to run it on an AsyncTask or a Thread instead.
try {
URL url = new URL(urlstr);
HttpsURLConnection connection =
(HttpsURLConnection)url.openConnection();
connection.setReadTimeout(6000);
connection.setRequestMethod("GET");
connection.setRequestProperty("User_agent", "android");
OutputStream os = connection.getOutputStream();
//os.write(buffer);
InputStream is = connection.getInputStream();
} catch (MalformedURLException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}catch (Exception e) {
// TODO: handle exception
}

Categories

Resources