0

我对 Android 开发还是很陌生,所以如果我的问题看起来很愚蠢,我提前道歉。

在我的应用程序中,我有一个按钮。单击按钮时,它会尝试查看应用程序在内部存储中是否有自己的文件夹,如果没有,它会创建一个文件夹,然后创建一个名为 output.txt 的文件,然后将系统信息写入 output.txt,然后它尝试将所有包含“SIP_MESSAGE”的行从 logcat 写入 output.txt,然后通过电子邮件发送默认电子邮件地址。


编辑

经过几天的辛勤工作,我设法把它们放在一起。请详细阅读下面的答案。

4

4 回答 4

1

经过几天的研究和无数次的猜测和检查,我终于弄清楚了一切。我想花时间解释一切,以防万一有人遇到这个问题并遇到与我相同的问题。希望您正在寻找的一切都在这里,并且我给出了比您(和我)之前访问过的 100 个其他站点更好的解释。

第一个主题是内部和外部存储之间的区别(这不是 sdcard 和 not sdcard 之间的区别)。

内部存储是除了您的应用程序之外没有人可以看到或访问的东西。如果您在内部存储上创建文件或文件夹,则无法使用文件浏览器(除非您的 root)或您的计算机来查看您创建的内容,从您的应用程序外部完全无法访问它。

公用文件夹,例如 Documents/Downloads/Music/Ringtones/etc。从技术上讲,在您的外部存储上。您需要权限才能对其进行写入和读取。这就是我感到困惑的地方。我认为只有 sdcard 才算作外部存储,外部存储是您可以从计算机或文件浏览器手动获取的东西,无论它是否在 sdcard 上。

要在内部或外部存储上创建文件,您不需要使用 mkDir()。任何说你这样做的人都过于复杂化了事情。实际上,您可以仅通过代码在系统上的任何位置创建任何文本文件:

PrintWriter osw = new PrintWriter(Environment.getExternalStoragePublicDirectory(DOWNLOAD_SERVICE).toString() + "/output.txt");

这会在下载目录中创建一个文本文件,无论它是否首先存在。您还可以使用 getDataDirectory() 或您要创建文件的任何其他位置。

下一个 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。

我希望你喜欢,祝你好运。

于 2013-01-24T23:01:32.730 回答
0

哎呀!说话太快了,你的意思是内部的。

您为什么不尝试将文件直接写入您的应用程序目录而不是创建文件夹。首先检查它是否有效。

为此,您可以这样做:

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"/>
于 2013-01-23T01:18:24.943 回答
0

对于电子邮件部分,您是否打算自动发送?

如果是这样,我认为它不能在后台轻松完成。最好的办法是调用 Gmail 应用程序,并将 output.txt 作为附件附加。随后,您需要手动发送它。

否则编码可能会很长,请参见此处:

在不使用默认/内置应用程序的情况下使用 JavaMail API 在 Android 中发送电子邮件

或者另一种方式是通过短信发送出去,这可以在后台完成。

于 2013-01-23T02:57:13.103 回答
0

您的清单中有 android.permission.READ_LOGS 权限吗?

于 2013-01-23T02:25:58.843 回答