在Android设备上创建和存储日志文件

24

我计划通过创建一个日志来自动化测试应用程序,并存储一些执行结果,然后使用 Python 代码解析它并绘制图形。

该应用程序是一个 WiFi 指纹识别器,即它收集周围环境中的 Wi-Fi 设备的 mac id、rss(接收信号强度)和 rank(标准化 rss)等信息。因此,要测试这个应用程序,我需要将其带到该位置并记录结果(目前手动)。因此,logcat 不能完成这个任务。

自动化需要: 1. 在设备中存储日志 2. 通过 USB 访问系统中的日志文件

日志文件格式:

Snapshot: 1
Fingerprint: 1, Rank: 0.23424, Boolean: true
Fingerprint: 2, Rank: 0.42344, Boolean: false
Fingerprint: 3, Rank: 0.23425, Boolean: true

Snapshot: 2
Fingerprint: 1, Rank: 0.75654, Boolean: false
Fingerprint: 2, Rank: 0.23456, Boolean: true
Fingerprint: 3, Rank: 0.89423, Boolean: true 

................

现在我知道持久化存储基本上有三种方法(SharedPrefs对这种情况无用)。我尝试使用内部存储,但即使将文件模式设置为MODE_WORLD_READABLE,也无法在Eclipse的Device File Explorer中读取该文件

我仍然不放心使用外部存储来存储日志。任何有关如何将文件写入设备USB的教程都会非常有帮助。

我考虑将要存储的数据结构化,以便使用SQLite进行存储。但这将在数据之间建立许多不必要的关系(国内和外国),使其变得复杂。如果没有其他方法,那么这里就有风险。

基本上,我想要在设备中写入一个文件(我认为更容易),然后通过USB连接到我的系统上读取它。如何实现这一点,任何帮助都将不胜感激。


1
请前往http://code.google.com/p/microlog4android。 - 100rabh
@100rabh,如何使用它的任何指针? - Primal Pappachan
这里有一个相关的问题,简单地展示了如何写入SD卡:https://dev59.com/EnI-5IYBdhLWcg3woJ9J - RenniePet
2个回答

14
即使有所顾虑,外部存储仍可能是唯一的选择。如果设备没有root访问权限,除非你愿意在设备上的应用程序中读取内容,否则你实际上无法访问任何“内部”内容。文档提供了创建外部文件的相当可靠的指南,并且如果你正在使用API Level 8或更高级别,则可以使用一些额外的函数。我确定你已经熟悉此页面,但这里还是给出链接:http://developer.android.com/guide/topics/data/data-storage.html#filesExternal 如果需要任何文件IO示例代码……我想我可以找到一些……
编辑-我建议按照上述文档中的指南首先确认存储状态。我不幸地没有任何使用Java追加文件的经验,所以其他人肯定比我更有资格回答。这并未涵盖追加,但我在我的个人应用程序中有一个备份例程,看起来像这样。
    File backupPath = Environment.getExternalStorageDirectory();

    backupPath = new File(backupPath.getPath() + "/Android/data/com.maximusdev.bankrecord/files");

    if(!backupPath.exists()){
        backupPath.mkdirs();
    }

    FileOutputStream fos;
    try {
        fos = new FileOutputStream(backupPath.getPath() + "/recordsbackup.txt");

        if(okaytowrite){
            for(int i = 0; i < count; ++i){
                entry = adapter.getItem(i);
                fos.write(entry.toString().getBytes());
                fos.write("\n".getBytes());
                fos.write(String.valueOf(entry.dateTime).getBytes());
                fos.write("\n".getBytes());
                fos.write(String.valueOf(entry.sign).getBytes());
                fos.write("\n".getBytes());
                fos.write(String.valueOf(entry.cleared).getBytes());
                fos.write("\n".getBytes());
                fos.write(String.valueOf(entry.transDate).getBytes());
                fos.write("\n".getBytes());
                fos.write(entry.category.getBytes());
                fos.write("\n".getBytes());
            }
        }
        fos.close();

        Toast.makeText(this, "Backup Complete", Toast.LENGTH_SHORT).show();

    } catch (FileNotFoundException e) {

        e.printStackTrace();

        AlertDialog.Builder delmessagebuilder = new AlertDialog.Builder(this);

        delmessagebuilder.setCancelable(false);

        delmessagebuilder.setMessage("File Access Error");

        delmessagebuilder.setNeutralButton("Okay", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                dialog.dismiss();
            }
        });

        delmessagebuilder.create().show();

    } catch (IOException e) {

        e.printStackTrace();

        AlertDialog.Builder delmessagebuilder = new AlertDialog.Builder(this);

        delmessagebuilder.setCancelable(false);

        delmessagebuilder.setMessage("File Access Error");

        delmessagebuilder.setNeutralButton("Okay", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                dialog.dismiss();
            }
        });

        delmessagebuilder.create().show();
    }

当我准备写入时,我从一个 ArrayAdapter (适配器) 中取出一个自定义对象(entry),将字段值转换为字符串并使用 getBytes() 传递给 FileOutputStream 的write函数。我进行了一些研究,在Java/Android中有很多其他的文件写入选项...例如 FileWriter 类,因此这需要进一步的研究。


文件IO示例中写入外部存储的代码会很有帮助。 :) - Primal Pappachan
我会看看能做些什么... Java 说实话不是我的第一语言,所以类似这样的东西在 C 中的示例更适合我。我会尝试发布一些 Java 的内容,但可能会遭到批评... 我现在在 Java 中所做的所有 I/O 操作都是相当粗略的。如果有其他人愿意加入其中,那当然是受欢迎的。具体而言... 不幸的是,我没有进行任何文件附加操作。 - Maximus
感谢您的关注。我读到外部存储的文件IO与Java中的IO并没有什么不同,所以我可以处理它。 - Primal Pappachan
是的,我明白它是一样的。那么请不要介意我的糟糕示例……你可能已经有了更好的东西 :) - Maximus
无论如何,感谢您的发布。 :) - Primal Pappachan

13

我使用了一种非常简单的方法来将字符串消息写入日志文件,即创建一个FileWriter对象。

    public static BufferedWriter out;
        private void createFileOnDevice(Boolean append) throws IOException {
                /*
                 * Function to initially create the log file and it also writes the time of creation to file.
                 */
                File Root = Environment.getExternalStorageDirectory();
                if(Root.canWrite()){
                     File  LogFile = new File(Root, "Log.txt");
                     FileWriter LogWriter = new FileWriter(LogFile, append);
                     out = new BufferedWriter(LogWriter);
                     Date date = new Date();
                     out.write("Logged at" + String.valueOf(date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds() + "\n")); 
                     out.close();

            }
        }

现在是写入新消息到日志文件的函数。

    public void writeToFile(String message){
            try {
                out.write(message+"\n");
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

非常好的例子,我很可能会借鉴这种方法。 - Maximus
1
out.write(...) 语句之后,你需要加上 out.close()。否则它不会保存写入的内容。(我是通过吃亏才明白这个问题的。) - Randy
一旦你使用 out.close() 关闭了缓冲区,就不能再向文件中重新写入数据。也就是说,如果你在 createFileOnDevice 中使用 out.close(),那么在下一次的 out.write() 之前,你需要在 writeToFile 中使用相同路径创建一个新的 FileWriter 对象。 - lanyusea

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接