Problem with dynamically updating text view - android

I have implemented the logs and they are being displayed on the screen. But even after creating the thread, the logs are not being dynamically updated on the screen. New logs should be appended after one second. While the user stays on the screen, the logs should keep displaying on the screen but it is not happening. The thread that I have created works fine as I have tested it with a count variable. But with logs, it does not seem to work.
Help me out, I am stuck here.
package com.example.logreader;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.text.method.ScrollingMovementMethod;
import android.widget.TextView;
public class MainActivity extends Activity {
private int mInterval = 100; // 5 seconds by default, can be changed later
private Handler mHandler;
int count;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView)findViewById(R.id.textView);
Thread t=new Thread(){
#Override
public void run(){
while(!isInterrupted()){
try {
Thread.sleep(1000); //1000ms = 1 sec
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
Process process = Runtime.getRuntime().exec("logcat -d");
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
StringBuilder log=new StringBuilder();
String line = "";
while ((line = bufferedReader.readLine()) != null) {
log.append(line);
}
tv.setText(log.toString());
tv.setMovementMethod(new ScrollingMovementMethod());
} catch (IOException e) {
}
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t.start();
}
}

Use LiveData and observables it is very powerful and your life becomes easy

Related

Socket For Android Emulator Works but Not For Real Device

I have java code that sends strings via ip to a python script. The code works perfectly with the emulator but when I successfully install the app via usb to my phone it does not work. Here is the code:
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class MainActivity extends AppCompatActivity {
public String message;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button btn_python = findViewById(R.id.python);
final Button btn_movie = findViewById(R.id.movie);
final Button btn_hw = findViewById(R.id.homework);
btn_python.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view1) {
send py = new send();
message = "python";
Log.i("Button", "Button works");
System.out.println("whatever");
py.execute();
}
});
btn_movie.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view2) {
send mov = new send();
message = "movie";
mov.execute();
}
});
btn_hw.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view2) {
send hw = new send();
message = "homework";
hw.execute();
}
});
}
class send extends AsyncTask<Void,Void,Void>{
Socket s;
PrintWriter pw;
#Override
protected Void doInBackground(Void...params) {
System.out.println("whatevernumbertwo");
try {
System.out.println("whatevernumberthree");
s = new Socket("ip address", 7800);
Log.i("Socket", "connects to socket");
pw = new PrintWriter(s.getOutputStream());
Log.i("output stream", "Output stream works");
pw.write(message);
Log.i("write", "Write works");
pw.flush();
Log.i("flush", "Flush works");
pw.close();
s.close();
} catch (UnknownHostException e) {
System.out.println("Fail");
e.printStackTrace();
} catch (IOException e) {
System.out.println("Fail");
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
}
As I mentioned this works on the emulator but not on the actual device. The proper permissions have also been given. What am I doing wrong? Thanks in advance.
After much digging around, it turned out to be the server's firewall all along. That explains why (apparently) no exception was thrown, and why the code didn't seem to execute; it was executing, it was just getting stuck inside Socket() (during the connect).
Surely Socket() is, in fact, throwing an IOException; it probably just takes a while.
The code works on the emulator because, as it is operating on the same machine, it is behind the firewall.

Android open another application from EditText

Can we open other app through this code by executing command given through the Edittext view. If yes then how it can be done?
package com.example.honey.shell;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class MainActivity extends AppCompatActivity {
TextView op;
EditText ip;
Button exec;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
op = (TextView) findViewById(R.id.textView);
ip = (EditText) findViewById(R.id.editText);
exec = (Button) findViewById(R.id.button);
}
public void execute(View view) {
String input = ip.getText().toString();
StringBuffer output = new StringBuffer();
Process p;
try {
p = Runtime.getRuntime().exec(input);
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
} catch (Exception e) {}
op.setText(output.toString());
}
}
Actually i wish to open some other application from my app by executing the command but it's not working,as I tried commands such as cd but it didn't work only the ls command is working in it...
to open an application from another app , you can use Intents
Intent launchNewApp = getPackageManager().getLaunchIntentForPackage("com.example.name");//specify the package name of other application which you intended to launch
if (launchNewApp != null) {
startActivity(launchIntent);//null pointer check in case package name was not found
}

my app could not send a message from my real device to emulator! What is goes wrong? is needed to more settings?

i am new by android.I have started work with a simple chat app. I wrote a short code by UDP socket one for client and one for server.Now i have some issues at connectivity android real device which client app installed on it , and emulator device which server app run on it.
Client app is a simple code which must set IP for connection to emulator and also has a EditText for sending a message.(I at this point set 10.0.2.2 or 10.0.2.15. But my app could not send a message from my real device to emulator! What is goes wrong? is needed to more settings?)
Server app has only a textView for getting and showing recived message.
here is Client code:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class ClienttextchatActivity extends Activity
{
private String udpMsg=null;
Handler hand=new Handler();
EditText edtSetIp=null , edtText=null;
Button btnSetIp=null , btnSend=null;
static String ip=null;
static final String LOG_TAG = "UdpStream";
static final int PORT = 8888;
static final int BUF_SIZE=4096;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
edtText=(EditText)findViewById(R.id.edtText);
edtSetIp=(EditText)findViewById(R.id.edtSetIp);
btnSetIp=(Button)findViewById(R.id.btnSetIp);
btnSend=(Button)findViewById(R.id.btnSend);
btnSetIp.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
ip=edtSetIp.getText().toString();
}
});
btnSend.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Thread mythread=new Thread(new th1() );
mythread.start();
}
});
}
//#############################################
public class th1 implements Runnable
{
public void run()
{
udpMsg =edtText.getText().toString();
Log.d(LOG_TAG,udpMsg);
DatagramSocket ds = null;
try
{
ds = new DatagramSocket();
InetAddress serverAddr = InetAddress.getByName(ip);
Log.d(LOG_TAG,"address server address created.");
DatagramPacket dp;
dp = new DatagramPacket(udpMsg.getBytes(), udpMsg.length(), serverAddr, PORT);
ds.send(dp);
Log.d(LOG_TAG,"packet send.");
}
catch (SocketException e)
{
e.printStackTrace();
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if (ds != null)
{
ds.close();
}
}
}//end run
}//end class th
}
Make sure emulator is started, then in ADB shell, type this command, it will show ip address of emulator.
adb shell
ifconfig etho

