2017-09-06 45 views
0

私はAndroidカメラアプリを使用するAndroidアプリを持っています。私は特定のファイル名が必要なので、私自身のCameraActivityを作成しました。このアクティビティで 新しいファイルがFile.createTempFile()で作成されたときの負のランダムint

私はそうのような私の一時ファイルを作成します。

public File createImageFile() throws IOException { 
    File pathOfStorageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); 
    pathOfStorageDir.mkdir(); 

    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
    String filePrefix = "img_" + timeStamp + "_"; 
    String suffix = ".jpg"; 

    File image = File.createTempFile(filePrefix, suffix, pathOfStorageDir); 
    currentFileName = image.getName(); 
    currentFilePath = image.getAbsolutePath(); 
    return image; 
} 

奇妙なことは、私は新しいファイル名でから、時には負の値を得ることです。

私はcreateTempFile()を呼び出して、generateTempFile()を呼び出し、そのメソッドはランダム絶対整数を作成する必要があります。なぜこのランダムintは時々負であるのですか?または、どうすればそれを避けることができますか?

問題:私のアプリケーションで後でファイルを必要としますが、 " - "記号でインポートすることはできません。これは私にこの例外を投げます: Error:com.android.build.gradle.tasks.ResourceException: <package-name>/app/src/main/res/drawable/img_sfr_20170715_-1‌​13604.jpg: Error: '-' is not a valid file-based resource name character: File-based resource names must contain only lowercase a-z, 0-9, or underscore

おかげさまで助けてくれてありがとう!

+1

なぜ重要ですか?それが引き起こす特定の問題はありますか、それとも単に審美的に不快なものでしょうか? –

+0

@Andy Turner: " - "記号は、Androidのファイル名の文字として受け入れられません。だから私は常に名前の名前を変更する必要があります。 –

+0

@HansiHansenbaumそうです。 AndroidはLinuxです。受け入れられない文字は/とヌルターミネータだけです –

答えて

0

これは興味深いことです:android.jarのFile.createTempFile()メソッドがrt.jarのものとは異なって実装されているようです。 rt.jar内

(Javaの8で)、我々は持っている:TempDirectory.generateFile(String, String, File)を使用しています

public static File createTempFile(String prefix, String suffix, 
            File directory) 
    throws IOException 
{ 
    if (prefix.length() < 3) 
     throw new IllegalArgumentException("Prefix string too short"); 
    if (suffix == null) 
     suffix = ".tmp"; 

    File tmpdir = (directory != null) ? directory 
             : TempDirectory.location(); 
    SecurityManager sm = System.getSecurityManager(); 
    File f; 
    do { 
     f = TempDirectory.generateFile(prefix, suffix, tmpdir); 

     if (sm != null) { 
      try { 
       sm.checkWrite(f.getPath()); 
      } catch (SecurityException se) { 
       // don't reveal temporary directory location 
       if (directory == null) 
        throw new SecurityException("Unable to create temporary file"); 
       throw se; 
      } 
     } 
    } while ((fs.getBooleanAttributes(f) & FileSystem.BA_EXISTS) != 0); 

    if (!fs.createFileExclusively(f.getPath())) 
     throw new IOException("Unable to create temporary file"); 

    return f; 
} 

private static final SecureRandom random = new SecureRandom(); 
    static File generateFile(String prefix, String suffix, File dir) 
     throws IOException 
    { 
     long n = random.nextLong(); 
     if (n == Long.MIN_VALUE) { 
      n = 0;  // corner case 
     } else { 
      n = Math.abs(n); 
     } 

     // Use only the file name from the supplied prefix 
     prefix = (new File(prefix)).getName(); 

     String name = prefix + Long.toString(n) + suffix; 
     File f = new File(dir, name); 
     if (!name.equals(f.getName()) || f.isInvalid()) { 
      if (System.getSecurityManager() != null) 
       throw new IOException("Unable to create temporary file"); 
      else 
       throw new IOException("Unable to create temporary file, " + f); 
     } 
     return f; 
    } 

これは、それらの正の乱数でファイル名につながります。 android.jar(AndroidのAPI 20)では

、我々は持っている:

public static File createTempFile(String prefix, String suffix, File directory) 
     throws IOException { 
    // Force a prefix null check first 
    if (prefix.length() < 3) { 
     throw new IllegalArgumentException("prefix must be at least 3 characters"); 
    } 
    if (suffix == null) { 
     suffix = ".tmp"; 
    } 
    File tmpDirFile = directory; 
    if (tmpDirFile == null) { 
     String tmpDir = System.getProperty("java.io.tmpdir", "."); 
     tmpDirFile = new File(tmpDir); 
    } 
    File result; 
    do { 
     result = new File(tmpDirFile, prefix + tempFileRandom.nextInt() + suffix); 
    } while (!result.createNewFile()); 
    return result; 
} 

tempFileRandomが標準Randomインスタンスであるので、そのnextInt()方法は、正だけでなく、負の整数を返します。

したがって、File.createTempFile()を使用すると、Androidでマイナス記号/ハイフン付きのファイル名を返すことができます。

ベストプラクティスは、ランタイムライブラリで提供されているものに基づいて、独自のファイル名ジェネレータとcreateTempFile()メソッドを実装することですが、正の乱数のみを使用します。

+0

のみが含まれている必要があります。これはAndroidのバグです。独自のコードは、使用できないファイル名を生成します。 – EJP

+0

他のコメントで述べたように、一般的にAndroidベースのLinuxは、マイナス記号付きのファイル名を扱うことができます。 HansenbaumのエラーメッセージであるError:com.android.build.gradle.tasks.ResourceExceptionから判断すると、ビルドプロセスのファイル名の制限に問題があるようです。確かに、一時ファイルを作成し、それをリソースとして追加するのは少し珍しいことです。 –

+0

ありがとうございました!私はこれをスライドさせると思います。私の目標は、画像ファイルを保存してプロトタイプに追加するための一時的なソリューションを実装することでした。しかし、長期的には、とにかくネットワークベースのソリューションを見つける必要があります。 –

0

簡単な回避策として、 " - "をファイル名文字列の "x"のように置き換えることができます。

厳密に言えば、これはcreateFileExclusively()についての保証を無効にする可能性がありますが、競合/衝突の可能性はほとんど存在しません。

関連する問題