Updating CPU frequency on textView (howto?) - android

private String ReadCPUMhz()
{
ProcessBuilder cmd;
String result="";
int resultshow = 0;
try{
String[] args = {"/system/bin/cat", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"};
cmd = new ProcessBuilder(args);
Process process = cmd.start();
InputStream in = process.getInputStream();
byte[] re = new byte[1024];
while(in.read(re) != -1)
{
result = result + new String(re);
}
in.close();
} catch(IOException ex){
ex.printStackTrace();
}
return result;
}
I used setText to write the value from result to a textView.
So it read out the current cpu frequency when app was started and write it to this textView. The app shows f.e. 1200Mhz the whole time the app is opened. It didn't update the value.
How can I use Timer or other methods to update the current value after 1s or 250ms and write it to the textView?
It should display the current CPU frequency. F.e.: 300Mhz - 1200Mhz.. updating after 1s or 250ms..
Please help me :-)
Best regards
Marcus

Try using runOnUiThread for updating Textview from Thread as:
public void myThread(){
Thread th=new Thread(){
#Override
public void run(){
try
{
while(true)
{
Thread.sleep(100L); //SET INTERVAL TO UPDATE TEXTVIEW TEXT
Activity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
String str=ReadCPUMhz(); //CALL YOUR METHOD HERE
tvnn.setText(str); SET TEXT HERE
});
}
}catch (InterruptedException e) {
// TODO: handle exception
}
}
};
th.start();
}
//....YOUR CODE
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myThread();
//YOUR CODE..

Related

Timing threads on Android