Run script with android app

i've got this shell script:
#!system/bin/sh
while :
do
sync
echo 3> /proc/sys/vm/drop_caches
echo "Script is been launched"
sleep 30m
done
exit 0;
i wish run this script with an android app. I have already created a button with only a toast for now. How can i take the script (free.sh) and launch it with the button on the app? Or is there a solution to rewrite the code in java? Thanks
First, you will use Eclipse to create a simple Android helloworld app.
And add a button in your layout. This is very priliminary practise of Android development which you can dig a lot more from http://d.android.com
please try this code in your button's onclick call back function:
Button b = (Button)findViewById(R.id.buttonPower);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Process p=null;
try {
p = new ProcessBuilder()
.command("PathToYourScript")
.start();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(p!=null) p.destroy();
}
}
});
Here is how you can run shell script from your android app
try {
Process process = Runtime.getRuntime().exec("sh /sdcard/test.sh");
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
String listOfFiles = "";
String line;
while ((line = in.readLine()) != null) {
listOfFiles += line;
}
}
catch (IOException e) {
e.printStackTrace();
}
Well, now No errors (THANK YOU!) but do nothing..to try i've written a easy script that write a file.txt. See the code:
package com.mkyong.android;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import java.io.IOException;
import com.example.toast.R;
public class MainActivity extends Activity {
private Button button;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab1);
button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
#SuppressLint("SdCardPath")
#Override
public void onClick(View arg0) {
Process p=null;
try {
p = new ProcessBuilder()
.command("/sdcard/Script/scritturafile.sh")
.start();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(p!=null) p.destroy();
}
}
});
}
}
The are no errors but when i press the button i think the shell doesn't go so don't create the file.txt
I've got errors in my code:
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import com.example.toast.R;
public class MainActivity extends Activity {
private Button button;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab1);
button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Process process = new ProcessBuilder()
.command("PATH")
.redirectErrorStream(true)
.start();
try {
InputStream in = process.getInputStream();
OutputStream out = process.getOutputStream();
readStream(in);// Here: Syntax error, insert "}" to complete `Block`
finally {
process.destroy();
}
}
}
}); //Here: Syntax error on token "}", delete this token
}
protected void readStream(InputStream in) {
// TODO Auto-generated method stub
}
}

