Stackoverflowers,
我正在使用Android智能手机创建一个简单的项目来创建3D表单。我正在使用Android Processing制作一个简单的应用程序。
我的代码生成3D形状并将其另存为.STL文件。它适用于我的笔记本电脑并保存.STL文件,但在应用程序中。版本,我需要它保存到我的手机的外部存储/ SD卡(HTC Sensation)。它没有,因为我正在使用的Processing库中的“save”函数(writeSTL)的编写方式。
我已经在这里发帖求助了(我的代码更完整的代码也在这里):
...和编写该库的Marius Watz说,writeSTL()代码几乎是独立的,唯一缺少的是(或应该)替换创建输出流的代码,需要将其修改为工作用Android。基本上,这一行:
FileOutputStream out=(FileOutputStream)UIO.getOutputStream(p.sketchPath(filename));
我不是一个优秀的程序员,因为我通常可以让Processing做我需要做的事,但不能再做了。这个问题让我挨打。我正在寻找替代线的正确代码的想法:...
FileOutputStream out=(FileOutputStream)UIO.getOutputStream(p.sketchPath(filename));
......用“Android友好”的东西。调用getExternalStorageDirectory()应该可以工作,但我找不到正确的结构。
writeSTL函数的代码如下。
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/**
* Output binary STL file of mesh geometry.
* @param p Reference to PApplet instance
* @param filename Name of file to save to
*/
public void customWriteSTL(UGeometry geo, PApplet p, String filename) {
byte [] header;
ByteBuffer buf;
UFace f;
try {
if (!filename.toLowerCase().endsWith("stl")) filename+=".stl";
FileOutputStream out=(FileOutputStream)UIO.getOutputStream(p.sketchPath(filename));
buf = ByteBuffer.allocate(200);
header=new byte[80];
buf.get(header, 0, 80);
out.write(header);
buf.rewind();
buf.order(ByteOrder.LITTLE_ENDIAN);
buf.putInt(geo.faceNum);
buf.rewind();
buf.get(header, 0, 4);
out.write(header, 0, 4);
buf.rewind();
UUtil.logDivider("Writing STL '"+filename+"' "+geo.faceNum);
buf.clear();
header=new byte[50];
if (geo.bb!=null) UUtil.log(geo.bb.toString());
for (int i=0; i<geo.faceNum; i++) {
f=geo.face[i];
if (f.n==null) f.calcNormal();
buf.rewind();
buf.putFloat(f.n.x);
buf.putFloat(f.n.y);
buf.putFloat(f.n.z);
for (int j=0; j<3; j++) {
buf.putFloat(f.v[j].x);
buf.putFloat(f.v[j].y);
buf.putFloat(f.v[j].z);
}
buf.rewind();
buf.get(header);
out.write(header);
}
out.flush();
out.close();
UUtil.log("Closing '"+filename+"'. "+geo.faceNum+" triangles written.\n");
}
catch (Exception e) {
e.printStackTrace();
}
}
感谢任何建议。
提前谢谢。
答案 0 :(得分:1)
有几种方法可以做到这一点 - 一些正常工作,一些正确 ...就像处理/ Java一样。它与普通Java没有什么不同 - 唯一的怪癖是根SD路径,并检查它是否存在(请注意,有些手机具有“内部”而非“外部”存储(即不可移动/可交换),但Android应该将这些解释为相同的AFAIK。
在经典Java方式中,您应该事先检查 IF SD卡是否存在...我使用以下结构,取自this answer @kaolick
String state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_MOUNTED)) {
// Storage is available and writeable - ALL GOOD
} else if (state.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
// Storage is only readable - RUH ROH
} else {
// Storage is neither readable nor writeable - ABORT
}
请注意,他提供了一个完整的课程供您使用,这很棒,并且有一些便利功能。
您可能想要看的第二件事是在设备的SD卡上创建自定义目录,可能在setup()中 - 如下所示:
try{
String dirName = "//sdcard//MyAppName";
File newFile = new File(dirName);
if(newFile.exists() && newFile.isDirectory()) {
println("Directory Exists... All Good");
}
else {
println("Directory Doesn't Exist... We're Making It");
newFile.mkdirs();
}
}
catch(Exception e) {
e.printStacktrace();
}
当然,代替HardCoding路径名,你应该做类似的事情
String dirName = Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyAppName";
而不是......
另外,请注意上面的try / catch应该在INS语句中“if(state.equals(Environment.MEDIA_MOUNTED))”......或者应该包含在从那里调用的单独函数anc中。
然后,最后,保存它。如果你想使用BufferedWriter,它将如下所示:
BufferedWriter writer = new BufferedWriter(new FileWriter(dirName, true));
writer.write(STL_STUFF);
writer.flush();
writer.close();
我只在BufferedOutput Stream中使用FileOutputStream,它看起来像这样:
try {
String fileName = "SOME_UNIQUE_NAME_PER_FILE";
String localFile = dirName + "/" +filename;
OutputStream output = new BufferedOutputStream(newFileOutputStream(localFile));
}
catch(Exception e) {
e.printStackTrace();
}
最后,如果你和他说话,请向Marius致以问候! ; - )