I try to build an app, that vibrates with a certain pattern depending on the value of a variable that comes constantly with a stream from a video game.
I managed to display telemetry data on the TextView continiously. What I want is the phone to vibrate for a certain lenght in ms or pattern, depending on the value of gforce in Thread2. What I would like to achieve is, the following sequence. Read the stream, display ias, gforce and vertical on the TextView, check gforce value, if value>=2, vibrate(choose length or pattern by gforce value), pause 500ms, repeat.
I know about the lack of connection security in my code, but that is something for later.
I do have the problem of thread management here, that I cant solve. The stream comes from a Java server socket and has an output of around one line per ms.
This the code I try to make that work with.
public class MainActivity extends AppCompatActivity {
Thread Thread1 = null;
EditText etIP, etPort;
TextView tvMessages;
String SERVER_IP;
int SERVER_PORT;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etIP = findViewById(R.id.etIP);
etPort = findViewById(R.id.etPort);
etIP.setText("192.168.178.61");
etPort.setText("31091");
tvMessages = findViewById(R.id.tvMessages);
Button btnConnect = findViewById(R.id.btnConnect);
btnConnect.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onClick(View v) {
tvMessages.setText("");
SERVER_IP = etIP.getText().toString().trim();
SERVER_PORT = Integer.parseInt(etPort.getText().toString().trim());
Thread1 = new Thread(new Thread1());
Thread1.start();
}
});
}
PrintStream output;
BufferedReader input;
Socket socket;
String message;
class Thread1 implements Runnable {
#Override
public void run() {
try {
socket = new Socket(SERVER_IP, SERVER_PORT);
socket.setTcpNoDelay(true);
output = new PrintStream(socket.getOutputStream(), true);
input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
runOnUiThread(new Runnable() {
#Override
public void run() {
tvMessages.setText("Connected\n");
}
});
new Thread(new Thread2()).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Thread2 implements Runnable {
private double ias;
private double gforce;
private double vertical;
#Override
public void run() {
while (!(socket.isClosed())) {
try {
message = input.readLine();
if (message != null && message.contains("IAS")) {
ias = Double.parseDouble(message.substring(5, (message.indexOf(" ", 5))));
gforce = Double.parseDouble(message.substring(message.indexOf("Gy:") + 4, message.indexOf("Gz:") - 1));
vertical = Double.parseDouble(message.substring(message.indexOf("vertical:") + 10, message.indexOf("Gx:") - 1));
}
if (message != null && !(message.equals("exit"))) {
runOnUiThread(new Runnable() {
#Override
public void run() {
System.out.println(message);
tvMessages.setText("IAS: " + ias + "\n" +
"G: " + gforce + "\n" +
"Vertical: " + vertical + "\n");
}
});
//do trigger Vibration handler and make the phone vibrate in a pattern relative to gforce
new VibrationHandler((int)gforce).start();
//at this point sleep for n ms
} else {
Thread1 = new Thread(new Thread1());
Thread1.start();
return;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class VibrationHandler extends Thread{
int pattern;
public VibrationHandler(int pattern){
this.pattern=pattern;
}
public void run(){
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
// Vibrate for 500 milliseconds
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
v.vibrate(VibrationEffect.createOneShot(pattern*50, VibrationEffect.DEFAULT_AMPLITUDE));
} else {
//deprecated in API 26
v.vibrate(pattern*50);
}
}
}
}
Thank you a lot for your help.

How to load new values of JSON after every 10 seconds

Hi people I am getting problem in getting my latest JSON value after every 10 seconds. I have developed this code and now I am stucked in this. When I run this code it shows the value after second and did not get updated the second time. I have implemented the handler but it is also not working here.
public class MainActivity extends AppCompatActivity {
TextView a,b,c,d,e,f,g,h;
String result = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
a=(TextView) findViewById(R.id.a);
b=(TextView) findViewById(R.id.b);
c=(TextView) findViewById(R.id.c);
DownloadTask task = new DownloadTask();
task.execute("https://api.thingspeak.com/channels/12345/feeds.json?results=1");
}
public class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data != -1) {
char current = (char) data;
result += current;
data = reader.read();
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(final String result) {
super.onPostExecute(result);
new Handler().postDelayed(new Runnable() {
public void run() {
search(result);
}
}, 10000);
}
public void search(String result){
try {
JSONObject jsonObject = new JSONObject(result);
JSONArray weatherInfo = jsonObject.getJSONArray("feeds");
JSONObject legsobject = weatherInfo.getJSONObject(0);
a.setText(legsobject.getString("field1"));
b.setText(legsobject.getString("field2"));
c.setText(legsobject.getString("field3"));
}catch (JSONException e) {
e.printStackTrace();
}
}
}
}
I want to get my value refreshed after every 10 seconds and it is not doing it.
Can any one guide me that how can I make it possible.
Try this code ..
private final int INTERVAL_MILLI = 60000; // define your time..
Handler mHandler;
#Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(SyncData);
}
Runnable SyncData = new Runnable() {
#Override
public void run() {
// call your code here..
Log.e(TAG, "SyncData1: " + new java.sql.Date(System.currentTimeMillis()).toString());
final String Token = AppSetting.getStringSharedPref(mContext, Constants.USER_KEY_TOKEN, "");
if (!TextUtils.isEmpty(Token) && !CommonUtils.isServiceRunning(mContext)) {
Log.e(TAG, "SyncData2: " + new java.sql.Date(System.currentTimeMillis()).toString());
startService(new Intent(mContext, SyncService.class));
}
callSyncData();
}
};
public void callSyncData()
{
mHandler.postDelayed(SyncData, INTERVAL_MILLI);
}
and callSyncData() method called in activity onCreate method and run method.
To begin with, I don't like the idea of hammering the server with a request every 10s even nothing changes really. If you can move to a solution with notification from the server it will be better.
If you still need to do that you can use three common solutions to fire a repeating task with a period:
1- Use Timer & TimerTask
For this solution you need to declare your timer task to run:
final TimerTask repeatedTask = new TimerTask() {
#Override
public void run() {
//you stuff here
}
};
Then you need to schedule your task using a timer like below:
final Timer timer = new Timer();
timer.scheduleAtFixedRate(repeatedTask,0, 10 * 1000);
==> Don't forget to call timer.cancel(); when your are done (or activity pause, stop, ...)
2- Use ScheduledThreadPoolExecutor
This is basically a replacing for Timer task starting android 5.0. The setup is more easy and straightforward like below:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
//you stuff here
}
}, 0, 10, TimeUnit.SECONDS);
==> don't forget to shutdown your executor when you are done by calling : executor.shutdown();
3- Use Handler
The tip here is to repost the runnable after downloading your json like mentionned in the previous answer.
You can use TimerTask and Timer. If you need to update UI components you should run it on UI thread.
final TimerTask yourRepeatedTask = new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
//your code here
}
});
}
};
And the Timer which schedules your task in a given interval. In your case, it is 10s. Make sure to give the interval in milliseconds.
final Timer timer = new Timer();
timer.scheduleAtFixedRate(yourRepeatedTask ,0, 10 * 1000);
At last call timer.cancel() to stop the timer.
#Override
protected void onPause() {
if (timer != null) {
timer.cancel();
}
super.onPause();
}

