diff options
| author | Po Lu | 2023-05-14 11:12:54 +0800 |
|---|---|---|
| committer | Po Lu | 2023-05-14 11:12:54 +0800 |
| commit | 841b0e220111869fcaf26468d88c7dd18e3caac1 (patch) | |
| tree | 111f5ef9820ea759325faabc041866cf42cbb2fa /java | |
| parent | 4d4a96b2061a463fced1add3b52beb3398c39810 (diff) | |
| download | emacs-841b0e220111869fcaf26468d88c7dd18e3caac1.tar.gz emacs-841b0e220111869fcaf26468d88c7dd18e3caac1.zip | |
Implement document moving on Android
* java/org/gnu/emacs/EmacsDocumentsProvider.java
(notifyChangeByName): New function.
(queryDocument1): Set FLAG_SUPPORTS_MOVE where necessary.
(moveDocument): Implement new function.
Diffstat (limited to 'java')
| -rw-r--r-- | java/org/gnu/emacs/EmacsDocumentsProvider.java | 114 |
1 files changed, 113 insertions, 1 deletions
diff --git a/java/org/gnu/emacs/EmacsDocumentsProvider.java b/java/org/gnu/emacs/EmacsDocumentsProvider.java index a92a1a5d330..b4ac4624829 100644 --- a/java/org/gnu/emacs/EmacsDocumentsProvider.java +++ b/java/org/gnu/emacs/EmacsDocumentsProvider.java | |||
| @@ -38,7 +38,9 @@ import android.webkit.MimeTypeMap; | |||
| 38 | import android.net.Uri; | 38 | import android.net.Uri; |
| 39 | 39 | ||
| 40 | import java.io.File; | 40 | import java.io.File; |
| 41 | import java.io.FileInputStream; | ||
| 41 | import java.io.FileNotFoundException; | 42 | import java.io.FileNotFoundException; |
| 43 | import java.io.FileOutputStream; | ||
| 42 | import java.io.IOException; | 44 | import java.io.IOException; |
| 43 | 45 | ||
| 44 | /* ``Documents provider''. This allows Emacs's home directory to be | 46 | /* ``Documents provider''. This allows Emacs's home directory to be |
| @@ -155,6 +157,22 @@ public final class EmacsDocumentsProvider extends DocumentsProvider | |||
| 155 | context.getContentResolver ().notifyChange (updatedUri, null); | 157 | context.getContentResolver ().notifyChange (updatedUri, null); |
| 156 | } | 158 | } |
| 157 | 159 | ||
| 160 | /* Inform the system that FILE's contents (or FILE itself) has | ||
| 161 | changed. FILE is a string describing containing the file name of | ||
| 162 | a directory as opposed to a File. */ | ||
| 163 | |||
| 164 | private void | ||
| 165 | notifyChangeByName (String file) | ||
| 166 | { | ||
| 167 | Uri updatedUri; | ||
| 168 | Context context; | ||
| 169 | |||
| 170 | context = getContext (); | ||
| 171 | updatedUri | ||
| 172 | = buildChildDocumentsUri ("org.gnu.emacs", file); | ||
| 173 | context.getContentResolver ().notifyChange (updatedUri, null); | ||
| 174 | } | ||
| 175 | |||
| 158 | /* Return the MIME type of a file FILE. */ | 176 | /* Return the MIME type of a file FILE. */ |
| 159 | 177 | ||
| 160 | private String | 178 | private String |
| @@ -212,6 +230,9 @@ public final class EmacsDocumentsProvider extends DocumentsProvider | |||
| 212 | 230 | ||
| 213 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) | 231 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) |
| 214 | flags |= Document.FLAG_SUPPORTS_RENAME; | 232 | flags |= Document.FLAG_SUPPORTS_RENAME; |
| 233 | |||
| 234 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) | ||
| 235 | flags |= Document.FLAG_SUPPORTS_MOVE; | ||
| 215 | } | 236 | } |
| 216 | } | 237 | } |
| 217 | else if (file.canWrite ()) | 238 | else if (file.canWrite ()) |
| @@ -224,7 +245,10 @@ public final class EmacsDocumentsProvider extends DocumentsProvider | |||
| 224 | flags |= Document.FLAG_SUPPORTS_RENAME; | 245 | flags |= Document.FLAG_SUPPORTS_RENAME; |
| 225 | 246 | ||
| 226 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) | 247 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) |
| 227 | flags |= Document.FLAG_SUPPORTS_REMOVE; | 248 | { |
| 249 | flags |= Document.FLAG_SUPPORTS_REMOVE; | ||
| 250 | flags |= Document.FLAG_SUPPORTS_MOVE; | ||
| 251 | } | ||
| 228 | } | 252 | } |
| 229 | 253 | ||
| 230 | displayName = file.getName (); | 254 | displayName = file.getName (); |
| @@ -460,4 +484,92 @@ public final class EmacsDocumentsProvider extends DocumentsProvider | |||
| 460 | { | 484 | { |
| 461 | return documentId.startsWith (parentDocumentId); | 485 | return documentId.startsWith (parentDocumentId); |
| 462 | } | 486 | } |
| 487 | |||
| 488 | @Override | ||
| 489 | public String | ||
| 490 | moveDocument (String sourceDocumentId, | ||
| 491 | String sourceParentDocumentId, | ||
| 492 | String targetParentDocumentId) | ||
| 493 | throws FileNotFoundException | ||
| 494 | { | ||
| 495 | File file, newName; | ||
| 496 | FileInputStream inputStream; | ||
| 497 | FileOutputStream outputStream; | ||
| 498 | byte buffer[]; | ||
| 499 | int length; | ||
| 500 | |||
| 501 | file = new File (sourceDocumentId); | ||
| 502 | |||
| 503 | /* Now, create the file name of the parent document. */ | ||
| 504 | newName = new File (targetParentDocumentId, | ||
| 505 | file.getName ()); | ||
| 506 | |||
| 507 | /* Try to perform a simple rename, before falling back to | ||
| 508 | copying. */ | ||
| 509 | |||
| 510 | if (file.renameTo (newName)) | ||
| 511 | { | ||
| 512 | notifyChangeByName (file.getParent ()); | ||
| 513 | notifyChangeByName (targetParentDocumentId); | ||
| 514 | return newName.getAbsolutePath (); | ||
| 515 | } | ||
| 516 | |||
| 517 | /* If that doesn't work, create the new file and copy over the old | ||
| 518 | file's contents. */ | ||
| 519 | |||
| 520 | inputStream = null; | ||
| 521 | outputStream = null; | ||
| 522 | |||
| 523 | try | ||
| 524 | { | ||
| 525 | if (!newName.createNewFile () | ||
| 526 | || !newName.setWritable (true) | ||
| 527 | || !newName.setReadable (true)) | ||
| 528 | throw new FileNotFoundException ("failed to create new file"); | ||
| 529 | |||
| 530 | /* Open the file in preparation for a copy. */ | ||
| 531 | |||
| 532 | inputStream = new FileInputStream (file); | ||
| 533 | outputStream = new FileOutputStream (newName); | ||
| 534 | |||
| 535 | /* Allocate the buffer used to hold data. */ | ||
| 536 | |||
| 537 | buffer = new byte[4096]; | ||
| 538 | |||
| 539 | while ((length = inputStream.read (buffer)) > 0) | ||
| 540 | outputStream.write (buffer, 0, length); | ||
| 541 | } | ||
| 542 | catch (IOException e) | ||
| 543 | { | ||
| 544 | throw new FileNotFoundException ("IOException: " + e); | ||
| 545 | } | ||
| 546 | finally | ||
| 547 | { | ||
| 548 | try | ||
| 549 | { | ||
| 550 | if (inputStream != null) | ||
| 551 | inputStream.close (); | ||
| 552 | } | ||
| 553 | catch (IOException e) | ||
| 554 | { | ||
| 555 | |||
| 556 | } | ||
| 557 | |||
| 558 | try | ||
| 559 | { | ||
| 560 | if (outputStream != null) | ||
| 561 | outputStream.close (); | ||
| 562 | } | ||
| 563 | catch (IOException e) | ||
| 564 | { | ||
| 565 | |||
| 566 | } | ||
| 567 | } | ||
| 568 | |||
| 569 | file.delete (); | ||
| 570 | notifyChangeByName (file.getParent ()); | ||
| 571 | notifyChangeByName (targetParentDocumentId); | ||
| 572 | |||
| 573 | return newName.getAbsolutePath (); | ||
| 574 | } | ||
| 463 | } | 575 | } |