That fuck shit the fascists are using
at master 577 lines 21 kB view raw
1package org.archiver; 2 3import android.Manifest; 4import android.content.ContentResolver; 5import android.content.ContentUris; 6import android.content.Context; 7import android.content.pm.PackageManager; 8import android.database.Cursor; 9import android.net.Uri; 10import android.os.Build; 11import android.os.Environment; 12import android.provider.DocumentsContract; 13import android.provider.MediaStore; 14import android.webkit.MimeTypeMap; 15 16import com.tm.logger.Log; 17 18import org.jetbrains.annotations.Nullable; 19import org.tm.archive.attachments.Attachment; 20import org.tm.archive.attachments.AttachmentId; 21import org.tm.archive.attachments.DatabaseAttachment; 22import org.tm.archive.contactshare.Contact; 23import org.tm.archive.database.SignalDatabase; 24import org.tm.archive.dependencies.ApplicationDependencies; 25import org.tm.archive.providers.BlobProvider; 26 27import java.io.File; 28import java.io.FileNotFoundException; 29import java.io.FileOutputStream; 30import java.io.FileWriter; 31import java.io.IOException; 32import java.io.InputStream; 33import java.io.OutputStream; 34import java.util.Random; 35 36public class ArchiveFileUtil { 37 38 39 public static String getPath(Context context, Uri uri){ 40 String[] projection = {MediaStore.MediaColumns.DATA}; 41 String path = ""; 42 ContentResolver cr = context.getApplicationContext().getContentResolver(); 43 Cursor metaCursor = cr.query(uri, projection, null, null, null); 44 if (metaCursor != null) { 45 try { 46 if (metaCursor.moveToFirst()) { 47 path = metaCursor.getString(0); 48 } 49 } finally { 50 metaCursor.close(); 51 } 52 } 53 return path; 54 } 55 56 /* 57This method can parse out the real local file path from a file URI. 58*/ 59 public static String getUriRealPath(Context ctx, Uri uri) 60 { 61 String ret = ""; 62 63 if( isAboveKitKat() ) 64 { 65 // Android sdk version number bigger than 19. 66 ret = getUriRealPathAboveKitkat(ctx, uri); 67 }else 68 { 69 // Android sdk version number smaller than 19. 70 ret = getImageRealPath(ctx.getContentResolver(), uri, null); 71 } 72 73 return ret; 74 } 75 76 /* 77 This method will parse out the real local file path from the file content URI. 78 The method is only applied to android sdk version number that is bigger than 19. 79 */ 80 public static String getUriRealPathAboveKitkat(Context ctx, Uri uri) 81 { 82 String ret = ""; 83 84 if(ctx != null && uri != null) { 85 86 if(isContentUri(uri)) 87 { 88 if(isGooglePhotoDoc(uri.getAuthority())) 89 { 90 ret = uri.getLastPathSegment(); 91 }else { 92 ret = getImageRealPath(ctx.getContentResolver(), uri, null); 93 } 94 }else if(isFileUri(uri)) { 95 ret = uri.getPath(); 96 }else if(isDocumentUri(ctx, uri)){ 97 98 // Get uri related document id. 99 String documentId = DocumentsContract.getDocumentId(uri); 100 101 // Get uri authority. 102 String uriAuthority = uri.getAuthority(); 103 104 if(isMediaDoc(uriAuthority)) 105 { 106 String idArr[] = documentId.split(":"); 107 if(idArr.length == 2) 108 { 109 // First item is document type. 110 String docType = idArr[0]; 111 112 // Second item is document real id. 113 String realDocId = idArr[1]; 114 115 // Get content uri by document type. 116 Uri mediaContentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; 117 if("image".equals(docType)) 118 { 119 mediaContentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; 120 }else if("video".equals(docType)) 121 { 122 mediaContentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; 123 }else if("audio".equals(docType)) 124 { 125 mediaContentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 126 } 127 128 // Get where clause with real document id. 129 String whereClause = MediaStore.Images.Media._ID + " = " + realDocId; 130 131 ret = getImageRealPath(ctx.getContentResolver(), mediaContentUri, whereClause); 132 } 133 134 }else if(isDownloadDoc(uriAuthority)) 135 { 136 // Build download uri. 137 Uri downloadUri = Uri.parse("content://downloads/public_downloads"); 138 139 // Append download document id at uri end. 140 Uri downloadUriAppendId = ContentUris.withAppendedId(downloadUri, Long.valueOf(documentId)); 141 142 ret = getImageRealPath(ctx.getContentResolver(), downloadUriAppendId, null); 143 144 }else if(isExternalStoreDoc(uriAuthority)) 145 { 146 String idArr[] = documentId.split(":"); 147 if(idArr.length == 2) 148 { 149 String type = idArr[0]; 150 String realDocId = idArr[1]; 151 152 if("primary".equalsIgnoreCase(type)) 153 { 154 ret = Environment.getExternalStorageDirectory() + "/" + realDocId; 155 } 156 } 157 } 158 } 159 } 160 161 return ret; 162 } 163 164 /* Check whether current android os version is bigger than kitkat or not. */ 165 public static boolean isAboveKitKat() 166 { 167 boolean ret = false; 168 ret = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; 169 return ret; 170 } 171 172 /* Check whether this uri represent a document or not. */ 173 public static boolean isDocumentUri(Context ctx, Uri uri) 174 { 175 boolean ret = false; 176 if(ctx != null && uri != null) { 177 ret = DocumentsContract.isDocumentUri(ctx, uri); 178 } 179 return ret; 180 } 181 182 /* Check whether this uri is a content uri or not. 183 * content uri like content://media/external/images/media/1302716 184 * */ 185 public static boolean isContentUri(Uri uri) 186 { 187 boolean ret = false; 188 if(uri != null) { 189 String uriSchema = uri.getScheme(); 190 if("content".equalsIgnoreCase(uriSchema)) 191 { 192 ret = true; 193 } 194 } 195 return ret; 196 } 197 198 /* Check whether this uri is a file uri or not. 199 * file uri like file:///storage/41B7-12F1/DCIM/Camera/IMG_20180211_095139.jpg 200 * */ 201 public static boolean isFileUri(Uri uri) 202 { 203 boolean ret = false; 204 if(uri != null) { 205 String uriSchema = uri.getScheme(); 206 if("file".equalsIgnoreCase(uriSchema)) 207 { 208 ret = true; 209 } 210 } 211 return ret; 212 } 213 214 215 /* Check whether this document is provided by ExternalStorageProvider. Return true means the file is saved in external storage. */ 216 public static boolean isExternalStoreDoc(String uriAuthority) 217 { 218 boolean ret = false; 219 220 if("com.android.externalstorage.documents".equals(uriAuthority)) 221 { 222 ret = true; 223 } 224 225 return ret; 226 } 227 228 /* Check whether this document is provided by DownloadsProvider. return true means this file is a downloaed file. */ 229 public static boolean isDownloadDoc(String uriAuthority) 230 { 231 boolean ret = false; 232 233 if("com.android.providers.downloads.documents".equals(uriAuthority)) 234 { 235 ret = true; 236 } 237 238 return ret; 239 } 240 241 /* 242 Check if MediaProvider provide this document, if true means this image is created in android media app. 243 */ 244 public static boolean isMediaDoc(String uriAuthority) 245 { 246 boolean ret = false; 247 248 if("com.android.providers.media.documents".equals(uriAuthority)) 249 { 250 ret = true; 251 } 252 253 return ret; 254 } 255 256 /* 257 Check whether google photos provide this document, if true means this image is created in google photos app. 258 */ 259 public static boolean isGooglePhotoDoc(String uriAuthority) 260 { 261 boolean ret = false; 262 263 if("com.google.android.apps.photos.content".equals(uriAuthority)) 264 { 265 ret = true; 266 } 267 268 return ret; 269 } 270 271 /* Return uri represented document file real local path.*/ 272 public static String getImageRealPath(ContentResolver contentResolver, Uri uri, String whereClause) 273 { 274 String ret = ""; 275 276 // Query the uri with condition. 277 Cursor cursor = contentResolver.query(uri, null, whereClause, null, null); 278 279 if(cursor!=null) 280 { 281 boolean moveToFirst = cursor.moveToFirst(); 282 if(moveToFirst) 283 { 284 285 // Get columns name by uri type. 286 String columnName = MediaStore.Images.Media.DATA; 287 288 if( uri==MediaStore.Images.Media.EXTERNAL_CONTENT_URI ) 289 { 290 columnName = MediaStore.Images.Media.DATA; 291 }else if( uri==MediaStore.Audio.Media.EXTERNAL_CONTENT_URI ) 292 { 293 columnName = MediaStore.Audio.Media.DATA; 294 }else if( uri==MediaStore.Video.Media.EXTERNAL_CONTENT_URI ) 295 { 296 columnName = MediaStore.Video.Media.DATA; 297 } 298 299 // Get column index. 300 int imageColumnIndex = cursor.getColumnIndex(columnName); 301 302 // Get column value which is the uri related file local path. 303 ret = cursor.getString(imageColumnIndex); 304 } 305 } 306 307 return ret; 308 } 309 310 public static String getRealPath(final Context context, final Uri uri) { 311 final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; 312 313 // DocumentProvider 314 if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { 315 System.out.println("getPath() uri: " + uri.toString()); 316 System.out.println("getPath() uri authority: " + uri.getAuthority()); 317 System.out.println("getPath() uri path: " + uri.getPath()); 318 319 // ExternalStorageProvider 320 if ("com.android.externalstorage.documents".equals(uri.getAuthority())) { 321 final String docId = DocumentsContract.getDocumentId(uri); 322 final String[] split = docId.split(":"); 323 final String type = split[0]; 324 System.out.println("getPath() docId: " + docId + ", split: " + split.length + ", type: " + type); 325 326 // This is for checking Main Memory 327 if ("primary".equalsIgnoreCase(type)) { 328 if (split.length > 1) { 329 return Environment.getExternalStorageDirectory() + "/" + split[1] + "/"; 330 } else { 331 return Environment.getExternalStorageDirectory() + "/"; 332 } 333 // This is for checking SD Card 334 } else { 335 return "storage" + "/" + docId.replace(":", "/"); 336 } 337 338 } 339 } 340 return null; 341 } 342 343 public static void copyInputStreamToFile(InputStream in, File file) { 344 OutputStream out = null; 345 346 try { 347 out = new FileOutputStream(file); 348 byte[] buf = new byte[1024]; 349 int len; 350 while((len=in.read(buf))>0){ 351 out.write(buf,0,len); 352 } 353 } 354 catch (Exception e) { 355 e.printStackTrace(); 356 } 357 finally { 358 // Ensure that the InputStreams are closed even if there's an exception. 359 try { 360 if ( out != null ) { 361 out.close(); 362 } 363 364 // If you want to close the "in" InputStream yourself then remove this 365 // from here but ensure that you close it yourself eventually. 366 in.close(); 367 } 368 catch ( IOException e ) { 369 e.printStackTrace(); 370 } 371 } 372 } 373 374 public static void deleteFile(Context context,String dirName,String fileName){ 375 376 File dir = new File(context.getCacheDir().toString()); 377 if(dir.exists()){ 378 for (File file : dir.listFiles()) { 379 if(file.getName().equalsIgnoreCase(fileName)){ 380 file.delete(); 381 break; 382 } 383 } 384 } 385 } 386 387 public static File createFileFromContentUri(Context context, String contentUri){ 388 File resultFile = null; 389 if(contentUri.contains(ArchiveConstants.SIGNAL_PART_PATH) ) { 390 resultFile = getFileFromDataBaseUri(context, contentUri); 391 }else if(contentUri.contains(ArchiveConstants.SIGNAL_STICKER_PATH)){ 392 resultFile = getStickerFileFromBlobProvider(context, contentUri); 393 }else if(contentUri.contains(ArchiveConstants.SIGNAL_BLOB_PATH)){ 394 resultFile = getFileFromBlobProvider(context, contentUri); 395 }else { 396 resultFile = getFileFromDeviceUri(context, contentUri); 397 } 398 return resultFile; 399 } 400 401 public static File getFileFromDataBaseUri(Context context, String contentUri) { 402 403 String[] splitUri = contentUri.split("/"); 404 int splitLength = splitUri.length; 405// DatabaseAttachment databaseAttachment = SignalDatabase.attachments().getAttachment(new AttachmentId(Long.parseLong(splitUri[splitLength - 1]),Long.parseLong(splitUri[splitLength - 2]))); 406 DatabaseAttachment databaseAttachment = SignalDatabase.attachments().getAttachment(new AttachmentId(Long.parseLong(splitUri[splitLength - 1]))); 407 408 InputStream attachmentInputStream = null; 409 try { 410 attachmentInputStream = SignalDatabase.attachments().getAttachmentStream(databaseAttachment.attachmentId,0); 411 } catch (IOException e) { 412 e.printStackTrace(); 413 } 414 415 String fileName = getFileNameWithType(databaseAttachment.fileName, 0 ,databaseAttachment.attachmentId.id,databaseAttachment.contentType); 416 File resultFile = new File(context.getCacheDir(), fileName); 417 ArchiveFileUtil.copyInputStreamToFile(attachmentInputStream, resultFile); 418 419 return resultFile; 420 } 421 422 public static String getFileType(DatabaseAttachment databaseAttachment) { 423 String fileType; 424 try { 425 fileType = databaseAttachment.fileName.split("\\.")[1]; 426 }catch (Exception e){ 427 fileType = MimeTypeMap.getSingleton().getExtensionFromMimeType(databaseAttachment.contentType); 428 } 429 return fileType; 430 } 431 432 public static String getFileType(String fileName, String contentType) { 433 String fileType; 434 try { 435 if(fileName != null) { 436 fileType = fileName.split("\\.")[fileName.split("\\.").length - 1]; 437 }else{ 438 fileType = MimeTypeMap.getSingleton().getExtensionFromMimeType(contentType); 439 } 440 }catch (Exception e){ 441 fileType = MimeTypeMap.getSingleton().getExtensionFromMimeType(contentType); 442 } 443 return fileType; 444 } 445 446 public static String getFileType(Attachment attachment) { 447 String fileType; 448 try { 449 fileType = attachment.fileName.split("\\.")[1]; 450 }catch (Exception e){ 451 fileType = MimeTypeMap.getSingleton().getExtensionFromMimeType(attachment.contentType); 452 } 453 return fileType; 454 } 455 456 private static File getFileFromBlobProvider(Context context, String contentUri) { 457 File resultFile = null; 458 String fileName = ""; 459 String fileType = MimeTypeMap.getSingleton().getExtensionFromMimeType(context.getContentResolver().getType(Uri.parse(contentUri))); 460 InputStream stream = null; 461 try { 462 stream = BlobProvider.getInstance().getStream(ApplicationDependencies.getApplication(), Uri.parse(contentUri)); 463 } catch (IOException e) { 464 e.printStackTrace(); 465 Log.e("ArchiveFileUtil", "getFileFromBlobProvider -> error getStream!!!!--------------"); 466 return null; 467 } 468 fileName = contentUri.split("/")[contentUri.split("/").length - 1].split("\\.")[0] + "." + fileType; 469 470 resultFile = new File(context.getCacheDir(), fileName); 471 472 ArchiveFileUtil.copyInputStreamToFile(stream, resultFile); 473 474 return resultFile; 475 } 476 477 private static File getStickerFileFromBlobProvider(Context context, String contentUri) { 478 File resultFile = null; 479 String fileName = ""; 480 InputStream stream = null; 481 try { 482 stream = SignalDatabase.stickers().getStickerStream(ContentUris.parseId(Uri.parse(contentUri))); 483 } catch (IOException e) { 484 e.printStackTrace(); 485 } 486 487 fileName = contentUri.split("/")[contentUri.split("/").length - 1].split("\\.")[0] + "." + "webp"; 488 489 resultFile = new File(context.getCacheDir(), fileName); 490 491 ArchiveFileUtil.copyInputStreamToFile(stream, resultFile); 492 493 return resultFile; 494 } 495 496 public static boolean checkWriteExternalPermission(Context context) 497 { 498 String permission = Manifest.permission.READ_EXTERNAL_STORAGE; 499 int res = context.checkCallingOrSelfPermission(permission); 500 return (res == PackageManager.PERMISSION_GRANTED); 501 } 502 503 @Nullable 504 private static File getFileFromDeviceUri(Context context, String contentUri) { 505 if(checkWriteExternalPermission(context)) { 506 File resultFile = null; 507 String fileName = ""; 508 String fileType = MimeTypeMap.getSingleton().getExtensionFromMimeType(context.getContentResolver().getType(Uri.parse(contentUri))); 509 InputStream inputStream = null; 510 511 fileName = contentUri.split("/")[contentUri.split("/").length - 1].split("\\.")[0] + "." + fileType; 512 513 resultFile = new File(context.getCacheDir(), fileName); 514 try { 515 inputStream = context.getContentResolver().openInputStream(Uri.parse(contentUri)); 516 ArchiveFileUtil.copyInputStreamToFile(inputStream, resultFile); 517 518 } catch (Exception e) { 519 e.printStackTrace(); 520 } 521 522 return resultFile; 523 } 524 return null; 525 } 526 527 public static File createVCFFileFromContact(Context context, Contact contact){ 528 529 File vcfFile = new File(context.getCacheDir(), contact.getName().isEmpty()? "contact" : contact.getName().getDisplayName().replaceAll(" ","_") + ".vcf"); 530 FileWriter fw = null; 531 try { 532 fw = new FileWriter(vcfFile); 533 fw.write("BEGIN:VCARD\r\n"); 534 fw.write("VERSION:3.0\r\n"); 535 fw.write("N:" + contact.getName().getFamilyName() + ";" + contact.getName().getGivenName() + "\r\n"); 536 fw.write("FN:" + contact.getName().getGivenName() + " " + contact.getName().getFamilyName() + "\r\n"); 537 if(contact.getOrganization() != null) { 538 fw.write("ORG:" + contact.getOrganization() + "\r\n"); 539 } 540 for (int i = 0; i < contact.getPostalAddresses().size(); i++) { 541 fw.write("TEL;TYPE=WORK,VOICE:" + contact.getPostalAddresses().get(0).getLabel() + "\r\n"); 542 } 543 544 for (int i = 0; i < contact.getPhoneNumbers().size(); i++) { 545 fw.write("TEL;TYPE=WORK,VOICE:" + contact.getPhoneNumbers().get(i).getNumber() + "\r\n"); 546 } 547 548 fw.write("ADR;TYPE=WORK:;;" + contact.getPostalAddresses()+ "\r\n"); 549 for (int i = 0; i < contact.getEmails().size(); i++) { 550 fw.write("EMAIL;TYPE=PREF,INTERNET:" + contact.getEmails().get(i).getEmail() + "\r\n"); 551 } 552 553 fw.write("END:VCARD\r\n"); 554 fw.close(); 555 } catch (IOException e) { 556 e.printStackTrace(); 557 } 558 559 return vcfFile; 560 561 } 562 563 564 public static String getFileNameWithType(String fileName, long messageId, long attachmentId, String contentType) { 565 return getFileNameWithType(fileName, messageId, attachmentId, contentType, false); 566 } 567 568 public static String getFileNameWithType(String fileName, long messageId, long attachmentId, String contentType, boolean isIncoming) { 569 570 if (isIncoming || fileName == null){ 571 return ArchiveUtil.Companion.generateAttachmentName(messageId, attachmentId) + "." + ArchiveFileUtil.getFileType(fileName, contentType); 572 }else{ 573 return fileName.replace(" ", "_"); 574 } 575 } 576 577}