android.os.NetworkOnMainThreadException - android

I am trying to set a url to my notification's setLargeIcon but while doing this I got the android.os.NetWorkOnMainThreadException error , I saw some posts that mention using AsyncTask, but I do not know how to implement that into my code.
#Override
public void onReceive(final Context context, Intent intent) {
Log.d(TAG, " START");
try {
if (intent == null)
{
Log.d(TAG, "Receiver intent null");
}
else
{
Log.d(TAG,intent.toString());
String action = intent.getAction();
Log.d(TAG, "got action " + action );
String channel = intent.getExtras().getString("com.parse.Channel");
JSONObject json = new JSONObject(intent.getExtras().getString("com.parse.Data"));
Log.d(TAG, "got action " + action + " on channel " + channel + " with:");
Iterator itr = json.keys();
while (itr.hasNext()) {
String key = (String) itr.next();
Log.d(TAG, "..."+key+ "=>" +json.getString(key));
if (key.equals("customdata"))
{
Log.d(TAG,"1.0");
msg=json.getString(key);
Log.d(TAG,msg.toString());
}
Log.d(TAG,"1.1");
if(key.equals("image_url"))
{
msg1=json.getString(key);
Log.d("msg1",msg1.toString());
}
}
Bitmap bitmap = getBitmapFromURL(msg1);
}
} catch (JSONException e) {
Log.d(TAG, "JSONException: " + e.getMessage());
}
}
public Bitmap getBitmapFromURL(String strURL) {
try {
URL url = new URL(strURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}

you can use AsyncTask as:
class LoadBitmaps extends AsyncTask<String, Void, Void> {
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
// do something // show some progress of loading images
}
#Override
protected Void doInBackground(String... str) {
try {
URL url = new URL(str[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void v) {
// do something
}
}

This exception occurred because you getting the data from network in the main thread. Move it to AsyncTask's onBackground or a Thread so the process of getting data will be on background thread. Example (using a Thread) :
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
try {
getBitmapFromURL(url);
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
Take a look here if you are not sure whether to use Thread or AsyncTask :
Asynctask vs Thread in android

Related

How Android Async Task Works with UrlConnection

I am new with the android. I am developing an app that will load content from target url in file. If the url didn't work, it will contact our server to request the correct url. If still fail, then it will ask the url from user input dialog. And it will try to initialize again. I have code like this:
if (initialize(target)!=true) {
JSONObject jsonParam = new JSONObject();
try {
jsonParam.put("sns", getSerial(PREF_NAME));
jsonParam.put("code", pwd);
} catch (JSONException e) {
e.printStackTrace();
}
target = getContent(samURL + "/sam_ip", jsonParam);
if (initialize(target)!=true) {
askIpUserDialog();
}
}
and the initialize() as follow
private boolean initialize(String url) {
Boolean success = false;
if ((!url.trim().startsWith("http://")) && (!url.trim().startsWith("https://"))) {
url = "http://" + url;
}
if (url.endsWith("/")) {
url = url.substring(0,url.length()-1);
}
String sUrl = url + "/android_view";
URL pUrl;
HttpURLConnection urlConn = null;
try {
DataOutputStream printout;
DataInputStream input;
pUrl = new URL (sUrl);
urlConn = (HttpURLConnection) pUrl.openConnection();
urlConn.setDoInput (true);
urlConn.setDoOutput (true);
urlConn.setUseCaches (false);
urlConn.setRequestProperty("Content-Type","application/json");
urlConn.setRequestProperty("Host", "android.schoolportal.gr");
urlConn.connect();
//Create JSONObject here
JSONObject jsonParam = new JSONObject();
jsonParam.put("snc", serialClient);
jsonParam.put("code", pwd);
printout = new DataOutputStream(urlConn.getOutputStream());
String str = jsonParam.toString();
byte[] data = str.getBytes("UTF-8");
printout.write(data);
printout.flush();
printout.close ();
int HttpResult = urlConn.getResponseCode();
if(HttpResult == HttpURLConnection.HTTP_OK){
success = true;
WebView view=(WebView) this.findViewById(R.id.webView);
view.setWebChromeClient(new WebChromeClient());
view.setWebViewClient(new WebViewClient());
view.getSettings().setJavaScriptEnabled(true);
view.loadUrl(sUrl);
}else{
success = false;
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally{
if(urlConn!=null)
urlConn.disconnect();
}
return success;
}
I just know that in android, url connection should run in separate thread. That's why I got the following error:
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork
My question is, how do I use AsyncTask to avoid the error?
I saw there is doInBackground() which I can put the initialize() function there.
I saw also there is onPostExecute() event which I can check the result from the doInBackground(), but I don't understand yet how do I retrieve the return of initialize() which placed inside doInBackground()?
Bonus question, later I'd like to place all this job inside an intentservice. Do I need to stil use the asynctask? Does intentservice itself is an asynctask?
you can try some thing like this and also u can use a different thread
final Handler h = new Handler();
Runnable r = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
final File file = new File(path);
Log.i("path",path);
downloadFile(url[j], file);
h.post(new Runnable(){
#Override
public void run() {
txt.setText(""+jp);
jp++;
}
});
}
}
};
new Thread(r).start();
}
private static void downloadFile(String url, File outputFile) {
try {
URL u = new URL(url);
URLConnection conn = u.openConnection();
int contentLength = conn.getContentLength();
Log.i("len","" + contentLength);
Log.i("url1","Streaming from "+url+ "....");
DataInputStream stream = new DataInputStream(u.openStream());
byte[] buffer = new byte[contentLength];
stream.readFully(buffer);
stream.close();
DataOutputStream fos = new DataOutputStream(new FileOutputStream(outputFile));
fos.write(buffer);
fos.flush();
fos.close();
} catch(FileNotFoundException e) {
Log.v("FileError" , e.toString());
return; // swallow a 404
} catch (IOException e) {
Log.v("FileError" , e.toString());
return; // swallow a 404
}
catch (Exception e) {
Log.v("FileError" , e.toString());
return; // swallow a 404
}
}
and also you cant access ui elements on different thread you have to use handler or run on ui thread.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try{
this.pd = ProgressDialog.show(this, "Loading..", "Please Wait...", true, false);
new AsyncAction().execute();
}catch (Exception e) {
e.printStackTrace();
}
}
private class AsyncAction extends AsyncTask<String, Void, String> {
protected Void doInBackground(String... args) {
//do your stuff here }
}
}
Network traffic (and all other logic which takes some time to process) should always be handled by a background thread and never on the Main thread.
Use an ASyncTask to execute the logic.
private class YourTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
// perform your network logic here
return "YourResult";
}
#Override
protected void onPostExecute(String result) {
// Update your screen with the results.
}
}
Call the ASyncTask in your code:
new YourTask().execute("");

