I found the answer
Include the following two lines in your “onCreate” method of the Main Activity:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
I created an android app that will read text from a URL and display the text on the screen. It crashes when my input is "http://web.njit.edu/~halper/it114/l2d.txt" but does nothing when my input is "http://web.njit.edu/~halper/it114/l2d.txt". I tried to add android.permission.INTERNET to Manifest.xml and I still get the same result.
FATAL EXCEPTION: main
java.lang.IllegalStateException: Could not execute method of the activity
Caused by: java.lang.reflect.InvocationTargetException
Caused by: android.os.NetworkOnMainThreadException
Thank you very much for your time
public void enter(View v) {
EditText input = (EditText) findViewById(R.id.edit_file);
TextView tv = (TextView) findViewById(R.id.text_main);
try {
URL url = new URL( input.getText().toString() );
Scanner scan = new Scanner( url.openStream() );
while( scan.hasNext() )
tv.append( scan.nextLine() );
}
catch(MalformedURLException e) { e.printStackTrace(); }
catch(IOException e) {e.printStackTrace();}
}
This is working for me:
public String getTextFromTheMagicKingom() throws ClientProtocolException, IOException {
String url = "http://web.njit.edu/~halper/it114/l2d.txt";
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(url);
HttpResponse response = client.execute(request);
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
return result.toString();
}
And please correct the format in your comment. Have a nice day ._./
Caused by: android.os.NetworkOnMainThreadException
Since HoneyComb we've no longer been allowed to make network calls on the UI thread because they're potentially slow and it would be silly to hang the UI while waiting on a server. You need to place your network code in a separate Thread, or use AsyncTask, or a library such as Volley.
If this is just to test things out then you could also turn of StrictMode which is what disallows network access from that thread...
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy); //Disabling StrictMode is not recommended. It is much better to make Asynchronous network calls...
You should have posted the code where you make the network request as well. It seems you're doing exercises for yourself, so I would recommend just using a Thread and using its runOnUiThread() method when you get your response. AsyncTask has much more functionality than you need...
Related
I need to get logcat -v time from a device and save it to a text file in a SD Card. The problem is that my application freezes when I press the button to do it.
I understand that it might happen because logcat -v time keeps getting the log of all actions of the device, nonstop. And I need all this information. But I don't know how to code it correctly. Would anyone could help me, please?
Thanks in advance!
Here is my code:
btn_comeca.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
Process process = Runtime.getRuntime().exec("logcat -v");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder log=new StringBuilder();
String line = "";
while ((line = bufferedReader.readLine()) != null) {
log.append(line);
}
try {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {
//Verifica permissão de gravar/ler
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MODE_ENABLE_WRITE_AHEAD_LOGGING);
}
}
File caminho_arquivo = new File("/sdcard/ARQUIVOFINAL.txt");
caminho_arquivo.createNewFile();
FileOutputStream fileOutputStream = new FileOutputStream(caminho_arquivo);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
TextView tv = (TextView)findViewById(R.id.texttext);
String texto = "";
//tv.setText(log.toString());
texto = log.toString();
//outputStreamWriter.append(tv.getText());
outputStreamWriter.append(texto);
outputStreamWriter.close();
fileOutputStream.close();
Toast.makeText(getBaseContext(), "Text File Saved!", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
catch (IOException e) {}
}
The problem may be: your logic works synchronously. You should never execute work like that in main thread, since it can lead to ANR (Android Not Responding).
There is plenty of ways to fix that, though. Since you are not using frameworks for multithreading (e.g. RxJava, you can read about it, if you are interested), you can use AsyncTask. You can place this in your listener.
EDIT: However, take a look at MVVM or MVP pattern and multithreading frameworks later. These things are widely used in production for executing different kinds of asynchronous tasks.
new AsyncTask<Void, Void, Void>(){
#Override
protected Void doInBackground(Void... params) {
// Place your logic here
return;
}
}.execute();
Normal invocation of logcat won't every exit by itself.
Therefore your code will be forever stuck in your while loop.
As per https://developer.android.com/studio/command-line/logcat
Use the -d "Dump the log to the screen and exits." commandline option.
This is what I use in a similar method to display the logcat output in to a TextView
ProgressDialog is showing only if I am sending text but when I sent images it gave me an error which tells that there are lot of activities running or the app can't handle all of it, the solution is to add StrictMode.ThreadPolicy before invoking those tasks but the problem is ProgressDialog is not showing anymore which is important to tell the user about the ongoing process.
I believe it is StrictMode.ThreadPolicy that causes the ProgressDialog to disappear. I am not using Asynctask that's why I haven't found solution on the Internet yet because most of them are using it. I am also planning to use Asynctask but my boss did not approve it, he's afraid that it will ruin the app.
{
private void upLoadImage(String path){
StrictMode.ThreadPolicy policy = new
StrictMode.ThreadPolicy.Builder().permitAll().penaltyDialog().build();
StrictMode.setThreadPolicy(policy);
uploadMedia(path);}}
{
private void uploadMedia(String path) {
String ImageName = "image_name";
String ImagePath = "image_path";
try {
String charset = "UTF-8";
File uploadFile1 = new File(path);
String requestURL= "http://myurl";
MultipartUtility multipart = new MultipartUtility(requestURL,
charset);
multipart.addFormField(ImageName, "iName");
multipart.addFormField(ImagePath, "iPath");
multipart.addFilePart("uploadedfile", uploadFile1);
List<String> response = multipart.finish();
Log.v("rht", "SERVER REPLIED:");
for (String line : response) {
Log.v("rht", "Line : "+line);
if(line=="true"||line=="Saved"){
progressDialog.dismiss();
}
}
// Toast.makeText(this, ""+response, Toast.LENGTH_SHORT).show();
finish();
} catch (Exception e) {
e.printStackTrace();
}
}
}
if you access Network in UI thread the error is shown.You cannot do the network operations in the main thread.It is better to use a worker thread or ayntask. But if you are willing to accept the consequences, and must do network operations on the main thread, you can override the default behavior:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
I created an android app. I try to get content from a PHP file. I wrote the logic in below getCont() method, but it doesn't work. It always returns null in Android. When I do the same with Java it returns the PHP content. How to solve this, so no exception is thrown.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String dbcont = getCont();
tone = (TextView)findViewById(R.id.textView1);
tone.setText("usean :-)"+dbcont);
}
public String getCont() {
String mit = null;
try {
URL oracle = new URL("http://localhost/grace/conn.php");
BufferedReader in = new BufferedReader(
new InputStreamReader(oracle.openStream()));
StringBuilder sb = new StringBuilder();
String inputLine;
while ((inputLine = in.readLine()) != null) {
sb.append(inputLine);
}
mit = sb.toString();
System.out.println(mit);
}
catch(Exception e){
e.printStackTrace();
}
return mit;
}
You're saying you're not getting an exception? You're opening a URL connection on the UI Thread. This is restricted on android. I'm surprised the app isn't crashing.
http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html
You have to use a separate thread to perform network functions. Read this
http://developer.android.com/reference/android/os/AsyncTask.html
You need to create a class that extends ASyncTask, then in the doInBackground() method, you can open the connection to fetch your PHP file.
You can then return the results which will be passed on to the onPostExecute() method. That will allow you to pass the data from the connection (i.e. the PHP file) back to your UI thread.
Let me know if this helps.
Here is the my post request code. please help me debug this one. thanks. i can run my application but it doesnt give out errors.
public void ibutton4Click()
{
{
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("10.0.0.1/cgi-bin/ForwardPress.cgi");
try {
HttpResponse response = client.execute(post);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = "";
while ((line = rd.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
startActivity(new Intent(this,MainActivity.class));
}
}
}
For more on NetworkOnMainThread error and why is it that way,
1. Responsive UI in design and interaction
2. More on the Adroid class
3. Useful SO link
To fetch the data in a separate thread,
1. Write custom Asynctasks:
AsyncTask Dev Reference
AsyncTask Android example
OR
2. Use something like AsyncHttpClient: http://loopj.com/android-async-http/
where you get onSuccess and onFailure methods to work with the response.
The option 2. is better if you just want to fetch data without doing anything else, and work on it, or save it. For the same, you need to parse the response first.
In my android app, i want to let the user fetch data from a website (by sending an http request). The http-response is then sent to another activtiy which shows the data. (i made this a bit simplier in this example code. In real, the data is parsed into an object and the object is sent).
This all works good with my code. But when the user goes back to the main activity by pressing the back key, and trys another request, the application throws an java.io.FileNotFoundException while getting the input stream from the URLConnection. If the app is closed (by pressing back again) and then reopend, all works well again.
Im pretty sure its a problem with a connection not being closed properly or something like that but i cant find the error in my code.
Any idea whats wrong here?
MainActivity.java
*no interessting code here.
it just calls the static function from MainMethods.java
when a button is pressed*
MainFunctions.java - I want to call the methods from several classes so its in an extra class
class MainFunctions {
public static void search(final Activity, final String searchString) {
new AsyncTast<String, String, String>() {
protected void onPreExecute() {
// im opening a progress dialog for the activity here
}
protected String doInBackground(String... searchString) {
try{
return new HttpUtils().sendRequest(searchString)
} catch (Exception e) {
// print a dialog, stacktrace and stuff
return null;
}
}
protected void onPostExecute(String result) {
if(result != null) {
// dismiss the dialog etc..
Intent i = new Intent("packagename");
i.putExtra("key", result);
activity.startActivity(i);
}
}
}.start(searchString)
}
}
HttpUtils.java
public class HTTPUtils {
public String sendRequest(String data)
throws IOException {
String answer = "";
URL url = new URL("http://myURL.com/" + data);
URLConnection conn = url.openConnection();
conn.setReadTimeout(5000);
BufferedReader in = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
answer += inputLine;
in.close();
return answer;
}
}
The Stacktrace shows that the Exception is thrown while conn.getInputStream() is called.
java.io.FileNotFoundException: http://myURL.com/danijoo
at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java)
at com.elophant.utils.HTTPUtils.sendRequest(HTTPUtils.java:20)
at com.elophant.Elophant.getSummoner(Elophant.java:183)
at com.lolsummoners.datacollector.Collecter.getSummonerInfo(Collecter.java:39)
at com.lolsummoners.utils.MainFunctions$1.doInBackground(MainFunctions.java:106)
at com.lolsummoners.utils.MainFunctions$1.doInBackground(MainFunctions.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java)
at java.util.concurrent.FutureTask.run(FutureTask.java)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java)
at java.lang.Thread.run(Thread.java)
The Methods getSummoner() and getSummonerInfo() are methods to parse objects out of the response string. i let that out to make the problem easier to undearstand.
Thanks!