Activity hangs on TextView.setText() - android

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);
}
}
}

Related

How getOutputStream() of Socket from another class?

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;
}

Updating textView while button execution? - Android

I have a process in a button (large process). I want to update the TextView with diferents values. Like:
Connecting...
Receiving Files...
Complete...
etc..
I'm using setText(); void, but I'm getting only the last value of setText();, in that case:
estatEdit.setText("Tareas completadas!");
Here is my code...
public class sincroGeneral extends Activity implements OnClickListener {
private static final String CATEGORIA = "libro";
private static final String HOST = "192.168.1.165";
private static final int PORT = 9889;
private static final int PORTDATOS = 9888;
int filesize=6022386;
int bytesRead;
int current = 0;
byte [] mybytearray = new byte [filesize];
byte buffer[] = new byte[1024];
byte buffer2[] = new byte[1024];
byte bufferArxiu[] = new byte[2048];
int s;
int s2;
String Benvinguda;
String compra;
EditText estatEdit;
EditText editInflated;
File myfile;
SQLiteDatabase baseDatos;
LinearLayout mainLayout;
View view2;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.sincrolayout);
Button b = (Button) findViewById(R.id.BotoEnviarSincro);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Button b = (Button) findViewById(R.id.BotoEnviarSincro);
estatEdit = (EditText) findViewById(R.id.editSincro);
estatEdit.setText("Enviando peticiĆ³n...");
b.setClickable(false);
b.setFocusable(false);
b.setEnabled(false);
ProcesRebre();
b.setClickable(true);
b.setFocusable(true);
b.setEnabled(true);
}
});
}
private void mostrarMensaje(String mensaje)
{
Toast.makeText(this, mensaje, 500).show();
}
private void ProcesRebre()
{
Socket sockDatos = null;
Socket clientSocket = null;
DataOutputStream sortida;
DataInputStream entrada;
BufferedReader inFromServer;
DataOutputStream sortidaDatos;
DataInputStream entradaDatos;
BufferedReader inFromServerDatos;
try {
estatEdit.setText("Conectando...");
clientSocket = new Socket(HOST, PORT);
sortida = new DataOutputStream(clientSocket.getOutputStream());
entrada = new DataInputStream(clientSocket.getInputStream());
inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
sortida.writeBytes("FAS4-F#S-1-F#S- 1.0.152-F#S-");
Log.i("Enviat","OK");
clientSocket.setSoTimeout(30000);
s = entrada.read(buffer);
String str = new String(buffer, "UTF8");
clientSocket.setSoTimeout(0);
Log.i("Rebut","OK");
if(str.contains("PDA1-F#S-"))
{
sockDatos = new Socket(HOST, PORTDATOS);
estatEdit.setText("Esperando archivo....");
sortidaDatos = new DataOutputStream(sockDatos.getOutputStream());
entradaDatos = new DataInputStream(sockDatos.getInputStream());
inFromServerDatos = new BufferedReader(new InputStreamReader(sockDatos.getInputStream()));
sortidaDatos.writeBytes("FAS4-F#S-1-F#S- 1.0.150-F#S-");
if(sockDatos.isConnected())
{
System.out.println("Conectat amb port 9888");
}
File carpetaSincro = new File(Environment.getExternalStorageDirectory()+"/OrdersCE/Syncro/");
carpetaSincro.mkdirs();
File ArxiuSincro = new File (Environment.getExternalStorageDirectory()+"/OrdersCE/Syncro/sincroorders.zip");
if(ArxiuSincro.exists())
{
ArxiuSincro.delete();
}
File ArxiuSincro2 = new File (Environment.getExternalStorageDirectory()+"/OrdersCE/Syncro/sincroorders.zip");
ArxiuSincro2.createNewFile();
sortida.writeBytes("FAS2-F#S-");
String str2= "";
clientSocket.setSoTimeout(30000);
while(true && (!str2.contains("PDA7-F#S-") && !str2.contains("PDAERR1-F#S-")))
{
s2 = entrada.read(buffer2);
str2 = new String(buffer2, "UTF8");
}
clientSocket.setSoTimeout(0);
String replace1 = str2.replace("PDA7-F#S-", "");
String replace2 = replace1.replace(" ", "");
String tamanyArxiu = replace2.replace("-F#S-ZIP","");
int bufferZip = Integer.parseInt(tamanyArxiu);
boolean in;
s2 = 0;
sockDatos.setSoTimeout(30000);
RandomAccessFile archivo = new RandomAccessFile(Environment.getExternalStorageDirectory()+"/OrdersCE/Syncro/sincroorders.zip", "rw");
long tamArxActual = 0;
while(bufferZip>=tamArxActual)
{
sockDatos.setSoTimeout(10000);
s2 = entradaDatos.read(bufferArxiu);
estatEdit.setText("Recibiendo archivo....");
archivo.write(bufferArxiu);
tamArxActual = archivo.length();
Thread.sleep(2);
}
sockDatos.setSoTimeout(0);
estatEdit.setText("Archivo recibido");
str2 = "";
clientSocket.setSoTimeout(30000);
while(true && (!str2.contains("PDA3-F#S-") && !str2.contains("PDAERR1-F#S-")))
{
s2 = entrada.read(buffer2);
str2 = new String(buffer2, "UTF8");
}
clientSocket.setSoTimeout(0);
if(str2.contains("PDA3-F#S-"))
{
sortida.writeBytes("FAS7-F#S-");
Thread.sleep(2000);
sortida.writeBytes("FAS6-F#S-");
}
sockDatos.close();
clientSocket.close();
String pathZip = Environment.getExternalStorageDirectory()+"/OrdersCE/Syncro/sincroorders.zip";
String directoriExtraccio = Environment.getExternalStorageDirectory()+"/OrdersCE/Syncro/";
String pathTxt = Environment.getExternalStorageDirectory()+"/OrdersCE/Syncro/SincrofitPC.txt";
UnzipUtility unzipper = new UnzipUtility();
try {
unzipper.unzip(pathZip, directoriExtraccio);
} catch (Exception ex) {
System.out.print("No s'ha pogut descomprimir l'arxiu");
ex.printStackTrace();
}
File f = new File(Environment.getExternalStorageDirectory()+"/OrdersCE/Syncro/SincrofitPC.dll");
f.renameTo(new File(Environment.getExternalStorageDirectory()+"/OrdersCE/Syncro/SincrofitPC.txt"));
importarSincro();
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void importarSincro() throws SQLException, IOException
{
int contador = 0;
String LiniaSQL;
FileInputStream fstream = new FileInputStream(Environment.getExternalStorageDirectory()+"/OrdersCE/Syncro/SincrofitPC.txt");
DataInputStream DataInFile = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream(Environment.getExternalStorageDirectory()+"/OrdersCE/Syncro/SincrofitPC.txt"), "Latin-1"));
String FinalSQL = "";
baseDatos = openOrCreateDatabase("BBDD", MODE_WORLD_WRITEABLE, null);
baseDatos.execSQL("BEGIN");
while ((LiniaSQL = br.readLine()) != null) {
if(contador > 0)
{
FinalSQL = LiniaSQL.replace("***** ", "");
if(FinalSQL.contains("DELETE") && !FinalSQL.contains("DELETE FROM"))
{
FinalSQL = FinalSQL.replace("DELETE", "DELETE FROM");
try{
baseDatos.execSQL(FinalSQL);
}catch(SQLiteException e){
}
}
else
{
try{
baseDatos.execSQL(FinalSQL);
}catch(SQLiteException e){
}
}
LiniaSQL = "";
}
contador++;
}
baseDatos.execSQL("COMMIT");
estatEdit.setText("Tareas completadas!");
baseDatos.close();
}
/////////////////////////////////////////
public static String deserializeString(File file)
throws IOException {
int len;
char[] chr = new char[4096];
final StringBuffer buffer = new StringBuffer();
final FileReader reader = new FileReader(file);
try {
while ((len = reader.read(chr)) > 0) {
buffer.append(chr, 0, len);
}
} finally {
reader.close();
}
return buffer.toString();
}
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
}
Thanks in advance!
David.
Internet connection is a blocking action, i.e. it blocks the UI until the action is complete (this is why only the last update is seen). You have to move it to a Thread (or even better to an AsyncTask). But then you get another problem, you cannot update UI from outside the main Thread. So, you have to use a Handler to update the UI.
You are executing a network operation on main thread, point to understand here is Android operates upon single main thread so if you do any time consuming operation on Service/Activity/Content Providers etc, it will block your main thread and hence all the stuff will look like they are blocked/un-responsive infact you will receive an ANR message after few seconds.
to conclude, follow this approach
Move your network extensive code to a separate thread
Implement a Mesasge handling mechanism to update your UI on main thread (Handler/Looper)
to help out things further Android provides you a class AsynTask for this purpose. You can do your operation in doInBackground() and upon condition you can update you UI through onProcessUpdate()
hope this helps.
If you run this process on UI thread it may cause to prompt a dialog saying "Applicaiton
not responding".So I recommend this task must be done either in AsyncTask or Service
U can update your text view in
onPreExecute()
onProgressUpdate()
onPostExecute() functions in AsyncTask.
Eg.for downloading file
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}

