Im building a graduation project for my collage about "Smart Homes, Home Automation System" implemented with Arduion on a mock-up structure.
To have the full image, the Arduaio takes the pin number via a get request to switch on or of a specific home device.
its all cool when i send the HTTP request from any browser, but when i use the
openConnection();
method, it's like something never happens, but when i use it to get some data about the home rooms and its devices it's working greatly.
i already gave the app the permission to access the internet.
the code from a simple project i made just to solve this praticualy problem:
MainActivity.java
package com.bitsandbytes.xemma_pc.newprototype;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new SendRequest().execute();
}
});
}
private static class SendRequest extends AsyncTask <Void,Void,Void>{
#Override
protected Void doInBackground(Void... params) {
HttpURLConnection httpURLConnection = null ;
URL url ;
try {
url = new URL("http://192.168.1.143/pin=13");
httpURLConnection = (HttpURLConnection) url.openConnection();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
httpURLConnection.disconnect();
}
return null;
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.bitsandbytes.xemma_pc.newprototype.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Press it to Test it"
android:id="#+id/textView"
android:layout_marginTop="154dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pin 13"
android:id="#+id/button"
android:layout_below="#+id/textView"
android:layout_centerHorizontal="true" />
</RelativeLayout>
AndroidManifist.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.bitsandbytes.xemma_pc.newprototype">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
i appreciate the help and the tips in advance.
EDIT: thanks you guys for helping me, but what it really helped me was using the getResponseMessage() method, and it works greatly :D
i didn't have to use .connect method to get some JSON strings before, but it was working.
anyway, thanks for the help!
openConnection just parses the URL and creates the appropriate URLConnection subclass. Network I/O doesn't happen until you send or receive something.
You need to read the data and then network IO will occur.
String response = "";
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// Set Method here
conn.setRequestMethod("POST");
InputStreamReader in = new InputStreamReader(conn.getInputStream());
BufferedReader br = new BufferedReader(in);
String line= "";
while ((line= br.readLine()) != null) {
response += line;
}
conn.disconnect();
URL.openConnection() only returns a URLConnection to the specified resource.
You can open an actual connection to that resource by calling the connect() method of that particular URLConnection.
For example:
HttpURLConnection connection = (HttpURLConnection) someUrl.openConnection();
connection.connect();
Operations that require a connection (like getInputStream() or getOutputStream()) will implicitly call connect(), so explicitly calling it before such operations is not necessary:
HttpURLConnection connection = (HttpURLConnection) someUrl.openConnection();
connection.connect(); // this is redundant
connection.getInputStream(); // getInputStream() will call connect()
Related
I am new to android studio and I tried to get html content of a webpage using AsyncTask class(deprecated API).I have attached my AndroidManifest.xml file. I have added the neccessary permisions to access internet,still i am getting the error "E/Zygote : no v2" and my app crashes. Please explain what does this error mean and how to eliminate the error.I launched the app in a phone with Android 6.0.1
public class MainActivity extends AppCompatActivity {
public static class DownloadTask extends AsyncTask<String,Void,String>{
#Override
protected String doInBackground(String... urls) {
String result ="";
URL url;
HttpsURLConnection urlConnection;
try {
url = new URL(urls[0]);
urlConnection =(HttpsURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while(data!=-1){
char current = (char) data;
result += current;
data = reader.read();
}
return result;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
But the LogCat came up with this error
[08-11 11:46:36.426 27036-27036/? E/Zygote: no v2
08-11 11:46:36.426 27036-27036/? W/SELinux: Function: selinux_compare_spd_ram, index[1], priority [2], priority version is VE=SEPF_SECMOBILE_6.0.1_0035
08-11 11:46:36.436 27036-27036/? W/SELinux: SELinux: seapp_context_lookup: seinfo=default, level=s0:c512,c768, pkgname=com.example.guessthecelebrity
08-11 11:46:36.436 27036-27036/? I/art: Late-enabling -Xcheck:jni
08-11 11:46:36.827 27036-27036/com.example.guessthecelebrity D/ResourcesManager: For user 0 new overlays fetched Null
08-11 11:46:36.847 27036-27036/com.example.guessthecelebrity W/System: ClassLoader referenced unknown path: /data/app/com.example.guessthecelebrity-2/lib/arm
08-11 11:46:36.907 27036-27036/com.example.guessthecelebrity D/ResourcesManager: For user 0 new overlays fetched Null
08-11 11:46:36.927 27036-27036/com.example.guessthecelebrity W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter androidx.vectordrawable.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.guessthecelebrity">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permissioandroid:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:largeHeap="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
I guess you are not good at using AsyncTask. You are not executing the AsyncTask anywhere. How ever, a better clean approach will be as follows,
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="#+id/url_request"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Input a web page url to get." />
<Button
android:id="#+id/url_request_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Request Page"
android:onClick="downloadSiteData"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/url_response"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</ScrollView>
</LinearLayout>
MainActivity with AsyncTask:
package com.example.downloadsite;
import androidx.appcompat.app.AppCompatActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
EditText urlRequest;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
urlRequest = findViewById(R.id.url_request);
}
public void downloadSiteData(View view) {
String url = urlRequest.getText().toString();
if ( url.equals("")) {
Toast.makeText(MainActivity.this, "URL can't be empty", Toast.LENGTH_SHORT).show();
}
else {
new DownloadTask().execute(url);
}
}
public class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(MainActivity.this, "Downloading site data", Toast.LENGTH_SHORT).show();
}
#Override
protected String doInBackground(String... urls) {
String value = urls[0];
String response = null;
URL url = null;
HttpURLConnection urlConnection = null;
InputStream in = null;
try {
url = new URL(value);
urlConnection = (HttpURLConnection) url.openConnection();
in = new BufferedInputStream(urlConnection.getInputStream());
response = readStream(in);
} catch (Exception e) { e.printStackTrace(); }
finally {
urlConnection.disconnect();
}
return response;
}
private String readStream(InputStream inputStream) {
StringBuilder sb = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String nextLine = "";
String newLine = "";
while ((newLine = reader.readLine()) != null) {
sb.append(nextLine + newLine);
}
} catch (IOException e) { e.printStackTrace(); }
return sb.toString();
}
#Override
protected void onPostExecute(String responseString) {
super.onPostExecute(responseString);
TextView tv = findViewById(R.id.url_response);
tv.setText(responseString);
}
}
}
I am using Android Studio 2.2 and I'm trying to see if a web service is up when pressing a button, but I receive the following error. I'm a beginner so any advice is helpful.
Thank you very much.
This is the code in android studio. I found something on the internet but I'm not sure what every line is doing.
package com.example.roxanapena.myapp6;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.HttpCookie;
import static java.net.Proxy.Type.HTTP;
public class MainActivity extends AppCompatActivity {
public boolean available() throws IOException {
URL url = new URL("https://www.Google.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
System.out.println("OK");
return true;
// otherwise, if any other status code is returned, or no status
// code is returned, do stuff in the else block
} else {
System.out.println("WRONG");
return false;
// Server returned HTTP error code.
}
}
Button button3;
public void buttonClicked(View view) throws IOException {
button3 = (Button) findViewById(R.id.button3);
EditText mytextField = (EditText) findViewById(R.id.mytextField);
Log.i("Ok", String.valueOf(available()));
}
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
This is a part of the error I receive when i am pressing the button in app :
03-01 12:13:08.977 28514-28514/com.example.roxanapena.myapp6 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.roxanapena.myapp6, PID: 28514
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22429)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22429)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
Later Edit: This is my xml file:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/GreenRed"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.roxanapena.myapp6.MainActivity">
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="buttonClicked"
android:text="Button"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="135dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:layout_constraintRight_creator="1"
tools:layout_constraintLeft_creator="1" />
<EditText
android:id="#+id/mytextField"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="142dp"
android:layout_marginTop="143dp"
android:ems="10"
android:hint="Name"
android:inputType="textPersonName"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button3"
tools:layout_constraintTop_creator="1"
tools:layout_constraintRight_creator="1"
tools:layout_constraintBottom_creator="1"
tools:layout_constraintLeft_creator="1" />
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="#mipmap/ic_launcher"
android:layout_marginBottom="43dp"
app:layout_constraintBottom_toTopOf="#+id/button3"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="44dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
tools:layout_constraintTop_creator="1"
tools:layout_constraintRight_creator="1"
tools:layout_constraintBottom_creator="1"
tools:layout_constraintLeft_creator="1" />
</android.support.constraint.ConstraintLayout>
When doing a Network Call in android first check in your application Manifest if Internet Permission is given to your application.
If not first provide permission in your application Manifest file like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.truckit">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity" />
</application>
Then to do a handshaking request with a server use an AsyncTask. Never do Network Calls on main thread because it will block your main thread and application will freeze until your application receives a response from the server. Use a simple AsyncTask like this:
public class HandShakingTask extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
System.out.println(connection.getResponseMessage());
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
System.out.println("OK");
// otherwise, if any other status code is returned, or no status
// code is returned, do stuff in the else block
} else {
System.out.println("WRONG");
// Server returned HTTP error code.
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Then call it in your button click method.
new HandShakingTask().execute("https://www.google.com");
Then it will be fine
Result:
2019-03-02 00:52:55.618 5575-5597/com.truckit I/System.out: OK
Here is a sample how to call via AsyncTask.
This code contains also code to pass data to server in JSON (if needed).
Also take care about a possible redirection to another URL, as described in my code
handShakeResponse = new DownloadAsyncTask().execute(request).get();
DownloadAsyncTask declaration:
private class DownloadAsyncTask extends AsyncTask<JSONObject, Void, String> {
#Override
protected String doInBackground(JSONObject... params) {
JSONObject response = null;
JSONObject request = params[0];
if (request != null) {
URL new_url;
String server_response = null;
HttpURLConnection urlConnection = null;
try {
new_url = new URL(HANDSHAKE_SERVER);
urlConnection = (HttpURLConnection) new_url.openConnection();
urlConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
urlConnection.setRequestMethod("POST");
urlConnection.setInstanceFollowRedirects(true);
urlConnection.setDoOutput(true);
OutputStream os = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "utf-8"));
writer.write(request.toString());
writer.flush();
writer.close();
os.close();
int response_code = urlConnection.getResponseCode();
if(response_code == HttpURLConnection.HTTP_OK) {
server_response = readStream(new BufferedInputStream(urlConnection.getInputStream()));
} else {
Log.e(getClass().getSimpleName(), "response code:" + String.valueOf(response_code));
if (response_code == HttpURLConnection.HTTP_MOVED_PERM || response_code == HttpURLConnection.HTTP_MOVED_TEMP) {
String server = urlConnection.getHeaderField("Location");
if (server == null || server.isEmpty()) {
Log.e(TAG, "Redirect not found!");
} else {
Log.e(TAG, "Redirecting to: " + server);
//You must handle here the redirection
return "redirect"; //this is just a flag for me, do your own handling
}
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return server_response;
}
return null;
}
#Override
protected void onPostExecute(String result) {
}
#Override
protected void onCancelled() {
// Cancel task
}
#Override
protected void onPreExecute() {}
}
Initialise button in onCreate
public class MainActivity extends AppCompatActivity {
public boolean available() throws IOException {
URL url = new URL("http://www.Google.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
System.out.println("OK");
return true;
// otherwise, if any other status code is returned, or no status
// code is returned, do stuff in the else block
} else {
System.out.println("WRONG");
return false;
// Server returned HTTP error code.
}
}
Button button3;
#Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button3 = (Button) findViewById(R.id.button3);
EditText mytextField = (EditText) findViewById(R.id.mytextField);
}
public void buttonClicked(View view) throws IOException{
Log.i("Ok", String.valueOf(available()));
}
}
Either use android:onClick="buttonClicked" in you xml for button
or set OnClicklistener on you button
button3.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
buttonClicked()
}
});
public void buttonClicked() {
Log.i("Ok", String.valueOf(available()));
}
Make network call on background thread
You can use AsynTask check this link for network guide
https://developer.android.com/training/basics/network-ops/connecting
i am working on a network communication project in android, but my app dose not work ! after some debugging, i find out that every network request has a null response from system.
i tried so many ways such as :
1) hard restart my phone
2) adding all network permissions to the manifest file
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
3) using local network ( my phone as a server )
4) letting all applications to connect to the network : setting > networked apps > ...
but ! nothing happened...
this is my similar problem link, but there is no answer in this topic:
can't connect to internet in ONLY in my android app. Each method to connect internet returns null
network is working on my phone because some apps like telegram and chrome are working well !
and there is a funny thing here, when i copy and past this code to the simple java project not android project, it works well !
because i wanted to find out where is the problem, i just copy 3 simple lines of codes to the simple android project, but still nothing happened!
manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.dltests"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
layout file
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
<TextView
android:id="#+id/hello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
</RelativeLayout>
source file
package com.example.dltests;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView mTextView = (TextView) findViewById(R.id.hello);
try
{
URL mUrl = new URL("http://192.168.1.53:8080/some.zip");
HttpURLConnection mHttpURLConnection = (HttpURLConnection) mUrl.openConnection();
mTextView.setText(mHttpURLConnection.getContentLength());
}
catch (Exception e)
{
mTextView.setText("ERROR: " + e.getMessage());
}
}
}
and the result is :
ERROR: null
Android bars you from networking in the UI thread. What you need to do it spawn a separate thread to do the networking for you. Then you need either a receiver or handler to post/update the UI with the data.
1 - Create a new class:
import android.os.Handler;
import android.os.Message;
public class GetData extends Thread
{
// Holds url that data is stored on
private URL url
// Sets the url value
public GetData(URL newUrl)
{
url = newUrl;
}
// Runs when the thread is launched
public void run()
{
// Opens connection
HttpURLConnection con = (HttpURLConnection) url.openConnection();
// Sends back to UI using a Message
Message msg = MainActivity.MainActivityInterface.obtainMessage(MainActivity.getAndUpdate);
msg.obj = con.getContentLength(); // Adds the data
HomeScreen.homeScreenInterface.sendMessage(msg);
}
}
2 - Create handler in activity so UI can be updated as well as launch worker thread
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.os.Handler;
import android.os.Message;
public class MainActivity extends Activity {
// Holds activity instance
public static MainActivity currentInstance;
// Variable that allows us to separate messages for handler
public static final getAndUpdate = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
currentInstance = this;
TextView mTextView = (TextView) findViewById(R.id.hello);
try
{
URL mUrl = new URL("http://192.168.1.53:8080/some.zip");
// Spawns worker thread
GetData gd = new GetData(mUrl);
gd.start();
}
catch (Exception e)
{
mTextView.setText("ERROR: " + e.getMessage());
}
}
// Deals with service responses
public static Handler MainActivityInterface = new Handler()
{
#Override
public void handleMessage(Message msg)
{
switch(msg.what)
{
case getAndUpdate:
currentInstance.mTextView.setText((String) msg.obj); // Gets message object and updates UI
break;
}
}
}
}
I hope this helps. Note that I have not tested it as I am very far away from my coding computer!
I am completely new to android.
I am trying to build a basic app to get an idea on "android applications reading data from a server".
To get an idea about http connection on android i created this app watching a video tutorial, i have two java classes.
HttpExample.java class,
package com.raveen.testingthree;
import android.app.Activity;
import android.os.Bundle;
import android.os.StrictMode;
import android.view.View;
import android.widget.TextView;
public class HttpExample extends Activity {
TextView httpStuff;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.detectAll().penaltyLog().build();
StrictMode.setThreadPolicy(policy);
super.onCreate(savedInstanceState);
httpStuff = (TextView) findViewById(R.id.tvHttp);
GetMethodHttp test = new GetMethodHttp();
String returned;
try {
returned = test.getInternetData();
httpStuff.setText(returned);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
and getmethodhttp.java class,
package com.raveen.testingthree;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
public class GetMethodHttp {
public String getInternetData () throws Exception{
BufferedReader in = null;
String data = null;
try{
HttpClient client = new DefaultHttpClient();
URI website = new URI("http://www.google.com");
HttpGet request = new HttpGet();
request.setURI(website);
HttpResponse responce = client.execute(request);
in = new BufferedReader(new InputStreamReader(responce.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String newLine = System.getProperty("line.separator");
while((line = in.readLine()) != null){
sb.append(line + newLine);
}
in.close();
data = sb.toString();
return data;
} finally {
if (in != null){
try{
in.close();
return data;
} catch (Exception e){
e.printStackTrace();
}
}
}
}
}
this is my AndroidManifest,
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="22" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".HttpExample"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
and my layout xml,
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="#+id/tvHttp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Loading Data"
android:textSize="20dp"
/>
</ScrollView>
</LinearLayout>
now when i run this on emulator or my android phone NOTHING IS DISPLAYED.. Just a blank white layout is visible.. what am i doing wrong here?
(i am using eclipse to program)
First of all you should not change the policy to force network calls on main thread instead use Async task.
If you want to read html contents then use jsoup which allows to parse html.
If you want to read data from webservice then try VOLLEY Library.This will save your time,works more efficiently and traceable.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I've been following a youtube video which explain how to insert data from an android app to mySQL.
It doesn't work for me and I don't know what am I doing wrong. It just breaks as soon as I execute it. Not even loading the textViews and Buttons
This is my MainActivity:
package com.example.insertbbdd;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import android.app.Activity;
import android.os.Bundle;
import android.os.StrictMode;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
EditText eName, eAge, eMail;
Button bSumbit;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
eName = (EditText) findViewById(R.id.editName);
eAge = (EditText) findViewById(R.id.editAge);
eMail = (EditText) findViewById(R.id.editMail);
bSumbit = (Button) findViewById(R.id.submitButton);
bSumbit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
InputStream is = null;
String name = "" + eName.getText().toString();
String age = "" + eAge.getText().toString();
String email = "" + eMail.getText().toString();
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("name", name));
nameValuePairs.add(new BasicNameValuePair("age", age));
nameValuePairs.add(new BasicNameValuePair("email", email));
try{
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://accessibility.es/prueba/script.php");
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
String msg = "Data entered succesfully";
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
catch(ClientProtocolException e){
Log.e("Client Protocol", "Log_tag");
e.printStackTrace();
}
catch(IOException e){
Log.e("Log tag", "IOException");
e.printStackTrace();
}
}
});
}
}
This is my main_activity.xml :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/submitButton"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/editName"
android:layout_alignParentBottom="true"
android:layout_marginBottom="130dp"
android:text="Button" />
<TextView
android:id="#+id/editMail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/submitButton"
android:layout_alignRight="#+id/editName"
android:layout_marginBottom="54dp"
android:layout_marginRight="17dp"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/editAge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/editMail"
android:layout_alignLeft="#+id/editMail"
android:layout_marginBottom="43dp"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/editName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/editAge"
android:layout_alignParentLeft="true"
android:layout_marginBottom="35dp"
android:layout_marginLeft="90dp"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
And this is my AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.insertbbdd"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I'm guessing you are getting the ClassCastException because you are trying to call (EditText) on a TextView.
change this :
TextView eName, eAge, eMail;
eName = (TextView) findViewById(R.id.editName);
eAge = (TextView) findViewById(R.id.editAge);
eMail = (TextView) findViewById(R.id.editMail);
bSumbit = (Button) findViewById(R.id.submitButton);
or change your xml tag from TextView to EditText.
<EditText />
NB: what is pointed by others is also correct. if you click your submit button you will get
android.os.NetworkOnMainThreadException
so you need to use either Handler or AsyncTask
You need to carry out any network operations such as HttpPost (or indeed any other slow operation) in a separate thread from the main UI thread, and then use a callback to update the UI back on the main thread later.
See http://developer.android.com/guide/components/processes-and-threads.html and http://developer.android.com/reference/android/os/AsyncTask.html for the main documentation. There are also numerous guides on the web eg http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html
try this..
try{
new Thread(new Runnable() {
public void run() {
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://accessibility.es/prueba/script.php");
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
String msg = "Data entered succesfully";
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
catch(ClientProtocolException e){
Log.e("Client Protocol", "Log_tag");
e.printStackTrace();
}
catch(IOException e){
Log.e("Log tag", "IOException");
e.printStackTrace();
}
}
}).start();