After a few days of research and a countless number of guess and checks, I finally figured everything out. I want to take this time to actually explain everything, in case anyone comes across this and is having the same problems that I had. Hopefully everything you are looking for is right here, and I gave a better explanation then the 100's of other sites that you (and I) had visited previous to this.
First topic is the difference between internal and external storage (it's not the difference between sdcard and not sdcard).
Internal storage is something that no one can see or get to but your application. If you create a file or folder on the internal storage, you cant use a file browser (unless your rooted) or your computer to see what you've created, it is completely inaccessible from outside your application.
Public folders such as Documents/Downloads/Music/Ringtones/etc. are technically on you external storage. You need permissions to write and read from it. This is where I was getting confused. I thought only sdcards counted as external storage, external storage is something you can manually get to from a computer or file browser whether its on an sdcard or not.
To create a file on the internal or external storage you do not need to use mkDir(). Anyone that says you do, is overly complicating things. You can actually create any text file anywhere on the system just from the code:
PrintWriter osw = new PrintWriter(Environment.getExternalStoragePublicDirectory(DOWNLOAD_SERVICE).toString() + "/output.txt");
This creates a text file in the download directory, whether it existed there or not first. You can also use getDataDirectory() or wherever else you want to create the file.
Next Logcat, like what the other people were pointing out, I was trying to read from the logcat as it was being created. There is no end to the logcat, so in effect, my application hung because it was constantly looking for more to write. An easy way around this is to use the -d feature of logcat. What that does is it just takes everything up to the point where -d was entered (which was exactly what I wanted), then it stops, then you can put it into a buffer and get the output with no hanging.
Finally, attaching a file to an email intent. This one was tricky because there were a few different areas that ended up giving me problems. In short, if you are receiving the error, "Couldn't show attachment", it means one of two things - 1.) you are trying to attach a file from the internal memory (remember, no other programs are allowed to access the internal memory, even gmail) or 2.) you are not using getAbsolutePath(). I found quite a few people that said you can't attach a file using uri.parse() and the you have to use uri.fromFile(), that is wrong, attached I show you how to attach a file and not get an error.
I hope this code helps you, and I hope you do not spend 1/10th of the time I did trying to figure this stuff out.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Calendar;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button mailb = (Button)findViewById(R.id.bmail);
final TextView confirmation = (TextView)findViewById(R.id.Confirmation);
mailb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
PrintWriter osw = new PrintWriter(Environment.getExternalStoragePublicDirectory(DOWNLOAD_SERVICE).toString() + "/output.txt"); //This creates a file in my public download directory
osw.println("Output Log: Report Tool");
osw.println("Date: " + java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime()));
osw.println("------------------------------------");
osw.println("Manufacturer: " + android.os.Build.MANUFACTURER);
osw.println("Model: " + android.os.Build.MODEL);
osw.println("Serial: " + android.os.Build.SERIAL);
osw.println("BootLoader: " + android.os.Build.BOOTLOADER);
osw.println("Build ID: " + android.os.Build.FINGERPRINT);
osw.println("------------------------------------");
try {
Process p = Runtime.getRuntime().exec("logcat -d -v long"); //This gets the dump of everything up to the button press
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
if(line.toString().contains("SIP_MESSAGE")){ //This parses out everything but SIP Messages
osw.println(line); }}}
catch (IOException e1) {confirmation.setText(e1.getMessage()); }
osw.flush();
osw.close();
} catch(Exception e){ confirmation.setText(e.getMessage()); }
String attach = Environment.getExternalStoragePublicDirectory(DOWNLOAD_SERVICE).getAbsolutePath() + "/output.txt"; //This is where you need to use the absolute path!!
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_EMAIL , new String[]{"MyEmail@Email.com"});
i.putExtra(Intent.EXTRA_SUBJECT, "Error Report.");
i.putExtra(Intent.EXTRA_TEXT , "Please see the attached file...");
i.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + attach)); //This is where you attach the file
try {
startActivity(Intent.createChooser(i, "Send mail..."));}
catch (android.content.ActivityNotFoundException ex) {
confirmation.setText("There is no Email Client installed on this device.");}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
And finally, the permissions I used for this was READ_LOGS, WRITE_EXTERNAL, READ_EXTERNAL.
I hope you've enjoyed, and good luck.