I need to get logcat -v time from a device and save it to a text file in a SD Card. The problem is that my application freezes when I press the button to do it.
I understand that it might happen because logcat -v time keeps getting the log of all actions of the device, nonstop. And I need all this information. But I don't know how to code it correctly. Would anyone could help me, please?
Thanks in advance!
Here is my code:
btn_comeca.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
Process process = Runtime.getRuntime().exec("logcat -v");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder log=new StringBuilder();
String line = "";
while ((line = bufferedReader.readLine()) != null) {
log.append(line);
}
try {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {
//Verifica permissão de gravar/ler
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MODE_ENABLE_WRITE_AHEAD_LOGGING);
}
}
File caminho_arquivo = new File("/sdcard/ARQUIVOFINAL.txt");
caminho_arquivo.createNewFile();
FileOutputStream fileOutputStream = new FileOutputStream(caminho_arquivo);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
TextView tv = (TextView)findViewById(R.id.texttext);
String texto = "";
//tv.setText(log.toString());
texto = log.toString();
//outputStreamWriter.append(tv.getText());
outputStreamWriter.append(texto);
outputStreamWriter.close();
fileOutputStream.close();
Toast.makeText(getBaseContext(), "Text File Saved!", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
catch (IOException e) {}
}
The problem may be: your logic works synchronously. You should never execute work like that in main thread, since it can lead to ANR (Android Not Responding).
There is plenty of ways to fix that, though. Since you are not using frameworks for multithreading (e.g. RxJava, you can read about it, if you are interested), you can use AsyncTask. You can place this in your listener.
EDIT: However, take a look at MVVM or MVP pattern and multithreading frameworks later. These things are widely used in production for executing different kinds of asynchronous tasks.
new AsyncTask<Void, Void, Void>(){
#Override
protected Void doInBackground(Void... params) {
// Place your logic here
return;
}
}.execute();
Normal invocation of logcat won't every exit by itself.
Therefore your code will be forever stuck in your while loop.
As per https://developer.android.com/studio/command-line/logcat
Use the -d "Dump the log to the screen and exits." commandline option.
This is what I use in a similar method to display the logcat output in to a TextView
Related
So I'm really new in android, and going to make an application which get the device id of a device, store it on database server, and then check it if the device are the same with the one already registered, if yes, then go to main activity, if not then they need to registered again.
My method :
public class SigninActivity extends AsyncTask<String, String, String> {
private Context context;
public SigninActivity(Context context, int flag) {
this.context = context;
}
protected void onPreExecute(String result) {
}
//#Override
protected String doInBackground(String... arg0) {
try {
String dev = (String) arg0[0];
String link = "http://10.20.2.14/service_antrian/get_data.php?device_id=" + dev;
URL url = new URL(link);
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI(link));
HttpResponse response = client.execute(request);
BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
while ((line = in.readLine()) != null) {
sb.append(line);
break;
}
in.close();
Log.d("RETURN", "return");
return sb.toString();
} catch (Exception e) {
Log.d("EXCEPTION", "EXP");
//return "failed";
return new String("Exception: " + e.getMessage());
}
}
// #Override
protected void onPostExecute(String result) {
if (result.equalsIgnoreCase("false")) {
Intent mainIntent = new Intent(UserActivity.this, RegisterActivity.class);
UserActivity.this.startActivity(mainIntent);
} else {
Intent mainIntent = new Intent(UserActivity.this, MainActivity.class);
UserActivity.this.startActivity(mainIntent);
}
}
}
and this is my service in php code:
<?php
ini_set('display_errors', 1);
require_once 'database.php';
if(isset($_GET['device_id'])) {
$device_id = $_GET['device_id'];
$sql = " SELECT * FROM `pasien`.`antrian_mobile` WHERE `device_id`=
'$device_id' ";
$rs = $mysqli->query($sql);
$data = array();
while ($row = $rs->fetch_object()) {
$data[] = $row;
}
if ($mysqli->affected_rows > 0) {
echo "successfull";
} else {
echo "false";
}
echo json_encode($data);
}
?>
but that code only make the app go to the main activity, while there are no records on the database yet. Is it because of my service?
You are returning successfull or failed from your service
if ($mysqli->affected_rows > 0) {
echo "successfull";
} else {
echo "failed";
}
but you are comparing the result with false in your mobile app, hence it always takes the else route and open MainActivity
if (result.equalsIgnoreCase("false")) {
Intent mainIntent = new Intent(UserActivity.this, RegisterActivity.class);
UserActivity.this.startActivity(mainIntent);
} else {
Intent mainIntent = new Intent(UserActivity.this, MainActivity.class);
UserActivity.this.startActivity(mainIntent);
}
I see a few issues in your code:
issue #1
Activity shouldn't extend AsyncTask. AsyncTask should be dedicated to a single asynchronous task (like sending HTTP request) and Activity is representing single user screen (UI layer). You should create AsyncTask separately and call it within an Activity like this:
class SigninActivity extends Activity {
// this method should be called in the place where you want to execute your task
// it could be onResume() method, onClick listener for the button or whatever
private void executeAsyncTask() {
new MyTask().execute(...) // put your params here...
}
private class MyTask extends AsyncTask<String, String, String> {
... // your task code goes here...
}
}
issue #2
Nowadays, using AsyncTask is considered as a bad practice in Android applications, because it has poor error handling and is not aware of the Activity lifecycle. Recommended solution for asynchronous operations on Android is RxJava (version 2).
issue #3
You are using HttpClient. It's recommended to use more mature solutions like Retrofit Http REST client or OkHttp library. They can be easily integrated with RxJava.
issue #4
You're passing Context, but you're not using it
issue #5
You don't have to comment #Override annotations.
issue #6
Your code is messy, hard to debug and read. Once you make it clean, it will be easier to solve problems related to it.
issue #7
In the PHP code, you're mixing responsibilities.
Summary
Make sure you're using the existing code correctly and then try to improve it.
ProgressDialog is showing only if I am sending text but when I sent images it gave me an error which tells that there are lot of activities running or the app can't handle all of it, the solution is to add StrictMode.ThreadPolicy before invoking those tasks but the problem is ProgressDialog is not showing anymore which is important to tell the user about the ongoing process.
I believe it is StrictMode.ThreadPolicy that causes the ProgressDialog to disappear. I am not using Asynctask that's why I haven't found solution on the Internet yet because most of them are using it. I am also planning to use Asynctask but my boss did not approve it, he's afraid that it will ruin the app.
{
private void upLoadImage(String path){
StrictMode.ThreadPolicy policy = new
StrictMode.ThreadPolicy.Builder().permitAll().penaltyDialog().build();
StrictMode.setThreadPolicy(policy);
uploadMedia(path);}}
{
private void uploadMedia(String path) {
String ImageName = "image_name";
String ImagePath = "image_path";
try {
String charset = "UTF-8";
File uploadFile1 = new File(path);
String requestURL= "http://myurl";
MultipartUtility multipart = new MultipartUtility(requestURL,
charset);
multipart.addFormField(ImageName, "iName");
multipart.addFormField(ImagePath, "iPath");
multipart.addFilePart("uploadedfile", uploadFile1);
List<String> response = multipart.finish();
Log.v("rht", "SERVER REPLIED:");
for (String line : response) {
Log.v("rht", "Line : "+line);
if(line=="true"||line=="Saved"){
progressDialog.dismiss();
}
}
// Toast.makeText(this, ""+response, Toast.LENGTH_SHORT).show();
finish();
} catch (Exception e) {
e.printStackTrace();
}
}
}
if you access Network in UI thread the error is shown.You cannot do the network operations in the main thread.It is better to use a worker thread or ayntask. But if you are willing to accept the consequences, and must do network operations on the main thread, you can override the default behavior:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
I created an android app. I try to get content from a PHP file. I wrote the logic in below getCont() method, but it doesn't work. It always returns null in Android. When I do the same with Java it returns the PHP content. How to solve this, so no exception is thrown.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String dbcont = getCont();
tone = (TextView)findViewById(R.id.textView1);
tone.setText("usean :-)"+dbcont);
}
public String getCont() {
String mit = null;
try {
URL oracle = new URL("http://localhost/grace/conn.php");
BufferedReader in = new BufferedReader(
new InputStreamReader(oracle.openStream()));
StringBuilder sb = new StringBuilder();
String inputLine;
while ((inputLine = in.readLine()) != null) {
sb.append(inputLine);
}
mit = sb.toString();
System.out.println(mit);
}
catch(Exception e){
e.printStackTrace();
}
return mit;
}
You're saying you're not getting an exception? You're opening a URL connection on the UI Thread. This is restricted on android. I'm surprised the app isn't crashing.
http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html
You have to use a separate thread to perform network functions. Read this
http://developer.android.com/reference/android/os/AsyncTask.html
You need to create a class that extends ASyncTask, then in the doInBackground() method, you can open the connection to fetch your PHP file.
You can then return the results which will be passed on to the onPostExecute() method. That will allow you to pass the data from the connection (i.e. the PHP file) back to your UI thread.
Let me know if this helps.
I'm having trouble figuring out how to make this work.
I'm developing an app in which I download data from a online txt, parse it and add it to my database. This is taking +-30 seconds, and there is only one part of the updater implemented.
When I try to use a Thread or Asynctask, I have problems when trying to pass the arguments to the void which is updating the Database.
How can I implement it on the good way?
Here is my code:
Main activity class:
public class Androideye_principal extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
//WhazzupUpdate.DownloadWhazzup(AllUsers, TotalConnections);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_androideye_principal);
PilotsSQLiteHelper pdbh = new PilotsSQLiteHelper(this, "PilotsDB", null, 1);
SQLiteDatabase dbPilots = pdbh.getWritableDatabase();
Context context = getApplicationContext();
String TotalConnections = new String();
WhazzupUpdate.DownloadWhazzup(dbPilots, TotalConnections, context);
dbPilots.close();
CharSequence text = "Total Users: " + TotalConnections;
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
[Continues with Buttons stuff and so on...]
Parser class:
public class WhazzupUpdate {
public static void DownloadWhazzup (SQLiteDatabase PilotsDB, String TotalConnections, Context context) {
try {
// Create a URL for the desired page
URL url = new URL("This is my url/whazzup.txt");
// Read all the text returned by the server
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String str;
for (int i = 0; i<=4; i++) {
in.readLine(); } // Go to the number of connections
TotalConnections = in.readLine();
for (int i = 0; i<=3; i++) {
in.readLine(); } // Go to !CLIENTS
PilotsDB.execSQL("DELETE FROM Pilots");
while (((str = in.readLine()) != null) && !(in.readLine().contains("!AIRPORTS"))) {
// str is one line of text; readLine() strips the newline character(s)
String[] dataRow = str.split(":");
if (str.contains("PILOT")) {
ContentValues NewValue = new ContentValues();
NewValue.put("VID", dataRow[1]);
[More NewValue puts...]
PilotsDB.insert("Pilots", null, NewValue);
} //End IF Pilot
} // End While
in.close();
} catch (MalformedURLException e) {
} catch (IOException e) {
}
}}
As you see, I call WhazzupUpdate.DownloadWhazzup Method in the main activity, and this is when all is getting frozen, but don't know how to derivate it to another threat and keep the references to the Data Bases and so on...
Hope anyone can help me. Thanks in advance.
A Thread or AsyncTask would be fine here. I prefer using AsyncTask for most of my heavy-lifting. You can create an AsyncTask and do your work in doInBackground() as it works on a background Thread. Then you can update your UI elements if needed in any of its other methods.
onPostExecute() will run after a result is passed from doInBackground()
onProgressUpdate() will run if you need to update UI during doInBackground() operations by calling publishProgress(). Here you can show a ProgressBar if you need to
and
onPreExecute() will run when you first call your task before doInBackground() runs.
Running the code in a background thread using Thread or AsyncTask will allow your UI to be free while the heavy work is being done.
Example of AsyncTask
Using interface with AsyncTask to post data back yo UI
AsyncTask Docs
I'm trying to learn Java right now and I've jumped in the deep end by starting with the Android Faceobok API. Right now, I'm trying to get some information from my graph data (a friend in this case) and display it in a text view. This seems rather trivial but it has been anything but.
JSONObject json_data = null;
try
{
JSONObject response = Util.parseJson(facebook.request("/me/friends", mBundle, "GET")); // Get a friend information from facebook
JSONArray jArray = response.getJSONArray("data");
json_data = jArray.getJSONObject(0);
String name = json_data.getString("name");
mText.setText(name);
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (JSONException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (FacebookError e)
{
e.printStackTrace();
}
The TextView doesn't change when I do this and I'm not exactly sure where I've gone wrong.
As an aside, there is a shortage of good Android Facebook API tutorials out there. Most are hundreds of lines of code; I don't have the energy or patience to consume all of that.
I have a feeling your initial request isnt working properly. you should try this line instead:
JSONObject response = Util.parseJson(facebook.request("me/friends"));
Firstly I think in your initial request, it should be "me/friends" rather than "/me/friends". Secondly you dont necessarily need the mBundleor "GET" parameters in what you're trying to achieve. Have you even defined parameters in mBundle? You're also getting information from the request method, so the "GET" parameter isn't necessary.
Try the line i just wrote, as it is simpler and will get your friends information. The rest of your code is fine.
Your assertion about being "trivial" is essentially true, but generally speaking "jumping into the deep end" rarely results in anything other than a drowning.
I'm going to be "that guy" and recommend you actually get to the point of having a general understanding and minimal competency in Java before tackling someone else's API. Once you know how Java works - the "PME" ... properties, methods, and events - learning anyone's API becomes just a question of following the proper steps.
Besides that little bit of PS, answer the following:
1) received data from your source?
2) what thread are you invoking this on?
3) any of the objects null?
4) any exceptions being thrown when you look in the Console or Log (print those out to the Log versus your current implementation)?
And, not for nothing, but if you don't have the time or patience to learn the "how's and why's" of an API or software dev in general then this will be a long exercise for you if the work ever becomes non-trivial.
Just one man's opinion who also has attempted to drink from fire hose before.
Update: Here's all of my code:
public class FriendsActivity extends Activity {
/** Called when the activity is first created. */
Facebook facebook = new Facebook("194653157245506");
TextView mText;
Bundle mBundle;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mText = (TextView) this.findViewById(R.id.text);
facebook.authorize(this, new String[] {"offline_access", "user_interests", "friends_interests"},
new DialogListener() {
#Override
public void onComplete(Bundle values) {}
#Override
public void onFacebookError(FacebookError error) {}
#Override
public void onError(DialogError e) {}
#Override
public void onCancel() {}
});
JSONObject json_data = null;
try
{
JSONObject response = Util.parseJson(facebook.request("/me/friends", mBundle, "GET")); // Get a friend information from facebook
JSONArray jArray = response.getJSONArray("data");
json_data = jArray.getJSONObject(0);
String name = json_data.getString("name");
Log.i("friend is", name);
mText.setText(name);
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (JSONException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (FacebookError e)
{
e.printStackTrace();
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
facebook.authorizeCallback(requestCode, resultCode, data);
}
}
I may be a little off key. but I have done facebook api development in C#, and i am wondering if you have had the client login.
Facebook works with OAuth to allow you to authorize through them for a client. (Even your own account as the client) therefore you may need to login.
Another thing to look at is, do you have the TextView that is in the Activity that is being displayed..
Try putting in a breakpoint and looking over the code as it is executing, Debug View is great for that.
see if your response is being populated.
make sure you have the Text from the Activity.
mText = (TextView)findViewById(R.id.TextView1); //or whatever you named it.
Also the LogCat should show you the stack trace for any errors that occur, maybe posting some of the output would help