Check if a url exists

I have developed a code to check if a url exists but it is not doing anything, could you please point out my mistake?
public void main(String s[]) {
String URLName = "http://www.google.com/";
Log_in uRLExists = new Log_in();
uRLExists.checkURLExists(URLName);
}
public void checkURLExists(String URLName) {
try {
HttpURLConnection con = (HttpURLConnection) new URL(URLName).openConnection();
HttpURLConnection.setFollowRedirects(false);
con.setRequestMethod("HEAD");
if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
Toast.makeText(getBaseContext(), "URL Exist", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getBaseContext(), "URL not Exists", Toast.LENGTH_SHORT).show();
}
}
catch(UnknownHostException unknownHostException){
}
catch (Exception e) {
e.printStackTrace();
}
}
On the Toasts, assuming this code is within an Activity, change getBaseContext() to getApplicationContext().
You can't do Network on MainThread. You are most likely getting android.os.NetworkOnMainThreadException. You should call checkURLExists() from a worker thread.
You could use AsyncTask class to do a network operation.
public class UrlChecker extends AsyncTask<String, Void, Boolean> {
#Override
protected Boolean doInBackground(String... params) {
String url = params[0];
// Check your URL here
return true;
}
#Override
protected void onPostExecute(Boolean exists) {
// Do something with your result
}
}
You did not call connect method.
After con.setRequestMethod("HEAD");
Add this: con.connect();
BTW, you should put the code in a new thread. Don't run it on the main thread, it will hang the App.
Try this:
new Thread(){
#Override
public void run() {
// TODO Auto-generated method stub
super.run();
try {
URL url = new URL(customURL);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("HEAD");
con.connect();
Log.i(TAG, "con.getResponseCode() IS : " + con.getResponseCode());
if(con.getResponseCode() == HttpURLConnection.HTTP_OK){
Log.i(TAG, "Sucess");
}
} catch (Exception e) {
e.printStackTrace();
Log.i(TAG, "fail");
}
}
}.start();

