@@ -20,105 +20,105 @@ namespace Uno.Samples;
20
20
21
21
partial class MediaGallery
22
22
{
23
- private static async Task < bool > CheckAccessAsyncImpl ( )
24
- {
25
- if ( ( int ) Build . VERSION . SdkInt < 29 )
26
- {
27
- return await PermissionsHelper . CheckWriteExternalStoragePermission ( default ) ;
28
- }
29
- else
30
- {
31
- return true ;
32
- }
33
- }
34
-
35
- private static async Task SavePlatformAsyncImpl ( MediaFileType type , Stream sourceStream , string targetFileName )
36
- {
37
- var context = Android . App . Application . Context ;
38
- var contentResolver = context . ContentResolver ?? throw new InvalidOperationException ( "ContentResolver is not set." ) ;
39
-
40
- var appFolderName = Package . Current . DisplayName ;
41
- // Ensure folder name is file system safe
42
- appFolderName = string . Join ( "_" , appFolderName . Split ( Path . GetInvalidFileNameChars ( ) ) ) ;
43
-
44
- var dateTimeNow = DateTime . Now ;
45
-
46
- var fileNameWithoutExtension = Path . GetFileNameWithoutExtension ( targetFileName ) ;
47
- var extension = Path . GetExtension ( targetFileName ) . ToLower ( ) ;
48
-
49
- using var values = new ContentValues ( ) ;
50
-
51
- values . Put ( IMediaColumns . DateAdded , GetUnixTimestampInSeconds ( dateTimeNow ) ) ;
52
- values . Put ( IMediaColumns . Title , fileNameWithoutExtension ) ;
53
- values . Put ( IMediaColumns . DisplayName , targetFileName ) ;
54
-
55
- var mimeTypeMap = MimeTypeMap . Singleton ?? throw new InvalidOperationException ( "MimeTypeMap is not set." ) ;
56
-
57
- var mimeType = mimeTypeMap . GetMimeTypeFromExtension ( extension . Replace ( "." , string . Empty ) ) ;
58
- if ( ! string . IsNullOrWhiteSpace ( mimeType ) )
59
- values . Put ( IMediaColumns . MimeType , mimeType ) ;
60
-
61
- using var externalContentUri = type == MediaFileType . Image
62
- ? Images . Media . ExternalContentUri
63
- : Video . Media . ExternalContentUri ;
64
-
65
- if ( externalContentUri is null )
66
- {
67
- throw new InvalidOperationException ( $ "External Content URI for { type } is not available.") ;
68
- }
69
-
70
- var relativePath = type == MediaFileType . Image
71
- ? Environment . DirectoryPictures
72
- : Environment . DirectoryMovies ;
73
-
74
- if ( relativePath is null )
75
- {
76
- throw new InvalidOperationException ( $ "Relative path for { type } is not available.") ;
77
- }
78
-
79
- if ( ( int ) Build . VERSION . SdkInt >= 29 )
80
- {
81
- values . Put ( IMediaColumns . RelativePath , Path . Combine ( relativePath , appFolderName ) ) ;
82
- values . Put ( IMediaColumns . IsPending , true ) ;
83
-
84
- using var uri = contentResolver . Insert ( externalContentUri , values ) ??
85
- throw new InvalidOperationException ( "Could not generate new content URI" ) ;
86
-
87
- using var stream = contentResolver . OpenOutputStream ( uri ) ??
88
- throw new InvalidOperationException ( "Could not open output stream" ) ;
89
-
90
- await sourceStream . CopyToAsync ( stream ) ;
91
- stream . Close ( ) ;
92
-
93
- values . Put ( IMediaColumns . IsPending , false ) ;
94
- context . ContentResolver . Update ( uri , values , null , null ) ;
95
- }
96
- else
97
- {
23
+ private static async Task < bool > CheckAccessAsyncImpl ( )
24
+ {
25
+ if ( ( int ) Build . VERSION . SdkInt < 29 )
26
+ {
27
+ return await PermissionsHelper . CheckWriteExternalStoragePermission ( default ) ;
28
+ }
29
+ else
30
+ {
31
+ return true ;
32
+ }
33
+ }
34
+
35
+ private static async Task SavePlatformAsyncImpl ( MediaFileType type , Stream sourceStream , string targetFileName )
36
+ {
37
+ var context = Android . App . Application . Context ;
38
+ var contentResolver = context . ContentResolver ?? throw new InvalidOperationException ( "ContentResolver is not set." ) ;
39
+
40
+ var appFolderName = Package . Current . DisplayName ;
41
+ // Ensure folder name is file system safe
42
+ appFolderName = string . Join ( "_" , appFolderName . Split ( Path . GetInvalidFileNameChars ( ) ) ) ;
43
+
44
+ var dateTimeNow = DateTime . Now ;
45
+
46
+ var fileNameWithoutExtension = Path . GetFileNameWithoutExtension ( targetFileName ) ;
47
+ var extension = Path . GetExtension ( targetFileName ) . ToLower ( ) ;
48
+
49
+ using var values = new ContentValues ( ) ;
50
+
51
+ values . Put ( IMediaColumns . DateAdded , GetUnixTimestampInSeconds ( dateTimeNow ) ) ;
52
+ values . Put ( IMediaColumns . Title , fileNameWithoutExtension ) ;
53
+ values . Put ( IMediaColumns . DisplayName , targetFileName ) ;
54
+
55
+ var mimeTypeMap = MimeTypeMap . Singleton ?? throw new InvalidOperationException ( "MimeTypeMap is not set." ) ;
56
+
57
+ var mimeType = mimeTypeMap . GetMimeTypeFromExtension ( extension . Replace ( "." , string . Empty ) ) ;
58
+ if ( ! string . IsNullOrWhiteSpace ( mimeType ) )
59
+ values . Put ( IMediaColumns . MimeType , mimeType ) ;
60
+
61
+ using var externalContentUri = type == MediaFileType . Image
62
+ ? Images . Media . ExternalContentUri
63
+ : Video . Media . ExternalContentUri ;
64
+
65
+ if ( externalContentUri is null )
66
+ {
67
+ throw new InvalidOperationException ( $ "External Content URI for { type } is not available.") ;
68
+ }
69
+
70
+ var relativePath = type == MediaFileType . Image
71
+ ? Environment . DirectoryPictures
72
+ : Environment . DirectoryMovies ;
73
+
74
+ if ( relativePath is null )
75
+ {
76
+ throw new InvalidOperationException ( $ "Relative path for { type } is not available.") ;
77
+ }
78
+
79
+ if ( ( int ) Build . VERSION . SdkInt >= 29 )
80
+ {
81
+ values . Put ( IMediaColumns . RelativePath , Path . Combine ( relativePath , appFolderName ) ) ;
82
+ values . Put ( IMediaColumns . IsPending , true ) ;
83
+
84
+ using var uri = contentResolver . Insert ( externalContentUri , values ) ??
85
+ throw new InvalidOperationException ( "Could not generate new content URI" ) ;
86
+
87
+ using var stream = contentResolver . OpenOutputStream ( uri ) ??
88
+ throw new InvalidOperationException ( "Could not open output stream" ) ;
89
+
90
+ await sourceStream . CopyToAsync ( stream ) ;
91
+ stream . Close ( ) ;
92
+
93
+ values . Put ( IMediaColumns . IsPending , false ) ;
94
+ context . ContentResolver . Update ( uri , values , null , null ) ;
95
+ }
96
+ else
97
+ {
98
98
#pragma warning disable CS0618 // Type or member is obsolete
99
- using var directory = new NativeFile ( Environment . GetExternalStoragePublicDirectory ( relativePath ) , appFolderName ) ;
100
- directory . Mkdirs ( ) ;
99
+ using var directory = new NativeFile ( Environment . GetExternalStoragePublicDirectory ( relativePath ) , appFolderName ) ;
100
+ directory . Mkdirs ( ) ;
101
101
102
- using var file = new NativeFile ( directory , targetFileName ) ;
102
+ using var file = new NativeFile ( directory , targetFileName ) ;
103
103
104
- using var fileOutputStream = System . IO . File . Create ( file . AbsolutePath ) ;
105
- await sourceStream . CopyToAsync ( fileOutputStream ) ;
106
- fileOutputStream . Close ( ) ;
104
+ using var fileOutputStream = System . IO . File . Create ( file . AbsolutePath ) ;
105
+ await sourceStream . CopyToAsync ( fileOutputStream ) ;
106
+ fileOutputStream . Close ( ) ;
107
107
108
- values . Put ( IMediaColumns . Data , file . AbsolutePath ) ;
109
- contentResolver . Insert ( externalContentUri , values ) ;
108
+ values . Put ( IMediaColumns . Data , file . AbsolutePath ) ;
109
+ contentResolver . Insert ( externalContentUri , values ) ;
110
110
111
111
#pragma warning disable CA1422 // Validate platform compatibility
112
- using var mediaScanIntent = new Intent ( Intent . ActionMediaScannerScanFile ) ;
112
+ using var mediaScanIntent = new Intent ( Intent . ActionMediaScannerScanFile ) ;
113
113
#pragma warning restore CA1422 // Validate platform compatibility
114
- mediaScanIntent . SetData ( NativeUri . FromFile ( file ) ) ;
115
- context . SendBroadcast ( mediaScanIntent ) ;
114
+ mediaScanIntent . SetData ( NativeUri . FromFile ( file ) ) ;
115
+ context . SendBroadcast ( mediaScanIntent ) ;
116
116
#pragma warning restore CS0618 // Type or member is obsolete
117
- }
118
- }
117
+ }
118
+ }
119
119
120
- private static long GetUnixTimestampInSeconds ( DateTime current ) => ( long ) GetTimeDifference ( current ) . TotalSeconds ;
120
+ private static long GetUnixTimestampInSeconds ( DateTime current ) => ( long ) GetTimeDifference ( current ) . TotalSeconds ;
121
121
122
- private static TimeSpan GetTimeDifference ( DateTime current ) => current . ToUniversalTime ( ) - DateTime . UnixEpoch ;
122
+ private static TimeSpan GetTimeDifference ( DateTime current ) => current . ToUniversalTime ( ) - DateTime . UnixEpoch ;
123
123
}
124
124
#endif
0 commit comments