Android networking does not work in emulator

I am working on a basic client-server application to send messages between an android app (client) and a java server on the pc. The messages are being sent and received fine when I use the emulator but does not work when i try to use the app on my mobile. I connect my phone to a wifi network hosted by my laptop using connectify. I wonder whats preventing my phone from connecting...
Here is the code :
SERVER
public class ServerMain {
public static void main(String argv[]) throws Exception
{
String clientSentence;
String capitalizedSentence;
int sock = 1234;
ServerSocket welcomeSocket = new ServerSocket(sock);
while(true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
clientSentence = inFromClient.readLine();
System.out.println("Received: " + clientSentence);
if(clientSentence.equalsIgnoreCase("QUIT"))
break;
}
welcomeSocket.close();
}
}
CLIENT
public class Message extends Activity {
EditText et;
String msg1 = "";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et = (EditText)findViewById(R.id.etTest);
}
// TODO Auto-generated method stub
class GetMessages extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
final String msg = et.getText().toString();
try{
Socket clientSocket = new Socket("*myip*", 1234);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
String sentence = msg;
outToServer.writeBytes(sentence + '\n');
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
public void readWebpage(View view) { //The button on click calls this function (from xml)
new GetMessages().execute();
}
}

connecting android emulators using tcp sockets

the following is my code. Editor: Eclipse, Platform: Windows.
Its a chat application where 2 android emulators connect through a tcp socket.
UI consists of a send button, a text view and a text box.
Problem: As soon as I type text and hit send, the application crashes.
server port is 8000.
So my redirection is redir add tcp:8081:8000 and redir add tcp:8082:8000.
I donno what is wrong in my code. Please suggest me somthing I need to change.
public class HelloandroidActivity extends Activity
{
/** Called when the activity is first created. */
public int serverport=8000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final EditText nameField = (EditText) findViewById(R.id.editText1);
final Button button2 = (Button) findViewById(R.id.button1);
Integer severport=8000;
new Server().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,severport);
button2.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
final String name = nameField.getText().toString();
final TextView tv = (TextView) findViewById(R.id.textView1);
//tv.setText(name);
String s=null;
new Client().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,s);
}
});// end onclicklis
}//end oncreate
class Server extends AsyncTask <Integer, String, String>
{
public InetAddress byIpAsName ;
int r=0;
#Override
protected String doInBackground(Integer... serverport) {
//i[0]=serverport;
Integer[] sp=serverport;
BufferedReader in=null;
ServerSocket s=null;
r=sp[0];
String cIn="";
try {
//byIpAsName = InetAddress.getByName("10.2.2.15");
s=new ServerSocket(r);
while(true)
{
Socket client = s.accept();
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String line=in.readLine();
cIn=null;
while(line!=null){cIn=cIn.concat(line);}
}//while
} catch (IOException e) {
e.printStackTrace();
}
try {
s.close();
in.close();
}
catch (IOException e) {
e.printStackTrace();
}
return cIn;
}//end inBackground
//#SuppressWarnings("null")
protected void onPostExecute(String... cIn)
{
}//onpost execute
}//server class
public class Client extends AsyncTask<String, String, String>
{
PrintWriter out = null;
BufferedReader in=null;
String sIn=null;
//Server s1=new Server();
//int q=s1.r;
TelephonyManager tel = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String portStr = tel.getLine1Number().substring(tel.getLine1Number().length() - 4);
int q = Integer.parseInt(portStr);
Socket socket;
#Override
protected String doInBackground(String... params) {
try
{
//q=8080;
InetAddress byIpAsName1=InetAddress.getByName("10.0.2.2");
socket = new Socket(byIpAsName1, q);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line=in.readLine();
sIn=null;
while(line!=null){sIn=sIn.concat(line);}
}
catch (IOException e) {
e.printStackTrace();
}//catch
return sIn;
}//in background
protected void onPostExecute(String... sIn)
{
String c=null;
final TextView tv = (TextView) findViewById(R.id.textView1);
c=c.concat(sIn[0]);
tv.setText(c);
}
}
}//main class
From your logcat, what is important is this line:
03-16 23:12:23.434: E/AndroidRuntime(571): java.lang.SecurityException: Requires READ_PHONE_STATE: Neither user 10040 nor current process has android.permission.READ_PHONE_STATE.
This indicates that in order to run your code, you need the READ_PHONE_STATE permission in the android manifest.xml.
Add this line to the manifest, outside of the <application> tag but inside the <manifest> tag.
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
If this does not solve the issue, the problem could be related to this answer.

How to view continuous logcat in my Application in Emulator

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();
}

Categories

Resources