I am just getting the first 30 lines, how can I view the new lines being generated in my application, here is my code:
package com.example.showinlog;
public class ShowingLog extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
Process process = Runtime.getRuntime().exec("logcat");
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
StringBuilder log=new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
log.append(line);
log.append("\n");
}
TextView tv = (TextView)findViewById(R.id.textView1);
tv.setText(log.toString());
} catch (IOException e) {
}
}
}
I'm actually not sure how you get anything. The reading shouldn't ever "end", and since you don't do your reading in a different thread, you should never get to the part where you initialize the TextView.
Even if you did get to a point where you can continually log text, it wouldn't work with this code because you'd never be "done" building your StringBuilder.
Try this. You'll need to pass in a LogcatOut as a callback for the log data:
public class LolCat
{
private Process proc;
private LogcatOut logcatOut;
public LolCat(LogcatOut logcatOut)
{
this.logcatOut = logcatOut;
}
private InputStream inStd;
private InputStream inErr;
private LogcatProcessStreamReader streamReader;
private LogcatProcessStreamReader errStreamReader;
public void start()
{
try
{
proc = Runtime.getRuntime().exec("logcat");
OutputStream os = proc.getOutputStream();
this.inStd = proc.getInputStream();
this.inErr = proc.getErrorStream();
startReaders();
os.flush();
}
catch (IOException e)
{
// App.logExecption("Can't logcat", e);
}
catch (Exception e1)
{
// App.logExecption("Can't logcata", e1);
}
}
private void startReaders() throws FileNotFoundException
{
this.streamReader = new LogcatProcessStreamReader(this.inStd, logcatOut);
this.errStreamReader = new LogcatProcessStreamReader(this.inErr, null);
streamReader.start();
errStreamReader.start();
}
public void kill()
{
proc.destroy();
if (this.streamReader != null)
this.streamReader.finish();
if (this.errStreamReader != null)
this.errStreamReader.finish();
}
public abstract class LogcatOut
{
public abstract void writeLogData(byte[] data, int read) throws IOException;
protected void cleanUp()
{
}
}
class LogcatProcessStreamReader extends Thread
{
private InputStream in;
private boolean done = false;
private LogcatOut logcatOut;
public LogcatProcessStreamReader(InputStream in, LogcatOut logcatOut)
{
this.in = in;
this.logcatOut = logcatOut;
}
#Override
public void run()
{
byte[] b = new byte[8 * 1024];
int read;
try
{
while (!done && ((read = in.read(b)) != -1))
{
if(logcatOut != null)
logcatOut.writeLogData(b, read);
}
if(logcatOut != null)
logcatOut.cleanUp();
}
catch (IOException e)
{
// App.logExecption("Can't stream", e);
}
}
public synchronized void finish()
{
done = true;
}
}
}
In your onCreate:
final Handler handler = new Handler();
new LolCat(new LolCat.LogcatOut()
{
#Override
public void writeLogData(final byte[] data, final int read) throws IOException
{
handler.post(new Runnable()
{
public void run()
{
TextView tv = (TextView) asdf;
tv.setText(tv.getText() + "\n" + new String(data, 0, read));
}
});
}
});
A few caveats:
1) I adapted this from other code I have. I HAVE NOT tested it. You may hit a null pointer exception or the like, but the basic code should work.
2) You do need the log permission (forget what that is)
3) I don't remember if the log data comes from std out or err out. I think its std, but if you're getting nothing, swap.
4) I would not recommend concatting text like I did in here in a text view. You'll need to implement a buffer that can be limited, and large string concats are obviously bad in Java. I'll leave that solution to the reader...
I found the AsyncTasks very useful when trying to implement this.
public class LogCatTask extends AsyncTask<Void, String, Void> {
public AtomicBoolean run = new AtomicBoolean(true);
#Override
protected Void doInBackground(Void... params) {
try {
Runtime.getRuntime().exec("logcat -c");
Process process = Runtime.getRuntime().exec("logcat");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder log = new StringBuilder();
String line = "";
while (run.get()) {
line = bufferedReader.readLine();
if (line != null) {
log.append(line);
publishProgress(log.toString());
}
line = null;
Thread.sleep(10);
}
}
catch(Exception ex){
}
return null;
}
}
And to implement the task you do something like
public void setupTextView(){
textView.setMovementMethod(new ScrollingMovementMethod());
logCatTask = new LogCatTask(){
#Override
protected void onProgressUpdate(String... values) {
textView.setText(values[0]);
super.onProgressUpdate(values);
}
};
logCatTask.execute();
}
Related
This is my main activity which gets a json array from a URL. My problem is that when I try and Unit test what should be in the textview it gives me a null pointer exeption.
public class MainActivity extends AppCompatActivity {
TextView txtJson;
ProgressDialog pd;
public static TextView testString;
String jsonString = null;
List<Location> locations;`enter code here`
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtJson = (TextView) findViewById(R.id.tvJsonItem);
testString = (TextView) findViewById(R.id.test_for_string);
new JsonTask().execute("https://wsu-dining-service.s3.amazonaws.com/current-menu.json");
}
protected void postCreate()
{
mapStrinToClass();
testString.setText(locations.get(0).getName());
}
private void mapStrinToClass()
{
ObjectMapper objectMapper = new ObjectMapper();
JsonFactory jsonFactory = objectMapper.getFactory();
try {
JsonParser jsonParser = jsonFactory.createParser(jsonString);
locations = objectMapper.readValue(jsonString,
new TypeReference<List<Location>>() {
});
} catch (IOException e) {
e.printStackTrace();
}
}
private class JsonTask extends AsyncTask<String, String, String> {
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(MainActivity.this);
pd.setMessage("Please wait");
pd.setCancelable(false);
pd.show();
}
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line+"\n");
Log.d("Response: ", "> " + line); //here u ll get whole response...... :-)
}
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (pd.isShowing()){
pd.dismiss();
}
jsonString = result;
postCreate();
}
}
}
My unit test
* When I run the app the textview is populated with "Tim & Jeanne's Dining Commons" but the test fails and says the testString.getText().toString(); is null
#Test
public void isMenuCorrect() {
String menuTxt = MainActivity.testString.getText().toString();
assert(menuTxt == "Tim & Jeanne's Dining Commons");
}
First of all, you should use Espresso to run UI tests, under the androidTest folder. Example:
onView(allOf(withId(R.id.tvJsonItem), withText("Tim & Jeanne's Dining Commons")).check(matches(isDisplayed()));
Basically what we're doing here is checking if a view with id R.id.tvJsonItem and with a text "Tim & Jeanne's Dining Commons" is displayed on the screen. Now how to run Espresso tests is not in this question's scope.
Second, your production code should never know what's going on in the tests, like you have created a TextView just to be used in your unit tests.
Finally, never have static references to your views since you can't guarantee your activity has been created by the time you try to access them. In fact, a view should only be seen by its parent. In your case, the reference TextView should be private in your activity.
I have two classes:
MainActivity.class
ScreenCapture.class
and want getOutputStream(); from a Socket that is located on MainActivity.class.
Then i do:
MainActivity.INSTANCE.clientSocket.getOutputStream();
but is failing in this line ^, i not left logcat here because my logcat not is catching all events correctly, but from this description hope that someone can help.
MainActivity
public class MainActivity extends AppCompatActivity {
public static final MainActivity INSTANCE = new MainActivity();
public Socket clientSocket;
private final int SERVERPORT = 101;
private final String SERVER_IP = "192.168.15.13";
/////////////////////////////////////////////// CLIENTSOCKET //////////////////////////////////////////////////////
class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
clientSocket = new Socket(serverAddr, SERVERPORT);
new Thread(new CommsThread()).start();
} catch (Exception e1) {
System.out.println(e1.toString());
}
}
}
class CommsThread implements Runnable {
#Override
public void run() {
try {
System.out.println("Waiting for server request");
while(clientSocket.isConnected()){
BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())),true);
if (reader.ready()) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
if(line != null && !line.trim().isEmpty()) {
if(line.equalsIgnoreCase("screen")){
// Do something
out.flush();
}
if(line.equalsIgnoreCase("exit")) break;
}
}
}
Thread.sleep(100);
}
System.out.println("Shutting down Socket!!");
clientSocket.close();
} catch (Exception e1) {
System.out.println(e1.toString());
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new ClientThread()).start();
}
ScreenCapture
public class ScreenCaptureClass {
#UiThread
public boolean takeScreenshot(#NonNull Context context) {
//...
imageReader.setOnImageAvailableListener(new OnImageAvailableListener() {
#Override
public void onImageAvailable(final ImageReader reader) {
new AsyncTask<Void, Void, Bitmap>() {
#Override
protected Bitmap doInBackground(final Void... params) {
// ...
OutputStream outs = MainActivity.INSTANCE.clientSocket.getOutputStream(); // <= Error is here
}
}
}
}
}
}
Try to pass the socket's reference to your ScreenCaptureClass, you can try the following things:
You can pass your socket through the ScreenCaptureClass constructor (probably the best way).
Inside your ScreenCaptureClass you can add a static variable like private static OutputStream outputStream and a setter called from your MainActivity :
public static void setOutputStream(OutputStream os) {
outputStream = os;
}
I am new to android and am completely puzzled by AsyncTasks. I need to create a leaderboard which will pull global leaderboard scores from a server.
I have posted below the two methods that were created in the LeaderboardsFragment which are used to access and display the scores - getGlobalScores and readStream.
I am unsure of how to use these in the AsyncTask - mostly how and what parameters to pass to the AsyncTask - most of the tutorials I have been looking at do not deal with 2D arrays. Any hints would be really appreciated, I am really having trouble understanding the literature surrounding this.
package uk.ni.appidemic.whackamole;
import java.io.BufferedReader;
public class LeaderboardsFragment extends Fragment {
AssetStore AS;
private TextView TopScores;
private String[][] global_scores = new String[10][3];
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_leaderboards, container, false);
//Go and get the asset store from the activity
AS = WhackAMoleActivity.getAssetManager();
TopScores = (TextView) rootView.findViewById(R.id.leaderboards);
// Extract and display the top score text view from the preferences
displayLocalScores();
// this method is used to send a highscore to the server (name and score)
// this method may get pulled out to the gameloop as its the only place it should be used in the final game
// but this can be used for testing purposes atm (Server needs to be on)
// sendScoreGlobal("porter", 1001);
//async Get global scores from the server and display them - new thread
new AsyncOperation().execute();
...................
public void getGlobalScores() {
//gets global score in HTML format to be parsed
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
try {
URL url = new URL("http://62........./high_scores");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
readStream(con.getInputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
/gets the data and stores the global scores in a 2d array
//it then displays to screen
public void readStream(InputStream in) {
BufferedReader reader = null;
try {
StringBuilder htmlIn = new StringBuilder();
StringBuilder globalScoreBuilder = new StringBuilder();
htmlIn.append("");
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
htmlIn.append(line);
}
// String to be scanned to find the pattern.
String html = htmlIn.toString();
String regexPattern = "<td align=\"left\" style=\"padding-left:10px;\">(\\d+?)</td>|<td align=\"right\" style=\"padding-right:10px;\">(\\w+?)</td>";
// Create a Pattern object
Pattern patternObject = Pattern.compile(regexPattern);
// Now create matcher object.
Matcher matcherObject = patternObject.matcher(html);
Log.d(getActivity().getResources().getString(R.string.LOG_TAG), "Trying to find regex matches");
TopScores.append("\n");
int nextFreePointer = 0;
int rowCount = 0;
while (matcherObject.find()) {
if (matcherObject.group(1) != null) {
Log.d(getActivity().getResources().getString(R.string.LOG_TAG), "Regex match : " + matcherObject.group(1));
globalScoreBuilder.append(matcherObject.group(1) + " ");
global_scores[rowCount][nextFreePointer] = matcherObject.group(1);
nextFreePointer++;
}
if (matcherObject.group(2) != null) {
Log.d(getActivity().getResources().getString(R.string.LOG_TAG), "Regex match : " + matcherObject.group(2));
globalScoreBuilder.append(matcherObject.group(2) + " ");
global_scores[rowCount][nextFreePointer] = matcherObject.group(2);
nextFreePointer++;
}
if (nextFreePointer > 2) {
nextFreePointer = 0;
rowCount++;
}
globalScoreBuilder.append("\n");
}
StringBuilder sb = new StringBuilder();
String lineSeparator = System.getProperty("line.separator");
for (String[] row : global_scores) {
sb.append(Arrays.toString(row)).append(lineSeparator);
}
String text = sb.toString();
TopScores.append("Global Top 10 Scores\n");
TopScores.append(text);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class AsyncOperation extends AsyncTask<String, Void, Void>{
protected void onPreExecute(){
}//end of onPreExecute
#Override
protected Void doInBackground(Void... values) {
}//doinBackground
protected void onProgressUpdate(Void... values){
}//onProgressUpdate
protected void onPostExecute(Void... result){
}//end of onPostExecute
}//end of AsyncOperation inner class
}//end of Leaderboards class
You should fetch your game score through a WebService class that extentds AsynTask. Below is my class that I am using in order to fetch remote data safely.
CODE:
public class WebServiceRestTask extends AsyncTask<HttpUriRequest, Void, Object> {
private static final String TAG = "WebServiceRestTask";
private AbstractHttpClient mClient;
private WeakReference<WebServiceRestCallback> mCallback;
private int ws_task;
public WebServiceRestTask(int ws_task) {
this(new DefaultHttpClient(), ws_task);
}
public WebServiceRestTask(AbstractHttpClient client, int task_number) {
mClient = client;
this.ws_task = task_number;
}
public interface WebServiceRestCallback {
public void onRequestSuccess(String response);
public void onRequestError(Exception error);
}
public void setResponseCallback(WebServiceRestCallback callback) {
mCallback = new WeakReference<WebServiceRestCallback>(callback);
}
#Override
protected Object doInBackground(HttpUriRequest... params) {
try {
HttpUriRequest request = params[0];
HttpResponse serverResponse = mClient.execute(request);
BasicResponseHandler handler = new BasicResponseHandler();
String response = handler.handleResponse(serverResponse);
return response + ws_task;
} catch (Exception e) {
Log.w(TAG, e);
return e;
}
}
#Override
protected void onPostExecute(Object result) {
if (mCallback != null && mCallback.get() != null) {
if (result instanceof String) {
mCallback.get().onRequestSuccess((String) result);
} else if (result instanceof Exception) {
mCallback.get().onRequestError((Exception) result);
} else {
mCallback.get().onRequestError(
new IOException("Unknown Error Contacting Host"));
}
}
}
}
Not at my workstation but think something like this should work.
public class AsyncOperation extends AsyncTask<String, Void, Void>{
private String[][] global_scores = new String[10][3];
protected void onPreExecute(){
// optionally show loading indicator
TopScores.append("\n");
}//end of onPreExecute
#Override
protected Void doInBackground(Void... values) {
try {
URL url = new URL("http://62........./high_scores");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
readStream(con.getInputStream());
} catch (Exception e) {
e.printStackTrace();
}
}//doinBackground
protected void onProgressUpdate(Void... values){
}//onProgressUpdate
protected void onPostExecute(Void... result){
// optionally hide loading indicator
StringBuilder sb = new StringBuilder();
String lineSeparator = System.getProperty("line.separator");
for (String[] row : global_scores) {
sb.append(Arrays.toString(row)).append(lineSeparator);
}
String text = sb.toString();
TopScores.append("Global Top 10 Scores\n");
TopScores.append(text);
}//end of onPostExecute
private void readStream(InputStream in) {
BufferedReader reader = null;
try {
StringBuilder htmlIn = new StringBuilder();
StringBuilder globalScoreBuilder = new StringBuilder();
htmlIn.append("");
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
htmlIn.append(line);
}
// String to be scanned to find the pattern.
String html = htmlIn.toString();
String regexPattern = "<td align=\"left\" style=\"padding-left:10px;\">(\\d+?)</td>|<td align=\"right\" style=\"padding-right:10px;\">(\\w+?)</td>";
// Create a Pattern object
Pattern patternObject = Pattern.compile(regexPattern);
// Now create matcher object.
Matcher matcherObject = patternObject.matcher(html);
Log.d(getActivity().getResources().getString(R.string.LOG_TAG), "Trying to find regex matches");
int nextFreePointer = 0;
int rowCount = 0;
while (matcherObject.find()) {
if (matcherObject.group(1) != null) {
Log.d(getActivity().getResources().getString(R.string.LOG_TAG), "Regex match : " + matcherObject.group(1));
globalScoreBuilder.append(matcherObject.group(1) + " ");
global_scores[rowCount][nextFreePointer] = matcherObject.group(1);
nextFreePointer++;
}
if (matcherObject.group(2) != null) {
Log.d(getActivity().getResources().getString(R.string.LOG_TAG), "Regex match : " + matcherObject.group(2));
globalScoreBuilder.append(matcherObject.group(2) + " ");
global_scores[rowCount][nextFreePointer] = matcherObject.group(2);
nextFreePointer++;
}
if (nextFreePointer > 2) {
nextFreePointer = 0;
rowCount++;
}
globalScoreBuilder.append("\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}//end of AsyncOperation inner class
Code first:
public class MyActivity extends Activity {
Button send;
TextView textv;
String answer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
send = (Button)findViewById(R.id.sendButton);
textv = (TextView)findViewById(R.id.textViewv);
send.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
MyClientTask myClientTask = new MyClientTask("localhost", 1234, "QUESTION");
myClientTask.execute();
}
});
}
void processAnswer() {
Log.i("DEBUG", "in processAnswer - before setting text");
Log.i("DEBUG", "ANSWER");
textv.setText("ANSWER\n"); // <-------- H E R E -----------
Log.i("DEBUG", "in processAnswer - after setting text");
}
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String message;
String response;
MyClientTask(String addr, int port, String msg){
dstAddress = addr;
dstPort = port;
message = msg;
response = "";
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
InetAddress serverAddr = InetAddress.getByName(dstAddress);
socket = new Socket(serverAddr, dstPort);
OutputStream out = socket.getOutputStream();
out.write(message.getBytes());
out.flush();
String msgrc = "";
int charsRead = 0;
char[] inputBuf = new char[4096];
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader in = new BufferedReader(isr);
while ((charsRead = in.read(inputBuf)) != -1) {
msgrc += new String(inputBuf).substring(0, charsRead);
}
// outer class variable
MyActivity.this.answer = msgrc;
out.close();
is.close();
socket.close();
Log.i("DEBUG", "before processing answer");
MyActivity.this.processAnswer();
Log.i("DEBUG", "after processing answer");
} catch (Exception e) {
}
return null;
}
}
}
The code above simply sends some message to a server and receives an answer. This answer should then be displayed in the TextView (see marked line). However, the app hangs at that line, i.e, LogCat displays
[...]
before processing answer
in processAnswer - before setting text
ANSWER
Then no more lines are written to LogCat. Has anybody an explanation for that? If the marked line is commented out, LogCat looks like
[...]
before processing answer
in processAnswer - before setting text
ANSWER
in processAnswer - after setting text
after processing answer
If you move your call to MyActivity.this.processAnswer() to onPostExecute() instead, perhaps that might work - IIRC, items on the UI thread should only be updated from the UI thread.
First inialize your text view by following , then add onPostExecute method bellow the doInBackground
method . And set your text there . Bellow is code which i change.
public class MyActivity extends Activity {
Button send;
TextView textv;
String answer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
send = (Button)findViewById(R.id.sendButton);
textv = (TextView)findViewById(R.id.textview);
send.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
MyClientTask myClientTask = new MyClientTask("localhost", 1234, "QUESTION");
myClientTask.execute();
}
});
}
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String message;
String response;
MyClientTask(String addr, int port, String msg){
dstAddress = addr;
dstPort = port;
message = msg;
response = "";
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
InetAddress serverAddr = InetAddress.getByName(dstAddress);
socket = new Socket(serverAddr, dstPort);
OutputStream out = socket.getOutputStream();
out.write(message.getBytes());
out.flush();
String msgrc = "";
int charsRead = 0;
char[] inputBuf = new char[4096];
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader in = new BufferedReader(isr);
while ((charsRead = in.read(inputBuf)) != -1) {
msgrc += new String(inputBuf).substring(0, charsRead);
}
// outer class variable
MyActivity.this.answer = msgrc;
out.close();
is.close();
socket.close();
Log.i("DEBUG", "before processing answer");
MyActivity.this.processAnswer();
Log.i("DEBUG", "after processing answer");
} catch (Exception e) {
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
textv.setText(msgrc);
}
}
}
I want to get matching line, which start with "a" and end for example "140807" in dir.txt read this line and set reading data to my TextView (like this: a152z140807). I don't know why, but my code set blank text in TextView.
Even if i change
data = inputLine;
to:
data = "something";
the text in TextView is setting to blank. Thanks in advance.
TextView poleTextowe;
public void mButton (View view){
URLConnection nbpUrl;
String data = null;
try {
nbpUrl = new URL("http://www.nbp.pl/Kursy/xml/dir.txt").openConnection();
InputStream is = nbpUrl.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = reader.readLine()) != null) {
if (inputLine.startsWith("a") && inputLine.endsWith("140807")) {
data = inputLine;
}
}
is.close();
}catch(Exception e){
e.printStackTrace();
}
poleTextowe = (TextView)findViewById(R.id.pole1);
poleTextowe.setText(data);
}
The xml file below:
<TextView
android:text="#string/hello_world"
android:id="#+id/pole1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="#+id/tekst"
android:onClick="mButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/pole1"
android:text="Click"/>
You probably have this exception :
android.os.NetworkOnMainThreadException
Android doesn't allow you to do networking on the main (ui) thread.
Create an async task for example to do networking tasks.
That's easy, your code throws an exception, to be specific, a android.os.NetworkOnMainThreadException. Which means data stays null, and nothing shows. Run it in an AsyncTask or a Thread
Here's an extremely common example. Make this an inner class in your Activity
public class MainActivity extends Activity {
public void onCreate(Bundle b) {
//usual stuff
}
public void doStuff() {
new LongOperation().execute(); //run asynctask
}
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
InputStream is = null;
try {
Log.d(TAG, "starting connection");
URLConnection nbpUrl = new URL("http://www.nbp.pl/Kursy/xml/dir.txt").openConnection();
is = nbpUrl.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = reader.readLine()) != null) {
if (inputLine.startsWith("a") && inputLine.endsWith("140807")) {
return inputLine; //because if the line's found, no need to look for other lines
}
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (is != null)
is.close(); //close inputstream in finally block, so it always gets closed
}
Log.d(TAG, "asynctask ran");
return "NOT FOUND";
}
#Override
protected void onPostExecute(String data) {
poleTextowe = (TextView) findViewById(R.id.pole1);
poleTextowe.setText(data);
}
#Override
protected void onPreExecute() { }
#Override
protected void onProgressUpdate(Void... values) { }
}
}