Skip to content

Commit e9a4290

Browse files
committed
argh android random API changes.
1 parent 9ca1e0a commit e9a4290

File tree

5 files changed

+223
-199
lines changed

5 files changed

+223
-199
lines changed

app/build.gradle

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
apply plugin: 'com.android.application'
22

33
android {
4-
compileSdkVersion 29
4+
compileSdkVersion 30
55
defaultConfig {
66
applicationId "com.larkery.simpleorgsync"
7-
minSdkVersion 29
8-
targetSdkVersion 29
7+
minSdkVersion 30
8+
targetSdkVersion 30
99
versionCode 1
1010
versionName "1.0"
1111
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

app/src/main/java/com/larkery/simpleorgsync/PrefsActivity.java

+39-4
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,18 @@
1212
import android.preference.Preference;
1313
import android.preference.PreferenceFragment;
1414
import android.support.annotation.Nullable;
15+
import android.util.Log;
1516
import android.widget.Toast;
1617

1718
import com.larkery.simpleorgsync.lib.Application;
1819
import com.larkery.simpleorgsync.lib.FileUtils;
1920

21+
import java.io.BufferedInputStream;
22+
import java.io.File;
23+
import java.io.FileInputStream;
24+
import java.io.FileNotFoundException;
25+
import java.io.IOException;
26+
import java.io.InputStream;
2027
import java.text.DateFormat;
2128
import java.text.SimpleDateFormat;
2229
import java.util.Date;
@@ -103,8 +110,16 @@ public boolean onPreferenceClick(Preference preference) {
103110
"How is your agenda stored?",
104111
new String[] {"In a single file", "In a directory of files"},
105112
new Intent[] {
106-
new Intent(Intent.ACTION_OPEN_DOCUMENT).setType("*/*"),
113+
new Intent(Intent.ACTION_OPEN_DOCUMENT).setType("*/*")
114+
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION |
115+
Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
116+
Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION |
117+
Intent.FLAG_GRANT_PREFIX_URI_PERMISSION),
107118
new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
119+
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION |
120+
Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
121+
Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION |
122+
Intent.FLAG_GRANT_PREFIX_URI_PERMISSION)
108123
},
109124
new int[] {SELECT_AGENDA_FILE, SELECT_AGENDA_DIRECTORY},
110125
OrgPreferenceFragment.this
@@ -118,6 +133,10 @@ public boolean onPreferenceClick(Preference preference) {
118133
public boolean onPreferenceClick(Preference preference) {
119134
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
120135
intent.setType("*/*");
136+
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION |
137+
Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
138+
Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION |
139+
Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
121140
startActivityForResult(intent, SELECT_CONTACTS_FILE);
122141
return true;
123142
}
@@ -155,18 +174,34 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
155174
super.onActivityResult(requestCode, resultCode, data);
156175
String path = null;
157176
String pref = null;
177+
Log.i("ORGSYNC/PREF", "got uri " + data.getData());
158178
switch (requestCode) {
159179
case SELECT_AGENDA_FILE:
160-
path = FileUtils.getFilePathFromUri(getContext(), data.getData());
180+
getContext().getContentResolver().takePersistableUriPermission(
181+
data.getData(),
182+
Intent.FLAG_GRANT_READ_URI_PERMISSION |
183+
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
184+
);
185+
path = data.getData().toString();
161186
pref = "agenda_files";
162187
break;
163188
case SELECT_AGENDA_DIRECTORY:
164-
path = FileUtils.getDirectoryPathFromUri(getContext(), data.getData());
189+
getContext().getContentResolver().takePersistableUriPermission(
190+
data.getData(),
191+
Intent.FLAG_GRANT_READ_URI_PERMISSION |
192+
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
193+
);
194+
path = data.getData().toString();
165195
pref = "agenda_files";
166196
break;
167197
case SELECT_CONTACTS_FILE:
198+
getContext().getContentResolver().takePersistableUriPermission(
199+
data.getData(),
200+
Intent.FLAG_GRANT_READ_URI_PERMISSION |
201+
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
202+
);
168203
pref = "contacts_file";
169-
path = FileUtils.getFilePathFromUri(getContext(), data.getData());
204+
path = data.getData().toString();
170205
break;
171206
}
172207
if (pref != null && path != null) {

app/src/main/java/com/larkery/simpleorgsync/cal/CalSyncAdapter.java

+52-58
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import android.provider.CalendarContract;
2121
import android.provider.CalendarContract.Calendars;
2222
import android.support.annotation.RequiresApi;
23+
import android.support.v4.provider.DocumentFile;
2324
import android.text.TextUtils;
2425
import android.util.Log;
2526
import android.widget.Toast;
@@ -34,6 +35,8 @@
3435
import com.larkery.simpleorgsync.lib.Application;
3536
import com.larkery.simpleorgsync.lib.FileUtils;
3637

38+
import org.w3c.dom.Document;
39+
3740
import java.io.BufferedReader;
3841
import java.io.File;
3942
import java.io.FileFilter;
@@ -61,22 +64,19 @@ public CalSyncAdapter(Context context, boolean autoInitialize) {
6164
super(context, autoInitialize);
6265
}
6366

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) {
6577
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);
8080
}
8181
} else if (rootFile.isFile() && rootFile.getName().endsWith(".org")) {
8282
output.add(rootFile);
@@ -105,30 +105,30 @@ public void onPerformSync(Account account, Bundle extras, String authority,
105105
account);
106106

107107
// 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<>();
111109

110+
final DocumentFile agendaRootFile = docFile(getContext(), agendaRoot);
112111
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();
115114
final ListMultimap<String, Heading> headingsByCategory = ArrayListMultimap.create();
116115

116+
117117
// load it all
118-
for (final File f : distinctAgendaFiles) {
118+
for (final DocumentFile df : distinctAgendaFiles) {
119119
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();
124124
if (category.endsWith(".org")) {
125125
category = category.substring(0, category.length() - 4);
126126
}
127127
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");
130130
} catch (IOException ex) {
131-
Log.e(TAG, "Reading " + f, ex);
131+
Log.e(TAG, "Reading " + df, ex);
132132
}
133133
}
134134

@@ -178,11 +178,11 @@ public void onPerformSync(Account account, Bundle extras, String authority,
178178
// I think at this point we need to put the new headings into the files
179179

180180
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);
184184
if (c.equals(category)) {
185-
headingsByFile.putAll(f, newHeadings);
185+
headingsByFile.putAll(df, newHeadings);
186186
foundFile = true;
187187
break;
188188
}
@@ -191,17 +191,19 @@ public void onPerformSync(Account account, Bundle extras, String authority,
191191

192192
if (!foundFile) {
193193
// need to put headings in a new file or so
194+
194195
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");
197199
headingsByFile.putAll(categoryFile, newHeadings);
198200
distinctAgendaFiles.add(categoryFile);
199201
}
200202
}
201203
}
202204

