我仍然是Android开发的新手,所以如果我的问题看起来很傻,我会提前道歉。
在我的应用程序中,我有一个按钮。单击该按钮时,它会尝试查看应用程序是否在内部存储上有自己的文件夹,如果没有创建文件夹,则会创建一个名为output.txt的文件,然后将系统信息写入output.txt,然后它尝试将包含“SIP_MESSAGE”的所有行从logcat写入output.txt,然后通过电子邮件发送默认电子邮件地址。
经过几天的劳动,我设法把它们放在一起。请仔细阅读以下答案。
答案 0 :(得分:1)
经过几天的研究和无数次的猜测和检查,我终于想出了一切。我想花时间来实际解释一切,万一有人碰到这个并且遇到了同样的问题。希望你所寻找的一切都在这里,我给出了一个更好的解释,那就是你(和我)之前访问过的100个其他网站。
第一个主题是内部和外部存储之间的区别(它不是SD卡和非SD卡之间的区别)。
除了您的应用程序,内部存储是任何人都无法看到或得到的东西。如果您在内部存储上创建文件或文件夹,则无法使用文件浏览器(除非您的root用户)或您的计算机查看您创建的内容,而是从应用程序外部无法访问它。
公共文件夹,例如文件/下载/音乐/铃声/等。在技术上是你的外部存储。您需要具有写入和读取权限的权限。这是我感到困惑的地方。我认为只有sdcards被视为外部存储,外部存储是你可以手动从计算机或文件浏览器访问的,无论它是否在SD卡上。
要在内部或外部存储上创建文件,您不需要使用mkDir()。任何说你这么做的人都会让事情变得过于复杂。实际上,你可以从代码中的任何地方创建任何文本文件:
PrintWriter osw = new PrintWriter(Environment.getExternalStoragePublicDirectory(DOWNLOAD_SERVICE).toString() + "/output.txt");
这会在下载目录中创建一个文本文件,无论它是否存在。您还可以使用getDataDirectory()或您想要创建文件的任何其他位置。
Next Logcat,就像其他人指出的一样,我试图在logcat创建时读取它。 logcat没有结束,所以实际上,我的应用程序挂了,因为它一直在寻找更多的写入。一个简单的方法是使用logcat的-d功能。这样做只是将所有内容都放到-d输入的位置(这正是我想要的),然后它停止,然后你就可以将它放入一个缓冲区并获得没有挂起的输出。
最后,将文件附加到电子邮件意图。这个很棘手,因为有几个不同的领域最终给我带来了麻烦。简而言之,如果您收到错误“无法显示附件”,则表示两件事之一 - 1.)您正试图从内部存储器附加文件(请记住,不允许其他程序访问内存,甚至是gmail)或2.)你没有使用getAbsolutePath()。我找到了很多人说你不能使用uri.parse()附加文件而你必须使用uri.fromFile(),这是错误的,附加我告诉你如何附加文件而不是得到一个错误。
我希望这段代码对你有所帮助,我希望你不要花费1/10的时间来尝试解决这些问题。
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;
}
}
最后,我用于此的权限是READ_LOGS,WRITE_EXTERNAL,READ_EXTERNAL。
我希望你很开心,祝你好运。
答案 1 :(得分:0)
哎呀!太快说,你的意思是内部。
为什么不尝试将文件直接写入app目录而不是创建文件夹。检查它是否有效。
您可以这样做:
FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
这就是您要找的内容:
File outputDir = new File(Environment.getExternalStorageDirectory()
+ "/farmer survey");
outputDir.mkdirs();
File outputFile = new File(outputDir, "something.csv");
try {
FileOutputStream fos = new FileOutputStream(outputFile);
PrintWriter pw = new PrintWriter(fos);
pw.println(text);
pw.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
您还需要添加此权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
答案 2 :(得分:0)
你的清单中是否有android.permission.READ_LOGS权限?
答案 3 :(得分:0)
对于电子邮件部分,您打算自动发送吗?
如果是这样,我认为不能在后台轻松完成。最好的方法是使用附加的output.txt调用Gmail应用。随后,您需要手动发送它。
否则编码可能会很长,请看:
Sending Email in Android using JavaMail API without using the default/built-in app
或者另一种方式是通过短信发送,这可以在后台完成。