File.lastModified () nunca es lo que se estableció con file.setLastModified ()

Tengo un problema con millis establecido y leer en Android 2.3.4 en un Nexus One. Este es el código:

File fileFolder = new File(Environment.getExternalStorageDirectory(), appName + "/" + URLDecoder.decode(folder.getUrl())); if (fileFolder != null && !fileFolder.exists()) { fileFolder.setLastModified(1310198774); fileFolder.mkdirs(); fileFolder.setLastModified(1310198774); } if (fileFolder != null && fileFolder.exists()) { long l = fileFolder.lastModified(); } 

En esta prueba pequeña escribo 1310198774 pero el resultado que se devuelve de lastModified () es 1310199771000.

Incluso si he cortado el "000", hay una diferencia de varios minutos.

Necesito sincronizar archivos entre un servicio web y el dispositivo Android. Los últimos módulos de modificación forman parte de los datos enviados por este servicio. Hago fijar los millis a los archivos creados / copiados y a las carpetas para comprobar si el archivo / carpeta necesita ser sobrescrito.

Todo está funcionando, pero los millis que se devuelven desde el sistema de archivos son diferentes de los valores que se establecieron.

Estoy bastante seguro de que hay algo mal con mi código, pero no lo encuentro.

Muchas gracias de antemano. HJW

Así que tal vez estoy perdiendo algo, pero veo algunos problemas con su código anterior. Su problema específico puede ser debido (como @ JB mencionado) a las ediciones de Androide pero para la posteridad, pensé que daría una respuesta.

En primer lugar, File.setLastModified() toma el tiempo en milisegundos. Aquí están los javadocs . Parece que estás intentando establecerlo en segundos. Así que su código debe ser algo como:

 fileFolder.setLastModified(1310198774000L); 

Como se menciona en los javadocs, muchos sistemas de archivos sólo admiten la granularidad de segundos para el tiempo de última modificación. Así que si necesitas ver el mismo tiempo de modificación en un archivo, debes hacer algo como lo siguiente:

 private void changeModificationFile(File file, long time) { // round the value down to the nearest second file.setLastModified((time / 1000) * 1000); } 

En Jelly Bean +, es diferente (sobre todo en dispositivos Nexus, y otros que usan la nueva capa de fusible para emulación mdm / shell / emulation sdcard):

Es un problema de permiso de VFS, el syscall utimensat () falla con EPERM debido a permisos inadecuados (por ejemplo, propiedad).

En la plataforma / system / core / sdcard / sdcard.c:

/ * Todos los archivos propiedad de root.sdcard * /
Attr-> uid = 0;
Attr-> gid = AID_SDCARD_RW;

De la página de manual syscall de utimensat ():

 2. the caller's effective user ID must match the owner of the file; or 3. the caller must have appropriate privileges. To make any change other than setting both timestamps to the current time (ie, times is not NULL, and both tv_nsec fields are not UTIME_NOW and both tv_nsec fields are not UTIME_OMIT), either condition 2 or 3 above must apply. 

Old FAT ofrece una anulación de la iattr-> bandera válida a través de una opción de montaje para permitir el cambio de marcas de tiempo a cualquier persona, FUSE + sdcard-FUSE de Android no lo hacen en este momento (por lo que la llamada 'inode_change_ok () falla) y el intento Se rechaza con -EPERM. Aquí está FAT ./fs/fat/file.c:

 /* Check for setting the inode time. */ ia_valid = attr->ia_valid; if (ia_valid & TIMES_SET_FLAGS) { if (fat_allow_set_time(sbi, inode)) attr->ia_valid &= ~TIMES_SET_FLAGS; } error = inode_change_ok(inode, attr); 

También he añadido esta información a este error abierto .

Si todo esto no funciona, pruebe esta solución (fea) citada en https://code.google.com/p/android/issues/detail?id=18624 :

 //As a workaround, this ugly hack will set the last modified date to now: RandomAccessFile raf = new RandomAccessFile(file, "rw"); long length = raf.length(); raf.setLength(length + 1); raf.setLength(length); raf.close(); 

Funciona en algunos dispositivos pero no en otros. No diseñe una solución que dependa de su funcionamiento. Consulta https://code.google.com/p/android/issues/detail?id=18624#c29.

Aquí hay una prueba simple para ver si funciona.

 public void testSetLastModified() throws IOException { long time = 1316137362000L; File file = new File("/mnt/sdcard/foo"); file.createNewFile(); file.setLastModified(time); assertEquals(time, file.lastModified()); } 

Si sólo desea cambiar la fecha / hora de un directorio a la fecha / hora actual (es decir, "ahora"), puede crear algún tipo de archivo temporal dentro de ese directorio, escribir algo en él y luego eliminarlo inmediatamente. Esto tiene el efecto de cambiar la fecha / hora 'lastModified ()' del directorio a la fecha / hora actual. Esto no funcionará, sin embargo, si desea cambiar la fecha / hora del directorio a algún otro valor aleatorio, y no se puede aplicar a un archivo, obviamente.

  • ¿Cómo se relaciona la versión Java de Android con una versión de Java SE?
  • Android no puede abrir mi aplicación
  • Cómo deshabilitar la reproducción de fondo de vídeo al salir de la aplicación Córdoba android
  • Proyecto de Android que utiliza httpclient -> http.client (apache), método post / get
  • Los servicios de juegos de Google Play logran desbloqueo: desbloquear tienda en juego o desbloquear (?) Cada vez.
  • Manejo y Mitigación IllegalStateException ("estado de error: activo $ Fragmento ha borrado el índice: -1")
  • Guardar una imagen con su pulgar y mostrarla en imageView android
  • ¿Hay un equivalente TweenMax en Java
  • Cómo agregar el evento de botón de clic en el estudio de android
  • Carga dibujable desde la tarjeta sd
  • Analizar fecha en android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.