d How can I use progress bar while fetching data from database?

I'm really bad at googling things I want so I decided to ask here. My question is is it possible to show a progress bar while fetching the data from the database? I'm using the typical code when fetching data(Pass value to php and the php will do the query and pass it again to android)
Edit(I have tried adding proggressdialog but the problem now is the loaded data will appear first before the progress dialog here's my AsyncTask code)
public class getClass extends AsyncTask<String, Void, String> {
public getClass()
{
pDialog = new ProgressDialog(getActivity());
}
URLConnection connection = null;
String command;
Context context;
String ip = new returnIP().getIpAddresss();
String link = "http://" + ip + "/android/getClass.php";//ip address/localhost
public URLConnection getConnection(String link) {
URL url = null;
try//retrieves link from string
{
url = new URL(link);
} catch (MalformedURLException e) {
e.printStackTrace();
}
URLConnection connection = null;
try//opens the url link provided from the "link" variable
{
connection = url.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
connection.setDoOutput(true);
return connection;
}
public String getResult(URLConnection connection, String logs) {
//this is the functions that retrieves what the php file echoes
//everything that php throws, the phone receives
String result = "";
OutputStreamWriter wr = null;
try {
wr = new OutputStreamWriter(connection.getOutputStream());//compiles data to be sent to the receiver
} catch (IOException e) {
e.printStackTrace();
}
try {
wr.write(logs);
} catch (IOException e) {
e.printStackTrace();
}
try {
wr.flush();//clears the cache-esque thingy of the writer
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
StringBuilder sb = new StringBuilder();
String line = null;
//Read server response
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
result = sb.toString();
return result;
}
#Override
protected void onPreExecute() {
pDialog.setMessage("Loading...");
pDialog.show();
}
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
String result = "";
//Toast.makeText(View_Classes.this, "ako n una", Toast.LENGTH_LONG).show();
try {
//first data sent is sent in command
command = (String) arg0[0];//it's in array, because everything you input here is placed in arrays
//Toast.makeText(View_Classes.this, "andtio n me", Toast.LENGTH_LONG).show();
if (command == "getCourses") {
connection = getConnection(link);
String logs = "";
logs = "&command=" + URLEncoder.encode(command, "UTF-8");
logs += "&username=" + URLEncoder.encode(username, "UTF-8");
result = getResult(connection, logs);
} else if (command == "getSections") {
connection = getConnection(link);
String logs = "";
logs = "&command=" + URLEncoder.encode(command, "UTF-8");
logs += "&username=" + URLEncoder.encode(username, "UTF-8");
logs += "&course=" + URLEncoder.encode(course, "UTF-8");
result = getResult(connection, logs);
}
return result;
} catch (Exception e) {
return result;
}
}
#Override
protected void onPostExecute(String result) {//this is going to be the next function to be done after the doInBackground function
// TODO Auto-generated method stub
if (pDialog.isShowing()) {
pDialog.dismiss();
}
if (result.equalsIgnoreCase(""))//if there's nothing to return, the text "No records" are going to be thrown
{
} else //Array adapter is needed, to be a place holder of values before passing to spinner
{
}
}
}
Have you tried using an AsyncTask?
You can show your progress bar on the preExecute method and then hide it on postExecute. You can do your querying inside the doInBackground method.
In addition to what #torque203 pointed, I would suggest you to check
http://developer.android.com/reference/android/os/AsyncTask.html#onProgressUpdate(Progress...)
this method was created for that purpose, showing progress to the user.
From developers docs:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
#Override
protected void onPreExecute() {
//show progress bar here
}
protected Long doInBackground(URL... urls) {
//Pass value to PHP here
//get values from your PHP
}
protected void onPostExecute(Long result) {
//Here you are ready with your PHP value. Dismiss progress bar here.
}
}
public void onPreExecute() {
Progress Dialog pDialog = new ProgressDialog(this);
pDialog.setMessage("Loading...");
pDialog.show();
}
public void doInBackground() {
//do your JSON Coding
}
public void onPostExecute() {
Progress Dialog pDialog = new ProgressDialog(this);
pDialog.setMessage("Loading...");
pDialog.show();
}
public URLConnection getConnection(String link) {
URL url = null;
try//retrieves link from string
{
url = new URL(link);
} catch (MalformedURLException e) {
e.printStackTrace();
}
URLConnection connection = null;
try//opens the url link provided from the "link" variable
{
connection = url.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
connection.setDoOutput(true);
return connection;
}
public String getResult(URLConnection connection, String logs) {
//this is the functions that retrieves what the php file echoes
//everything that php throws, the phone receives
String result = "";
OutputStreamWriter wr = null;
try {
wr = new OutputStreamWriter(connection.getOutputStream());//compiles data to be sent to the receiver
} catch (IOException e) {
e.printStackTrace();
}
try {
wr.write(logs);
} catch (IOException e) {
e.printStackTrace();
}
try {
wr.flush();//clears the cache-esque thingy of the writer
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
StringBuilder sb = new StringBuilder();
String line = null;
//Read server response
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
result = sb.toString();
return result;
}
public class getClass extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
pDialog.setMessage("Loading...");
pDialog.show();
URLConnection connection = null;
String command;
Context context;
String ip = new returnIP().getIpAddresss();
String link = "http://" + ip + "/android/getClass.php";//ip address/localhost
}
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
String result = "";
//Toast.makeText(View_Classes.this, "ako n una", Toast.LENGTH_LONG).show();
try {
//first data sent is sent in command
command = (String) arg0[0];//it's in array, because everything you input here is placed in arrays
//Toast.makeText(View_Classes.this, "andtio n me", Toast.LENGTH_LONG).show();
if (command == "getCourses") {
connection = getConnection(link);
String logs = "";
logs = "&command=" + URLEncoder.encode(command, "UTF-8");
logs += "&username=" + URLEncoder.encode(username, "UTF-8");
result = getResult(connection, logs);
} else if (command == "getSections") {
connection = getConnection(link);
String logs = "";
logs = "&command=" + URLEncoder.encode(command, "UTF-8");
logs += "&username=" + URLEncoder.encode(username, "UTF-8");
logs += "&course=" + URLEncoder.encode(course, "UTF-8");
result = getResult(connection, logs);
}
return result;
} catch (Exception e) {
return result;
}
}
#Override
protected void onPostExecute(String result) {//this is going to be the next function to be done after the doInBackground function
// TODO Auto-generated method stub
if (pDialog.isShowing()) {
pDialog.dismiss();
}
if (result.equalsIgnoreCase(""))//if there's nothing to return, the text "No records" are going to be thrown
{
} else //Array adapter is needed, to be a place holder of values before passing to spinner
{
}
}
}