Get website source code from WebView

I'm trying to get HTML source but it's freezing the app.
I don't know what the problem is and I added Internet Permission
I took this code from a site but it's not working with me. It works until I press the button and then it just freezes.
I hope some one can help me with this, here is the code I'm using:
public class MainActivity extends Activity {
private String HTML = "";
EditText tv;
private ProgressDialog m_ProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button)findViewById(R.id.button1);
tv = (EditText)findViewById(R.id.editText1);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
getHTML("http://m.Facebook.com/");
}
});
}
public void getHTML(String paramString)
{
try
{
BufferedInputStream localBufferedInputStream = new BufferedInputStream(new URL(paramString).openConnection().getInputStream());
ByteArrayBuffer localByteArrayBuffer = new ByteArrayBuffer(50);
while (true)
{
int i = localBufferedInputStream.read();
if (i == -1)
{
HTML = new String(localByteArrayBuffer.toByteArray());
handler.sendEmptyMessage(0);
return;
}
i = (byte)i;
localByteArrayBuffer.append(i);
}
}
catch (Exception localException)
{
while (true)
this.HTML = "Error!";
}
}
private Handler handler = new Handler()
{
public void handleMessage(Message paramMessage)
{
EditText localEditText = (EditText)MainActivity.this.findViewById(R.id.editText1);
MainActivity.this.m_ProgressDialog.dismiss();
localEditText.setText(MainActivity.this.HTML);
}
};
}
What does this have to to with a WebView? You have a NetworkOnMainThreadExeption. You have to put your code in an AsyncTask or Thread to prevent this.
In addition to doing network work on your main thread (a big no-no in Android - use an AsyncTask), your error is probably happening here:
public void getHTML(String paramString) {
try {
BufferedInputStream localBufferedInputStream = new BufferedInputStream(new URL(paramString).openConnection().getInputStream());
ByteArrayBuffer localByteArrayBuffer = new ByteArrayBuffer(50);
while (true) {
int i = localBufferedInputStream.read();
if (i == -1) {
HTML = new String(localByteArrayBuffer.toByteArray());
handler.sendEmptyMessage(0);
return;
}
i = (byte) i;
localByteArrayBuffer.append(i);
}
} catch (Exception localException) {
while (true) // <<< this will create an infinite loop when an error occurs
this.HTML = "Error!";
}
}
Try removing while (true) from your catch statement.

how to link process output to textview and automatically update in realtime?

