20
20
import android .provider .CalendarContract ;
21
21
import android .provider .CalendarContract .Calendars ;
22
22
import android .support .annotation .RequiresApi ;
23
+ import android .support .v4 .provider .DocumentFile ;
23
24
import android .text .TextUtils ;
24
25
import android .util .Log ;
25
26
import android .widget .Toast ;
34
35
import com .larkery .simpleorgsync .lib .Application ;
35
36
import com .larkery .simpleorgsync .lib .FileUtils ;
36
37
38
+ import org .w3c .dom .Document ;
39
+
37
40
import java .io .BufferedReader ;
38
41
import java .io .File ;
39
42
import java .io .FileFilter ;
@@ -61,22 +64,19 @@ public CalSyncAdapter(Context context, boolean autoInitialize) {
61
64
super (context , autoInitialize );
62
65
}
63
66
64
- public static void collectOrgFiles (final File rootFile , final Set <File > output ) {
67
+ public static DocumentFile docFile (final Context con , final String uri ) {
68
+ final Uri _uri = Uri .parse (uri );
69
+ if (_uri .getPath ().startsWith ("/tree" )) {
70
+ return DocumentFile .fromTreeUri (con , _uri );
71
+ } else {
72
+ return DocumentFile .fromSingleUri (con , _uri );
73
+ }
74
+ }
75
+
76
+ public static void collectOrgFiles (DocumentFile rootFile , final Set <DocumentFile > output ) {
65
77
if (rootFile .isDirectory ()) {
66
- final File [] sub = rootFile .listFiles (
67
- new FileFilter () {
68
- @ Override
69
- public boolean accept (File pathname ) {
70
- return pathname .isDirectory () ||
71
- (pathname .isFile () && pathname .getName ().endsWith (".org" ));
72
- }
73
- });
74
- for (final File f : sub ) {
75
- if (f .isDirectory ()) {
76
- collectOrgFiles (f , output );
77
- } else if (f .isFile ()) {
78
- output .add (f );
79
- }
78
+ for (DocumentFile child : rootFile .listFiles ()) {
79
+ collectOrgFiles (child , output );
80
80
}
81
81
} else if (rootFile .isFile () && rootFile .getName ().endsWith (".org" )) {
82
82
output .add (rootFile );
@@ -105,30 +105,30 @@ public void onPerformSync(Account account, Bundle extras, String authority,
105
105
account );
106
106
107
107
// identify / create calendars for all the names
108
- final Set <File > distinctAgendaFiles = new HashSet <>();
109
-
110
- final File agendaRootFile = new File (agendaRoot );
108
+ final Set <DocumentFile > distinctAgendaFiles = new HashSet <>();
111
109
110
+ final DocumentFile agendaRootFile = docFile (getContext (), agendaRoot );
112
111
collectOrgFiles (agendaRootFile , distinctAgendaFiles );
113
- final Map <File , StringBuffer > fileContents = new HashMap <>();
114
- final ListMultimap <File , Heading > headingsByFile = ArrayListMultimap .create ();
112
+ final Map <DocumentFile , StringBuffer > fileContents = new HashMap <>();
113
+ final ListMultimap <DocumentFile , Heading > headingsByFile = ArrayListMultimap .create ();
115
114
final ListMultimap <String , Heading > headingsByCategory = ArrayListMultimap .create ();
116
115
116
+
117
117
// load it all
118
- for (final File f : distinctAgendaFiles ) {
118
+ for (final DocumentFile df : distinctAgendaFiles ) {
119
119
try {
120
- Log .i (TAG , "Parsing" + f );
121
- final StringBuffer sb = readFile (f );
122
- fileContents .put (f , sb );
123
- String category = f .getName ();
120
+ Log .i (TAG , "Parsing" + df );
121
+ final StringBuffer sb = readFile (df . getUri () );
122
+ fileContents .put (df , sb );
123
+ String category = df .getName ();
124
124
if (category .endsWith (".org" )) {
125
125
category = category .substring (0 , category .length () - 4 );
126
126
}
127
127
final List <Heading > headings = OrgParser .parse (sb , TimeZone .getTimeZone ("Europe/London" ), category );
128
- headingsByFile .putAll (f , headings );
129
- Log .i (TAG , f + " contains " + headings .size () + " headings" );
128
+ headingsByFile .putAll (df , headings );
129
+ Log .i (TAG , df + " contains " + headings .size () + " headings" );
130
130
} catch (IOException ex ) {
131
- Log .e (TAG , "Reading " + f , ex );
131
+ Log .e (TAG , "Reading " + df , ex );
132
132
}
133
133
}
134
134
@@ -178,11 +178,11 @@ public void onPerformSync(Account account, Bundle extras, String authority,
178
178
// I think at this point we need to put the new headings into the files
179
179
180
180
boolean foundFile = false ;
181
- for (final File f : distinctAgendaFiles ) {
182
- if (f .getName ().endsWith (".org" )) {
183
- final String c = f .getName ().substring (0 , f .getName ().length () - 4 );
181
+ for (final DocumentFile df : distinctAgendaFiles ) {
182
+ if (df .getName ().endsWith (".org" )) {
183
+ final String c = df .getName ().substring (0 , df .getName ().length () - 4 );
184
184
if (c .equals (category )) {
185
- headingsByFile .putAll (f , newHeadings );
185
+ headingsByFile .putAll (df , newHeadings );
186
186
foundFile = true ;
187
187
break ;
188
188
}
@@ -191,17 +191,19 @@ public void onPerformSync(Account account, Bundle extras, String authority,
191
191
192
192
if (!foundFile ) {
193
193
// need to put headings in a new file or so
194
+
194
195
if (agendaRootFile .isDirectory ()) {
195
- final File categoryFile =
196
- new File (agendaRootFile , category + ".org" );
196
+ final DocumentFile categoryFile =
197
+ agendaRootFile .createFile ("text/plain" ,
198
+ category + ".org" );
197
199
headingsByFile .putAll (categoryFile , newHeadings );
198
200
distinctAgendaFiles .add (categoryFile );
199
201
}
200
202
}
201
203
}
202
204
203
205
// now write each file, one at a time
204
- for (final File file : distinctAgendaFiles ) {
206
+ for (final DocumentFile file : distinctAgendaFiles ) {
205
207
final List <Heading > fileHeadings = headingsByFile .get (file );
206
208
final List <Edit > edits = new ArrayList <>();
207
209
final StringBuffer appends = new StringBuffer ();
@@ -234,7 +236,9 @@ public void onPerformSync(Account account, Bundle extras, String authority,
234
236
}
235
237
try {
236
238
final OutputStreamWriter w = new OutputStreamWriter (
237
- new FileOutputStream (file ),
239
+ getContext ().getContentResolver ().openOutputStream (
240
+ file .getUri ()
241
+ ),
238
242
StandardCharsets .UTF_8 );
239
243
try {
240
244
w .write (newContents .toString ());
@@ -336,31 +340,21 @@ private Uri syncAdapterURI(Uri contentUri, Account account) {
336
340
337
341
private static final long MAX_FILE = 1024 * 1024 * 1024 ;
338
342
339
- private static StringBuffer readFile (File file ) throws IOException {
340
- final long size = file .length ();
341
- if (size < 1 || size > MAX_FILE ) {
342
- Log .w (TAG , file + " has unreasonable size " + size );
343
- return null ;
344
- } else {
345
- final StringBuffer sb = new StringBuffer ((int ) size );
346
-
347
- final BufferedReader isr = new BufferedReader (new InputStreamReader (
348
- new FileInputStream (file ),
349
- StandardCharsets .UTF_8
350
- ));
343
+ private StringBuffer readFile (Uri file ) throws IOException {
344
+ try (final BufferedReader isr = new BufferedReader (new InputStreamReader (
345
+ getContext ().getContentResolver ().openInputStream (file ),
346
+ StandardCharsets .UTF_8
347
+ ))) {
348
+ final StringBuffer sb = new StringBuffer ();
351
349
352
- try {
353
- String line ;
354
-
355
- while (null != (line = isr .readLine ())) {
356
- sb .append (line );
357
- sb .append ("\n " );
358
- }
350
+ String line ;
359
351
360
- return sb ;
361
- } finally {
362
- isr . close ( );
352
+ while ( null != ( line = isr . readLine ())) {
353
+ sb . append ( line );
354
+ sb . append ( " \n " );
363
355
}
356
+
357
+ return sb ;
364
358
}
365
359
}
366
360
0 commit comments