I use ObjectAnimator and testing app on different devices. On some old slowly phones it animates too bad (no GPU, no memory etc), so I want to automatically switch user to second (lite) version of an app.
So how to detect what ObjectAnimator is slowly?
Is it have some framerate report? I found nothing.
Is Choreographer have same listener? it lists errors in catlog, but I want to get it in code.
01-22 05:55:15.775: INFO/Choreographer(3794): Skipped 33 frames! The application may be doing too much work on its main thread.
Note: I know how to parse catlog via system command, but it seems to me it is not a smart or fast solution.
Note2: I do not need to make things faster. I need to detect slow phone.
Ok, this solution works fine
It can be called from ObjAnimator's loop (listener - onRepeat, for example)
You can count events and make conclusion about speed of device.
p.s. it is not smart enought, but until nobody answered about native framerate report...
boolean getCatLog(){
boolean yes=false;
try {
Process process = Runtime.getRuntime().exec("logcat -d");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String output;
String lastLine = null;
while ((output = reader.readLine()) != null) {
lastLine = output;
}
if(lastLine!=null && lastLine.contains("Choreographer")){
Log.d(TAG,"yes!"); //do not remove!
yes=true;
}
reader.close();
process.waitFor();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return yes;
}
Related
I'm developing an Android application for in-house of a certain company, and it needs to log the working time of employees. Therefore, the work with system time is crucial. My application badly needs to know when the user changes the system time. Big deal, you say, see this: Is there a way to detect when the user has changed the clock time on their device?
The problem is that the user may circumvent that solution by doing Force Stop of the application prior to changing the time. The application then won't receive system notification, which is brilliantly described here: https://stackoverflow.com/a/19856367/1309803
I don't mind checking that upon the next launch of the application, but how can I possibly know if the user has changed the time? I'm aware about SystemClock.elapsedRealtime(). I could figure time shift based on delta of those values provided that the user hasn't reboot the device, but this is what I'm unsure of. My application is subscribed to BOOT_COMPLETED event, but that one won't be received either while the application is in stopped state.
And, to cap it all, employees of that company are supposed to work in condition of having no network access, so I can't rely on Web servers. So is there any other possible approach?
Getting the time from the third-party servers is not reliable most of the times and some of them are paid services.
If you want to get the exact time and check with the phone whether it is correct or not, irrespective of the proper way, you can use the following simple trick to get the actual time.
private class GetActualTime extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
try {
HttpURLConnection urlConnection = null;
StringBuilder result = new StringBuilder();
try {
URL url = new URL(urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int code = urlConnection.getResponseCode();
if (code == 200) {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = bufferedReader.readLine()) != null)
result.append(line);
in.close();
}
else {
return "error on fetching";
}
return result.toString();
} catch (MalformedURLException e) {
return "malformed URL";
} catch (IOException e) {
return "io exception";
} finally {
if (urlConnection != null) {urlConnection.disconnect();
}
}
} catch (Exception e) { return "null"; }
}
#Override
protected void onPostExecute(String time) {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat mdformat = new SimpleDateFormat("h:mm");
String times = mdformat.format(calendar.getTime());
try {
String areatime = time.substring(time.indexOf(String.valueOf(times)), time.indexOf(String.valueOf(times)) + 5).trim();
Toast.makeText(this, "The actual time is " + areatime, Toast.LENGTH_SHORT).show();
}
catch(IndexOutOfBoundsException e){
Toast.makeText(this, "Mobile time is not same as Internet time", Toast.LENGTH_SHORT).show();
}
}
}
}
Call the class in the onCreate();
new GetActualTime().execute("https://www.google.com/search?q=time");
So this is actually getting the time from Google. This works pretty awesomely in my projects. In order to check whether the system time is wrong, you can use this trick. Instead of depending on the time servers, you can trust Google.
As it is more sensitive in checking, even a minute ahead or lag will catch the exception. You can customise the code if you want to handle that.
I tried webview.loadurl("www.blahblah.com/blah.txt") and it crashed after a couple of seconds. What else can I do?
I only want to view these .txt files from the web as fast and as stable as possible.
Also I came across asynctask while researching. What is it and can it help me with this?
Also how can I make them to a string if I want to display these text files as a listview item?
Asynctask is wrapper for a new thread that allow you to perform network tasks such as downloading. If you try to download on the UI thread, you will get a crash.
For the text file, download it to disc first, and then read it into memory and display it
StringBuilder txtString = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String textLine;
while ((textLine = br.readLine()) != null) {
txtString.append(line);
txtString.append('\n');
}
}
catch (IOException e) {
//error stuff
}
I'm wonder if there is any way (on rooted phone) to use onTouch method from background, do some think and then dispatch this touch to foreground application.
Create a process and throw this at it: getevent
Multiple new lines will come in every time the screen is touched. Must have root since it contains sensitive touch position information.
Something like this:
try {
Process process = Runtime.getRuntime().exec("su getevent"); //su to get root access
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = "";
while ((line = bufferedReader.readLine()) != null) {
//A new line came in. So a touch event came in.
}
}
catch (IOException e) {}
Note: I haven't tested it but it should work. Maybe minor tweaks are necessary.
Is there a good way of preventing an activity from launching? I'd like to build either a whitelist or blacklist of applications, then prevent those instances from being started.
One potential solution is to poll the running tasks every so often and shut them down, but this seems like it could eat through a lot of battery.
Sorry, this is not supported with the SDK.
Ok so this doesnt count as a "GOOD WAY", could very well be as draining if not more so on your battery, but in line with your polling method:
you could create a service that monitors the log cat (http://www.helloandroid.com/tutorials/reading-logs-programatically)
need permission in manifest:
<uses-permission android:name="android.permission.READ_LOGS" />
then in your service something like (very crude):
private void readLogAndKill(){
try {
Process process = Runtime.getRuntime().exec("logcat -d");
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
if (line.contains("Starting Activity")){
if(line.contains("com.twitter.android"){
//kill twitter for example
}
}
}
} catch (IOException e) {
}
}
there may be someway to catch the "Starting Activity" events - or filter the log as you read it for just those msgs.
I have a problem with blocking buffer with the following code on my android application:
else if (tcpdumpButton.isChecked())
{
try
{
Process process1 = Runtime.getRuntime().exec("tcpdump");
BufferedReader osRes = new BufferedReader(new InputStreamReader(process1.getInputStream()));
StringBuffer output = new StringBuffer();
String line="";
while ((line = osRes.readLine()) != null)
{
output.append(line);
output.append("\n");
tv.setText(output);
setContentView(tv);
}
}
catch (Exception e)
{
throw e;
}
}
Since the tcpdump process is running continuously and never terminated i am unable to print the buffer contents on the screen.Can anybody tell me what i should do or give an example on how to read the buffer and print it on the screen without waiting for the process to terminate??
Sounds to me like the tcpdump process should be in its own thread.
You should take a look at multithreading in java - this way the main thread can continue running as per normal, and the additional thread can deal with the tcpdump and update the main thread with the status.
http://www.devarticles.com/c/a/Java/Multithreading-in-Java/