Skip to content

Commit f0bfe23

Browse files
committed
Edit last modified date directly from the app
A new "Edit" section has been added to the app
1 parent 7837dd5 commit f0bfe23

9 files changed

Lines changed: 415 additions & 84 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@
1313
.externalNativeBuild
1414
.cxx
1515
local.properties
16+
app/release/app-release.apk
17+
app/release/output-metadata.json

app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ android {
1111
minSdk 21
1212
targetSdk 34
1313
versionCode 1
14-
versionName "1.0"
14+
versionName "1.1"
1515

1616
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1717
}
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
package dinoosauro.filedate.sync;
2+
3+
import android.content.ContentUris;
4+
import android.content.Context;
5+
import android.database.Cursor;
6+
import android.net.Uri;
7+
import android.os.Build;
8+
import android.os.Environment;
9+
import android.provider.DocumentsContract;
10+
import android.provider.MediaStore;
11+
12+
import androidx.core.content.ContextCompat;
13+
14+
import java.io.File;
15+
16+
public class ConvertDocumentFiles {
17+
// Huge thanks to: https://stackoverflow.com/a/39388941
18+
public static String getPathFromUri(final Context context, final Uri uri) {
19+
20+
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
21+
22+
// DocumentProvider
23+
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
24+
// ExternalStorageProvider
25+
if (isExternalStorageDocument(uri)) {
26+
final String docId = DocumentsContract.getDocumentId(uri);
27+
final String[] split = docId.split(":");
28+
final String type = split[0];
29+
30+
if ("primary".equalsIgnoreCase(type)) {
31+
return Environment.getExternalStorageDirectory() + "/" + split[1];
32+
}
33+
34+
// TODO handle non-primary volumes
35+
}
36+
// DownloadsProvider
37+
else if (isDownloadsDocument(uri)) {
38+
39+
final String id = DocumentsContract.getDocumentId(uri);
40+
final Uri contentUri = ContentUris.withAppendedId(
41+
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
42+
43+
return getDataColumn(context, contentUri, null, null);
44+
}
45+
// MediaProvider
46+
else if (isMediaDocument(uri)) {
47+
final String docId = DocumentsContract.getDocumentId(uri);
48+
final String[] split = docId.split(":");
49+
final String type = split[0];
50+
51+
Uri contentUri = null;
52+
if ("image".equals(type)) {
53+
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
54+
} else if ("video".equals(type)) {
55+
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
56+
} else if ("audio".equals(type)) {
57+
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
58+
}
59+
60+
final String selection = "_id=?";
61+
final String[] selectionArgs = new String[] {
62+
split[1]
63+
};
64+
65+
return getDataColumn(context, contentUri, selection, selectionArgs);
66+
}
67+
}
68+
// MediaStore (and general)
69+
else if ("content".equalsIgnoreCase(uri.getScheme())) {
70+
71+
// Return the remote address
72+
if (isGooglePhotosUri(uri))
73+
return uri.getLastPathSegment();
74+
75+
return getDataColumn(context, uri, null, null);
76+
}
77+
// File
78+
else if ("file".equalsIgnoreCase(uri.getScheme())) {
79+
return uri.getPath();
80+
}
81+
82+
return null;
83+
}
84+
85+
public static String getDataColumn(Context context, Uri uri, String selection,
86+
String[] selectionArgs) {
87+
88+
Cursor cursor = null;
89+
final String column = "_data";
90+
final String[] projection = {
91+
column
92+
};
93+
94+
try {
95+
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
96+
null);
97+
if (cursor != null && cursor.moveToFirst()) {
98+
final int index = cursor.getColumnIndexOrThrow(column);
99+
return cursor.getString(index);
100+
}
101+
} finally {
102+
if (cursor != null)
103+
cursor.close();
104+
}
105+
return null;
106+
}
107+
108+
109+
/**
110+
* @param uri The Uri to check.
111+
* @return Whether the Uri authority is ExternalStorageProvider.
112+
*/
113+
public static boolean isExternalStorageDocument(Uri uri) {
114+
return "com.android.externalstorage.documents".equals(uri.getAuthority());
115+
}
116+
117+
/**
118+
* @param uri The Uri to check.
119+
* @return Whether the Uri authority is DownloadsProvider.
120+
*/
121+
public static boolean isDownloadsDocument(Uri uri) {
122+
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
123+
}
124+
125+
/**
126+
* @param uri The Uri to check.
127+
* @return Whether the Uri authority is MediaProvider.
128+
*/
129+
public static boolean isMediaDocument(Uri uri) {
130+
return "com.android.providers.media.documents".equals(uri.getAuthority());
131+
}
132+
133+
/**
134+
* @param uri The Uri to check.
135+
* @return Whether the Uri authority is Google Photos.
136+
*/
137+
public static boolean isGooglePhotosUri(Uri uri) {
138+
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
139+
}
140+
141+
}

app/src/main/java/dinoosauro/filedate/sync/FileDateSync.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,25 @@ public void onCreate() {
1111
DynamicColors.applyToActivitiesIfAvailable(this);
1212
}
1313

14+
/**
15+
* The Unix Epoch time that is used in the "Edit" section
16+
*/
17+
private static long selectedTime = 0;
18+
19+
/**
20+
* Update the Unix Epoch time that is used in the "Edit" section
21+
* @param newTime the Unix Epoch time
22+
*/
23+
public static void updateSelectedTime(long newTime) {
24+
selectedTime = newTime;
25+
}
26+
27+
/**
28+
* Get the Unix Epoch time that is used in the "Edit" section
29+
* @return the Unix epoch time
30+
*/
31+
public static long getSelectedTime() {
32+
return selectedTime;
33+
}
34+
1435
}

0 commit comments

Comments
 (0)