Displaying an image from URL

I'm having some troubles displaying an image I am fetching from a URL into an ImageView. With the code I have at the moment, I am getting absolutely nothing. Is there a problem with this code?
Drawable img = image.LoadImageFromWeb(icon);
imageView.setImageDrawable(img);
public static Drawable LoadImageFromWeb(String iconId) {
try {
String url = "http://ddragon.leagueoflegends.com/cdn/4.3.12/img/profileicon/" + iconId + ".png";
InputStream is = (InputStream) new URL(url).getContent();
Drawable icon = Drawable.createFromStream(is, "src name");
return icon;
} catch (Exception e) {
return null;
}
}
try this function
private void downloadImage()
{
Bitmap bitmap = null;
try {
URL urlImage = new
URL("http://ddragon.leagueoflegends.com/cdn/4.3.12/img/profileicon/" + iconId +
".png");
HttpURLConnection connection = (HttpURLConnection)
urlImage.openConnection();
InputStream inputStream = connection.getInputStream();
//****bitmap is your image*****
bitmap = BitmapFactory.decodeStream(inputStream);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
and use asyncTask to wait until downloading the image like this
private class Asyn_SaveData extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
//get the random string from prefs
if (context != null)
downloadImage();
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
//do what you want after the image downloaded
}
}
Note: AsyncTask must be subClassed, and after the doInBackground finish its job it calls automatically the onPostExecute

