0

几个星期以来,我们一直在解决一个之前在 SO 上讨论过的问题,但在我们遇到的具体案例中没有一个可行的答案。因此,在重新阅读了数十个线程并尝试了人们提供的所有代码之后,我请求您的帮助。(顺便说一句,别再三星了:事实证明他们帮不上忙。)

操作系统:4.0.x 到 4.2.x(API lvls 14 - 17)

设备:具有 /storage/sdcard0 的三星 S3(我们测试的所有设备都可以。)

...而不是旧的/mnt/sdcard/storage/sdcard (注意缺少尾随零)。

使用任何口味的

Environment.getExternalStorageDirectory().getAbsolutePath(); 
// e.g .getPath() .getName() etc.

// or

Environment.getExternalStoragePublicDirectory() ... 

或使用媒体 URI 通知系统文件位置。(令人震惊的是,这也失败了。)

现在保存一个文件 - 您会看到它显示在 DDMS 文件资源管理器中。你可以通过亚行拉取它来验证。但只需尝试重新读取相同的文件 - 使用您最初编写它的同一个应用程序!ENOENT - 未找到文件。硬编码路径,将 '/external_sd/' 附加到上面 os 调用给出的路径(Sumsung 说这是需要的 - 但它不会蹲下。)

正如一些人建议的那样,将“sdcard0”更改为“sdcard”……也尝试了所有这些。齐尔奇。

权限等当然都是正确的(因为进程何时可以写入文件但不能读取它!?)。

USB 电缆连接与否,调试模式与否,“真实应用程序”与开发人员应用程序(不受信任的应用程序) - 结果都一样:ENOENT

关于如何在此处进行的任何想法或建议?

(手里拿着一把大锤,全神贯注地盯着一个新的 SG3……而且,三星,如果你正在阅读这个:“/storage/sdcard0/external_sd/myFileFoo.txt”不起作用。)

/** 
 *
 * [Edit - added sample of failing code, as requested]
 */

public void testFile () {

      ImageView image ; 
      String m_Path = "/SamsuxS3/" ; // more fun than a barrel of NULLs
      String m_MyFile = "myFileFoo.jpg" ;

      image = (ImageView) findViewById ( R.id.imageView1 ) ; 

////   Test 0:
       m_Path = Environment.getExternalStorageDirectory().getAbsolutePath() ;   

////  Test 1:        
//       String getPath = Environment.getExternalStorageDirectory().getPath();  // fails
//       m_Path = getPath ;

////  Test 2:        
//       String getName = Environment.getExternalStorageDirectory().getName() ; //fails
//       m_Path = getName ;    

////  Test 3:        
//       String defPics = Environment.DIRECTORY_PICTURES;  // fails
//       m_Path = m_path + "/" + defPics + "/" ;     

////  Test 4:        
//       m_Path = "/storage/sdcard0/" ;  // fails

////  Test 5:        
//       m_Path = "/storage/sdcard0/external_sd/" // Samsung says so, but it fails too.   

////  Test 6: now we're really hacking ...
//      m_Path = "/storage/sdcard/"  // Fails (although sdcard is mounted as sdcard0 - hmmm)   

      InputStream fIn = null;
      File fileIn = new File(m_Path, m_MyFile);   

      try { //// This is only one way many attempts...  

            //// 1) just grab an image from a known resource, 
            //// 2) try to save it, 
            //// 3) then read it back into an ImageView.

            //// External storage must be mounted or this fails.

            InputStream is = getResources().openRawResource(R.drawable.somepicture) ;  // works
            OutputStream os = new FileOutputStream(fileIn); // OK

            byte[] data = new byte[is.available()]; // OK
            is.read(data);  // OK
            os.write(data); // OK - DDMS file explorer verfied
            is.close();
            os.close();

        } catch (IOException e) {
            Log.d("Error writing to " + m_Path, e.toString());  // never happened yet
        }

        //// now we step into the SamDung  
        ////
        InputStream fIn2 = null;  //// Well, it's redundant but ...
        File fileIn2 = new File(m_Path, m_MyFile);   

        try {
             fIn2 = new FileInputStream (fileIn2) ;   
              //
              // Here be the Dragons...
              //       
              // Next line WORKS on every device EXCEPT a Samsung - blows up w/ ENOENT !
              // 
             image.setImageBitmap ( BitmapFactory.decodeStream(fIn2) );  
             fIn2.close ();                                             
        } catch (Exception IOError) { 
             Log.d("WTF? I'm not moving to Korea: ",  IOError.toString()) ; 
        }  
  }      
4

1 回答 1

3

在Android 3.0+上写入文件的正确方法是:

  os.flush();
  os.getFD().sync();
  os.close();

对于一个FileOutputStream名为os.

使用此更改,您的示例代码可以Environment.getExternalStorageDirectory()在运行 Android 4.1.2 的三星 Galaxy S3 上使用。

于 2013-05-15T17:11:54.913 回答