I'm not the best programmer, actually, I'm pretty bad :(
I need help with something thats driving my crazy. basically I have a tcpdump process, I want to extract the output and put it into a textview which is updated every few milliseconds, I've tried everything and just cant get it to work.
I don't get any errors and it seems to work in the background, but only displays chunks of text only after I go to the homescreen and return back into the app. however, it doesnt constantly update the textview, and sometimes hangs and crashes.
I've created a simple handler which can update the textview with plain text without problems, but then i faced major problems getting it to read the process.
Begin button
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.capture);
this.LiveTraffic = (TextView) findViewById(R.id.LiveTraffic);
this.CaptureText = (TextView) findViewById(R.id.CaptureText);
((TextView) findViewById(R.id.ipv4)).setText(getLocalIpv4Address());
((TextView) findViewById(R.id.ipv6)).setText(getLocalIpv6Address());
//Begin button
final Button startButton = (Button) findViewById(R.id.start);
startButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "Now Capturing Packets", Toast.LENGTH_LONG).show();
try {
process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
os.writeBytes("/data/local/tcpdump -q\n");
os.flush();
os.writeBytes("exit\n");
os.flush();
os.close();
inputStream = new DataInputStream(process.getInputStream());
Thread.sleep(1000);
Process process2 = Runtime.getRuntime().exec("ps tcpdump");
DataInputStream in = new DataInputStream(process2.getInputStream());
String temp = in.readLine();
temp = in.readLine();
temp = temp.replaceAll("^root *([0-9]*).*", "$1");
pid = Integer.parseInt(temp);
Log.e("MyTemp", "" + pid);
process2.destroy();
CaptureActivity.this.thisActivity.CaptureText.setText("Active");
} catch (Exception e) {
}
ListenThread thread = new ListenThread(new BufferedReader(new InputStreamReader(inputStream)));
thread.start();
}
});
}
ListenThread class
public class ListenThread extends Thread {
public ListenThread(BufferedReader reader) {
this.reader = reader;
}
private BufferedReader reader = null;
#Override
public void run() {
reader = new BufferedReader(new InputStreamReader(inputStream));
while (true) {
try {
CaptureActivity.this.thisActivity.CaptureText.setText("exec");
int a = 1;
String received = reader.readLine();
while (a == 1) {
CaptureActivity.this.thisActivity.LiveTraffic.append(received);
CaptureActivity.this.thisActivity.LiveTraffic.append("\n");
received = reader.readLine();
CaptureActivity.this.thisActivity.CaptureText.setText("in loop");
}
CaptureActivity.this.thisActivity.CaptureText.setText("out loop");
} catch (Exception e) {
Log.e("FSE", "", e);
}
}
}
}
I am not an android expert but I notice that:
you are running I/O operations in the UI thread - that will freeze your GUI until the I/O operation finishes ==> run them in a separate thread.
you update the UI from outside the UI thread in ListenThread, which can lead to unexpected results
You can read more about it in this tutorial (make sure you read the 2 examples as the first one is broken (on purpose)).
EDIT
In conclusion you should have something like this in your first piece of code:
startButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "Now Capturing Packets", Toast.LENGTH_LONG).show();
new Thread(new Runnable() {
public void run() {
try {
process = Runtime.getRuntime().exec("su");
...
CaptureActivity.this.runOnUiThread(new Runnable() {
public void run() {
CaptureActivity.this.thisActivity.CaptureText.setText("Active");
}
});
} catch (Exception e) {
}
ListenThread thread = new ListenThread(new BufferedReader(new InputStreamReader(inputStream)));
thread.start();
}
}).start();
}
});
and in the second:
while (true) {
try {
CaptureActivity.this.runOnUiThread(new Runnable() {
public void run() {
CaptureActivity.this.thisActivity.CaptureText.setText("exec");
}
});
int a = 1;
String received = reader.readLine();
while (a == 1) {
CaptureActivity.this.runOnUiThread(new Runnable() {
public void run() {
CaptureActivity.this.thisActivity.LiveTraffic.append(received);
CaptureActivity.this.thisActivity.LiveTraffic.append("\n");
CaptureActivity.this.thisActivity.CaptureText.setText("in loop");
}
});
received = reader.readLine();
}
CaptureActivity.this.runOnUiThread(new Runnable() {
public void run() {
CaptureActivity.this.thisActivity.CaptureText.setText("out loop");
}
});
} catch (Exception e) {
Log.e("FSE", "", e);
}
}
That should solve the specific UI interaction issue. But there are other logic problems in your code which go beyond this question (for example the fact that you never test if you have reached the end of the file you are reading, the fact that while(a==1) is an infinite loop because you never change the value of a etc.).