203205
// now write each file, one at a time
204-
for (final File file : distinctAgendaFiles) {
206+
for (final DocumentFile file : distinctAgendaFiles) {
205207
final List<Heading> fileHeadings = headingsByFile.get(file);
206208
final List<Edit> edits = new ArrayList<>();
207209
final StringBuffer appends = new StringBuffer();
@@ -234,7 +236,9 @@ public void onPerformSync(Account account, Bundle extras, String authority,
234236
}
235237
try {
236238
final OutputStreamWriter w = new OutputStreamWriter(
237-
new FileOutputStream(file),
239+
getContext().getContentResolver().openOutputStream(
240+
file.getUri()
241+
),
238242
StandardCharsets.UTF_8);
239243
try {
240244
w.write(newContents.toString());
@@ -336,31 +340,21 @@ private Uri syncAdapterURI(Uri contentUri, Account account) {
336340

337341
private static final long MAX_FILE = 1024 * 1024 * 1024;
338342

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();
351349

352-
try {
353-
String line;
354-
355-
while (null != (line = isr.readLine())) {
356-
sb.append(line);
357-
sb.append("\n");
358-
}
350+
String line;
359351

360-
return sb;
361-
} finally {
362-
isr.close();
352+
while (null != (line = isr.readLine())) {
353+
sb.append(line);
354+
sb.append("\n");
363355
}
356+
357+
return sb;
364358
}
365359
}
366360

0 commit comments

Comments
 (0)