XSAFFile.java 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. package com.datarecovery.master.utils.xfile;
  2. import android.content.Context;
  3. import android.database.Cursor;
  4. import android.net.Uri;
  5. import android.provider.DocumentsContract;
  6. import java.io.File;
  7. import java.io.FileNotFoundException;
  8. import java.io.InputStream;
  9. import java.util.ArrayList;
  10. import java.util.List;
  11. import java.util.Objects;
  12. public class XSAFFile extends BaseXFile {
  13. private final Context context;
  14. private final Uri documentUri;
  15. private final Uri pathUri;
  16. private final String path;
  17. private String mimeType;
  18. private String name;
  19. private boolean exist;
  20. private long size;
  21. private long lastModified;
  22. static String[] queryIds = {
  23. DocumentsContract.Document.COLUMN_MIME_TYPE,
  24. DocumentsContract.Document.COLUMN_DISPLAY_NAME,
  25. DocumentsContract.Document.COLUMN_DOCUMENT_ID,
  26. DocumentsContract.Document.COLUMN_SIZE,
  27. DocumentsContract.Document.COLUMN_LAST_MODIFIED
  28. };
  29. public XSAFFile(Context context, Uri treeRoot, String[] segments) {
  30. this.context = context;
  31. Uri androidDataUri = null;
  32. if (segments == null || segments.length == 0) {
  33. this.pathUri = treeRoot;
  34. } else {
  35. StringBuilder stringBuilder = new StringBuilder(treeRoot.toString());
  36. stringBuilder.append("%3A");
  37. for (int i = 0; i < segments.length; i++) {
  38. stringBuilder.append(Uri.encode(segments[i]));
  39. if (i == 1) {
  40. androidDataUri = Uri.parse(stringBuilder.toString());
  41. }
  42. if (i != segments.length - 1) {
  43. stringBuilder.append("%2F");
  44. }
  45. }
  46. this.pathUri = Uri.parse(stringBuilder.toString());
  47. }
  48. StringBuilder pathBuilder = new StringBuilder(File.separator);
  49. for (String segment : treeRoot.getPathSegments()) {
  50. pathBuilder.append(segment).append(File.separator);
  51. }
  52. if (segments != null && segments.length != 0) {
  53. for (String segment : segments) {
  54. pathBuilder.append(segment).append(File.separator);
  55. }
  56. pathBuilder.deleteCharAt(pathBuilder.length() - 1);
  57. }
  58. this.path = pathBuilder.toString();
  59. String documentId;
  60. if (DocumentsContract.isDocumentUri(context, pathUri)) {
  61. documentId = DocumentsContract.getDocumentId(pathUri);
  62. } else {
  63. documentId = DocumentsContract.getTreeDocumentId(pathUri);
  64. }
  65. this.documentUri = DocumentsContract.buildDocumentUriUsingTree(androidDataUri, documentId);
  66. queryData();
  67. }
  68. public XSAFFile(Context context, Uri treeRoot, List<String> segments) {
  69. this.context = context;
  70. if (segments == null || segments.size() == 0) {
  71. this.pathUri = treeRoot;
  72. } else {
  73. StringBuilder stringBuilder = new StringBuilder(treeRoot.toString());
  74. stringBuilder.append("%3A");
  75. for (int i = 0; i < segments.size(); i++) {
  76. if (i < 2) {
  77. stringBuilder.append(Uri.encode(segments.get(i)));
  78. }
  79. if (i != segments.size() - 1 && i < 1) {
  80. stringBuilder.append("%2F");
  81. }
  82. }
  83. this.pathUri = Uri.parse(stringBuilder.toString());
  84. }
  85. StringBuilder pathBuilder = new StringBuilder(File.separator);
  86. for (String segment : treeRoot.getPathSegments()) {
  87. pathBuilder.append(segment).append(File.separator);
  88. }
  89. if (segments != null && segments.size() != 0) {
  90. for (String segment : segments) {
  91. pathBuilder.append(segment).append(File.separator);
  92. }
  93. pathBuilder.deleteCharAt(pathBuilder.length() - 1);
  94. }
  95. this.path = pathBuilder.toString();
  96. String documentId;
  97. if (DocumentsContract.isDocumentUri(context, pathUri)) {
  98. documentId = DocumentsContract.getDocumentId(pathUri);
  99. } else {
  100. documentId = DocumentsContract.getTreeDocumentId(pathUri);
  101. }
  102. this.documentUri = DocumentsContract.buildDocumentUriUsingTree(pathUri, documentId);
  103. queryData();
  104. }
  105. public XSAFFile(Context context, Uri documentUri) {
  106. this.context = context;
  107. this.documentUri = documentUri;
  108. Uri treeRootUri = DocumentsContract.buildTreeDocumentUri(documentUri.getAuthority(),
  109. DocumentsContract.getDocumentId(documentUri));
  110. StringBuilder pathBuilder = new StringBuilder(File.separator);
  111. List<String> pathSegments = treeRootUri.getPathSegments();
  112. if (pathSegments != null && pathSegments.size() > 0) {
  113. for (String segment : pathSegments) {
  114. pathBuilder.append(segment).append(File.separator);
  115. }
  116. pathBuilder.deleteCharAt(pathBuilder.length() - 1);
  117. }
  118. this.path = pathBuilder.toString();
  119. this.pathUri = treeRootUri;
  120. queryData();
  121. }
  122. private void queryData() {
  123. try (Cursor cursor = context.getContentResolver().query(documentUri, queryIds,
  124. null, null, null)) {
  125. if (cursor != null && cursor.moveToFirst()) {
  126. for (int i = 0; i < queryIds.length; i++) {
  127. if (DocumentsContract.Document.COLUMN_MIME_TYPE.equals(queryIds[i])) {
  128. try {
  129. mimeType = cursor.getString(i);
  130. } catch (Exception ignore) {
  131. }
  132. } else if (DocumentsContract.Document.COLUMN_DISPLAY_NAME.equals(queryIds[i])) {
  133. try {
  134. name = cursor.getString(i);
  135. } catch (Exception ignore) {
  136. }
  137. } else if (DocumentsContract.Document.COLUMN_DOCUMENT_ID.equals(queryIds[i])) {
  138. try {
  139. exist = cursor.getString(i) != null;
  140. } catch (Exception ignore) {
  141. }
  142. } else if (DocumentsContract.Document.COLUMN_SIZE.equals(queryIds[i])) {
  143. try {
  144. size = cursor.getLong(i);
  145. } catch (Exception ignore) {
  146. }
  147. } else if (DocumentsContract.Document.COLUMN_LAST_MODIFIED.equals(queryIds[i])) {
  148. try {
  149. lastModified = cursor.getLong(i);
  150. } catch (Exception ignore) {
  151. }
  152. }
  153. }
  154. }
  155. } catch (Exception ignore) {
  156. }
  157. }
  158. @Override
  159. public String getName() {
  160. return name;
  161. }
  162. @Override
  163. public String getPath() {
  164. return path;
  165. }
  166. @Override
  167. public String getMineType() {
  168. return mimeType;
  169. }
  170. @Override
  171. public Uri getUri() throws Exception {
  172. return documentUri;
  173. }
  174. @Override
  175. public boolean isDirectory() {
  176. return Objects.equals(mimeType, DocumentsContract.Document.MIME_TYPE_DIR);
  177. }
  178. @Override
  179. public XFile[] listFiles() {
  180. Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(documentUri, DocumentsContract.getDocumentId(documentUri));
  181. try (Cursor cursor = context.getContentResolver().query(childrenUri, new String[]{DocumentsContract.Document.COLUMN_DOCUMENT_ID},
  182. null, null, null)) {
  183. ArrayList<XFile> children = new ArrayList<>();
  184. if (cursor != null && cursor.moveToFirst()) {
  185. do {
  186. String documentId = cursor.getString(0);
  187. Uri childUri = DocumentsContract.buildDocumentUriUsingTree(documentUri, documentId);
  188. children.add(new XSAFFile(context, childUri));
  189. } while (cursor.moveToNext());
  190. }
  191. return children.toArray(new XFile[0]);
  192. } catch (Exception e) {
  193. e.printStackTrace();
  194. }
  195. return null;
  196. }
  197. @Override
  198. public boolean exists() {
  199. return exist;
  200. }
  201. @Override
  202. public boolean delete() {
  203. try {
  204. DocumentsContract.deleteDocument(context.getContentResolver(), documentUri);
  205. return true;
  206. } catch (FileNotFoundException e) {
  207. e.printStackTrace();
  208. }
  209. return false;
  210. }
  211. @Override
  212. public long length() {
  213. return size;
  214. }
  215. @Override
  216. public long lastModified() {
  217. return lastModified;
  218. }
  219. @Override
  220. public InputStream newInputStream() throws Exception {
  221. return context.getContentResolver().openInputStream(documentUri);
  222. }
  223. public Uri getPathUri() {
  224. return pathUri;
  225. }
  226. public Uri getDocumentUri() {
  227. return documentUri;
  228. }
  229. private String queryForString(String colum) throws Exception {
  230. try (Cursor cursor = context.getContentResolver().query(documentUri, new String[]{colum},
  231. null, null, null)) {
  232. if (cursor != null && cursor.moveToFirst()) {
  233. return cursor.getString(0);
  234. }
  235. }
  236. return null;
  237. }
  238. private long queryForLong(String colum) throws Exception {
  239. try (Cursor cursor = context.getContentResolver().query(documentUri, new String[]{colum},
  240. null, null, null)) {
  241. if (cursor != null && cursor.moveToFirst()) {
  242. return cursor.getLong(0);
  243. }
  244. }
  245. return 0;
  246. }
  247. }