Getting force close error in android when using threading

In my application i want to do bluetooth chat. I'm facing a problem in threading. In my application my android phone will work as server which has a blocking statement
socket=mServerSocket.accept();
for this purpose i've created a child thread so that it will run separately. But before finishing this child thread main thread goes down giving Force Close and if i use the .join() method it hangs up my UI.
What is the solution to run both threads parallel?
this is my code
main Activity
package com.my.bluechat_2_1;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class BlueChat extends Activity {
/** Called when the activity is first created. */
private BlueHandler btHandler=null;
private BluetoothAdapter btAdapter = null;
private Context context=this;
TextView chatWindow=null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
chatWindow=(TextView)findViewById(R.id.textView1);
doStart();
}
private void doStart(){
Button btnStart=(Button)findViewById(R.id.button1);
btnStart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// Get local Bluetooth adapter
btAdapter = BluetoothAdapter.getDefaultAdapter();
// If the adapter is null, then Bluetooth is not supported
if(btAdapter == null)
{
Toast.makeText(context, "Device does not support Bluetooth", Toast.LENGTH_LONG).show();
}
if (!btAdapter.isEnabled()) {
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
chatWindow.append("Waiting for connection...\n");
btHandler=new BlueHandler(context,chatWindow,btAdapter);
Thread acceptThread=new Thread(btHandler);
acceptThread.start();
}
});
}
}
BlueHandler
package com.my.bluechat_2_1;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.widget.TextView;
import android.widget.Toast;
public class BlueHandler implements Runnable{
// Name for the SDP record when creating server socket
private static final String SMARTCAM_BT_SERVICE_NAME = "SmartCam";
// Unique UUID for this application
private static final UUID SMARTCAM_BT_SERVICE_UUID = UUID.fromString("95b82690-4c94-11e1-b86c-0800200c9a66");
private BluetoothAdapter btAdapter = null;
private BluetoothServerSocket btServerSocket = null;
private BluetoothSocket btSocket = null;
private InputStream btInputStream=null;
private Context contextObj=null;
private TextView textView;
public BlueHandler(Context contextObj,TextView textView,BluetoothAdapter btAdapter){
this.contextObj=contextObj;
this.btAdapter=btAdapter;
this.textView=textView;
try {
btServerSocket=this.btAdapter.listenUsingRfcommWithServiceRecord(SMARTCAM_BT_SERVICE_NAME, SMARTCAM_BT_SERVICE_UUID);
} catch (IOException e) {
// TODO Auto-generated catch block
Toast.makeText(this.contextObj, "Service not created", Toast.LENGTH_LONG);
}
}
#Override
public void run() {
// TODO Auto-generated method stub
textView.append("Inside child thread.\n");
textView.append(btServerSocket+"\n");
while (true) {
try {
btSocket = btServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (btSocket != null) {
// Do work to manage the connection (in a separate thread)
try {
btServerSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
textView.append("Connected.\n");
try {
btInputStream=btSocket.getInputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] buffer = new byte[1024]; // buffer store for the stream
String s;
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes=btInputStream.read(buffer);
s= new String(buffer);
// Send the obtained bytes to the UI Activity
textView.append("received ::" +s+"\n");
} catch (IOException e) {
break;
}
}
}
}
You're probably getting a crash because you're accessing a textView on the worker thread. You'll need to use TextView.post(Runnable) to make that not happen.
In reality you should be using a bindable Service to do this kind of work. You can post back to the UI via broadcast intents or callback methods, That way you don't have to worry about rotation bugs.
Are you performing a long operation in the constructor of your children thread? Each long operation must be done in the run() method.

Categories

Resources