how can I chnage a TextViews text from a thread?

I'm trying to write code to pull a server every second for updated messages. The messages then get displayed in a text view. If I do not change the text in the text view it runs fine. It will crash if I try to change the textview on the thread. IF i change it not on the thread works fine.
I'm assuming the thread cannot access the main threads memory? How can I set the text in the view with the text just loaded over the internet?
In the code below I have a thread that does a endless loop with a sleep. It calls a method called SendMessage. Send Message loads in text over the internet and at the end tries to update the View with it. It causes a exception when this happens.
code:
public class cChat extends cBase implements OnClickListener {
/** Called when the activity is first created. */
TextView mUsers;
TextView mComments;
int i=0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chat);
mUsers=( TextView) findViewById(R.id.viewusers);;
mComments=( TextView) findViewById(R.id.viewchats);;
Thread thread = new Thread()
{
#Override
public void run() {
try {
int t=0;
while(true)
{
SendMessage();
sleep(1000*5);
t++;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}
public void onClick(View v) {
} // end function
// send a uypdate message to chat server
// return reply in string
void SendMessage()
{
try {
URL url = new URL("http://50.63.66.138:1044/update");
System.out.println("make connection");
URLConnection conn = url.openConnection();
// set timeouts to 5 seconds
conn.setConnectTimeout(1000*5);
conn.setReadTimeout(5*1000);
conn.setDoOutput(true);
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
// String line;
String strUsers=new String("");
String strComments=new String("");
String line=new String();
int state=0;
while ((line= rd.readLine() ) != null) {
switch(state){
case 0:
if ( line.contains("START USER"))
state=1;
if ( line.contains("START COMMENTS"))
state=2;
break;
case 1:
if ( line.contains("END USER"))
state=0;
else
{
strUsers+=line;
strUsers+="\n";
}
break;
case 2:
if ( line.contains("END COMMENTS"))
state=0;
else {
strComments+=line;
strComments+="\n";
}
break;
} // end switch
} // end loop
// the next line will cause a exception
mUsers.setText(strUsers);
mComments.setText(strComments);
} catch (Exception e) {
i++; // use this to see if it goes here in debugger
// System.out.println("exception");
// System.out.println(e.getMessage());
}
} // end methed
}
use runOnUiThread as
YOUR_CURRENT_ACTIVITY.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// the next line will cause a exception
mUsers.setText(strUsers);
mComments.setText(strComments);
//....YOUR UI ELEMENTS
}
});
EDIT :
see doc runOnUiThread
You can use a handler to post tasks (Runnables) to the UI/Main Thread:
private Handler handler = new Handler();
//...
Thread thread = new Thread()
{
#Override
public void run() {
try {
int t=0;
while(true)
{
handler.post(new Runnable() {
#Override
public void run() {
SendMessage();
}
});
sleep(1000*5);
t++;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
You can't touch an UI widget from a thread different than the one used to create it (the UI thread). But if you have a reference to the Activity, you can simply do:
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
mUsers.setText(strUsers);
mComments.setText(strComments);
}
});
which would require strUsers to be accessible by the anonymous class. For that you can simply do:
final String finalUseres = strUsers;
and use finalUsers within run().
Try using a Service to continuously pull/send data to server. This will reduce the load on your UI-Thread.
the Andoid UI toolkit is not thread-safe. So, you
must not manipulate your UI from a worker thread
To fix this problem, Android offers several ways to access the UI thread from other threads. Here is a list of methods that can help:
Activity.runOnUiThread(Runnable)
View.post(Runnable)
View.postDelayed(Runnable, long)
you can also use AsyncTask.
see this tutorial on process and threads in android.

Categories

Resources