bitmap error null pointer exception

Bitmap bitmap = BitmapFactory.decodeStream(result);
HERE IN LOG I AM GETTING
03-05 06:47:36.639: E/bitmap(931): android.graphics.Bitmap#417d5948
BUT THEN EXCEPTION COMES OF NULL POINTER EXCEPTION
public class DetailsActivity extends Activity {
private ImageView image;
//ASYNCTASK
class DownloadImageTask extends AsyncTask<Void, Void, InputStream> {
private ProgressDialog dialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(DetailsActivity.this);
dialog.setTitle("Please wait");
dialog.setMessage("Please wait while the application is downloading the image");
dialog.setCancelable(false);
dialog.show();
}
#Override
protected InputStream doInBackground(Void... params) {
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
url FROM WHERE WE HAVE TO FETCH IMAGE
String stringURL = "http://theopentutorials.com/totwp331/wp-content/uploads/totlogo.png";
try {
Log.e("URL TEST",""+stringURL);
stringURL=stringURL.replaceAll(" ", "%20");
URL url = new URL(stringURL);
Log.e("URL TEST",""+url);
//stringURL=stringURL.replaceAll(" ", "%20");
URLConnection connection = url.openConnection();
InputStream stream = connection.getInputStream();
Log.e("TESTING","TESTING"+ stream);
return stream;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(InputStream result) {
super.onPostExecute(result);
//Bitmap bi = BitmapFactory.
try{Bitmap bitmap = BitmapFactory.decodeStream(result);
Log.e("bitmap",""+bitmap);
ERROR AT THIS LINE==>image.setImageBitmap(bitmap);
//Log.e("final"," " + image.setImageBitmap(bitmap));
}catch(Exception e){
Log.e(" YNull" , ""+ e);//NULL POINTER EXCEPTION
}
dialog.cancel();
}
}
private void asyncDownload() {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectNetwork().build());
DownloadImageTask task = new DownloadImageTask();
task.execute();
}
///////////////////////////////////////////////////////////////////////////////
Async Dowloader
/////////////////////////////////////////////////////////////////////////////
ONCREATE METHORD
IMAGE IS NOT GETTING FETCHED
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
image = (ImageView)findViewById(R.id.imageView2);
ActionBar actionBar = getActionBar();
actionBar.hide();
setContentView(R.layout.activity_details);
asyncDownload();
}
First correct this You should return InputStream stream
return stream;
Instead of
return null;
in doInBackground() in your DownloadImageTask
Don't return the input stream. Download the complete data into a byte array and return it. Then in onPostExecute, use the byte array to decode the image.
#Override
protected byte[] doInBackground(Void... params) {
....
Log.e("URL TEST",""+stringURL);
stringURL=stringURL.replaceAll(" ", "%20");
URL url = new URL(stringURL);
Log.e("URL TEST",""+url);
//stringURL=stringURL.replaceAll(" ", "%20");
URLConnection connection = url.openConnection();
DataInputStream stream = new DataInputStream(connection.getInputStream());
int len = connection.getContentLength();
byte[] data = new byte[len];
stream.readFully(data, 0, len);
Log.e("TESTING","TESTING"+ stream);
return data;
....
}
Then in onPostExecute, use this:
#Override
protected void onPostExecute(byte[] result) {
super.onPostExecute(result);
//Bitmap bi = BitmapFactory.
try{
Bitmap bitmap = BitmapFactory.decodeByteArray(result, 0, result.length);
Log.e("bitmap",""+bitmap);
//Log.e("final"," " + image.setImageBitmap(bitmap));
} catch(Exception e){
Log.e(" YNull" , ""+ e);//NULL POINTER EXCEPTION
}
dialog.cancel();
}

Categories

Resources