Browse Source

No more scanning

renovate/org.robolectric-robolectric-4.x
Ammar Githam 4 years ago
parent
commit
ef847321dc
  1. 25
      app/src/main/java/awais/instagrabber/activities/CameraActivity.java
  2. 7
      app/src/main/java/awais/instagrabber/fragments/imageedit/ImageEditFragment.java
  3. 21
      app/src/main/java/awais/instagrabber/utils/MediaUtils.java
  4. 124
      app/src/main/java/awais/instagrabber/utils/Utils.java
  5. 19
      app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.java
  6. 5
      app/src/main/java/awais/instagrabber/workers/DownloadWorker.java

25
app/src/main/java/awais/instagrabber/activities/CameraActivity.java

@ -22,7 +22,6 @@ import androidx.documentfile.provider.DocumentFile;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -115,7 +114,7 @@ public class CameraActivity extends BaseLanguageActivity {
binding.cameraCaptureButton.setOnClickListener(v -> { binding.cameraCaptureButton.setOnClickListener(v -> {
try { try {
takePhoto(); takePhoto();
} catch (FileNotFoundException e) {
} catch (IOException e) {
Log.e(TAG, "updateUi: ", e); Log.e(TAG, "updateUi: ", e);
} }
}); });
@ -205,14 +204,19 @@ public class CameraActivity extends BaseLanguageActivity {
preview.setSurfaceProvider(binding.viewFinder.getSurfaceProvider()); preview.setSurfaceProvider(binding.viewFinder.getSurfaceProvider());
} }
private void takePhoto() throws FileNotFoundException {
private void takePhoto() throws IOException {
if (imageCapture == null) return; if (imageCapture == null) return;
final String extension = "jpg"; final String extension = "jpg";
final String fileName = SIMPLE_DATE_FORMAT.format(System.currentTimeMillis()) + "." + extension; final String fileName = SIMPLE_DATE_FORMAT.format(System.currentTimeMillis()) + "." + extension;
// final File photoFile = new File(outputDirectory, fileName); // final File photoFile = new File(outputDirectory, fileName);
final String mimeType = Utils.mimeTypeMap.getMimeTypeFromExtension(extension);
final String mimeType = "image/jpg";
final DocumentFile photoFile = outputDirectory.createFile(mimeType, fileName); final DocumentFile photoFile = outputDirectory.createFile(mimeType, fileName);
if (photoFile == null) {
Log.e(TAG, "takePhoto: photoFile is null!");
return;
}
final OutputStream outputStream = getContentResolver().openOutputStream(photoFile.getUri()); final OutputStream outputStream = getContentResolver().openOutputStream(photoFile.getUri());
if (outputStream == null) return;
final ImageCapture.OutputFileOptions outputFileOptions = new ImageCapture.OutputFileOptions.Builder(outputStream).build(); final ImageCapture.OutputFileOptions outputFileOptions = new ImageCapture.OutputFileOptions.Builder(outputStream).build();
imageCapture.takePicture( imageCapture.takePicture(
outputFileOptions, outputFileOptions,
@ -220,31 +224,20 @@ public class CameraActivity extends BaseLanguageActivity {
new ImageCapture.OnImageSavedCallback() { new ImageCapture.OnImageSavedCallback() {
@Override @Override
public void onImageSaved(@NonNull final ImageCapture.OutputFileResults outputFileResults) { public void onImageSaved(@NonNull final ImageCapture.OutputFileResults outputFileResults) {
if (outputStream != null) {
try { outputStream.close(); } catch (IOException ignored) {} try { outputStream.close(); } catch (IOException ignored) {}
}
// final Uri uri = Uri.fromFile(photoFile);
// final String mimeType = MimeTypeMap.getSingleton()
// .getMimeTypeFromExtension(Files.getFileExtension(photoFile.getName()));
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, photoFile.getUri()));
Utils.scanDocumentFile(CameraActivity.this, photoFile, (path, uri1) -> {
Log.d(TAG, "onImageSaved: scan complete");
final Intent intent = new Intent(); final Intent intent = new Intent();
intent.setData(uri1);
intent.setData(photoFile.getUri());
setResult(Activity.RESULT_OK, intent); setResult(Activity.RESULT_OK, intent);
finish(); finish();
});
Log.d(TAG, "onImageSaved: " + photoFile.getUri()); Log.d(TAG, "onImageSaved: " + photoFile.getUri());
} }
@Override @Override
public void onError(@NonNull final ImageCaptureException exception) { public void onError(@NonNull final ImageCaptureException exception) {
Log.e(TAG, "onError: ", exception); Log.e(TAG, "onError: ", exception);
if (outputStream != null) {
try { outputStream.close(); } catch (IOException ignored) {} try { outputStream.close(); } catch (IOException ignored) {}
} }
} }
}
); );
// We can only change the foreground Drawable using API level 23+ API // We can only change the foreground Drawable using API level 23+ API
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

7
app/src/main/java/awais/instagrabber/fragments/imageedit/ImageEditFragment.java

@ -34,7 +34,6 @@ import com.yalantis.ucrop.UCropActivity;
import com.yalantis.ucrop.UCropFragment; import com.yalantis.ucrop.UCropFragment;
import com.yalantis.ucrop.UCropFragmentCallback; import com.yalantis.ucrop.UCropFragmentCallback;
import java.io.File;
import java.util.List; import java.util.List;
import awais.instagrabber.R; import awais.instagrabber.R;
@ -42,7 +41,6 @@ import awais.instagrabber.databinding.FragmentImageEditBinding;
import awais.instagrabber.fragments.imageedit.filters.filters.Filter; import awais.instagrabber.fragments.imageedit.filters.filters.Filter;
import awais.instagrabber.models.SavedImageEditState; import awais.instagrabber.models.SavedImageEditState;
import awais.instagrabber.utils.AppExecutors; import awais.instagrabber.utils.AppExecutors;
import awais.instagrabber.utils.Utils;
import awais.instagrabber.viewmodels.ImageEditViewModel; import awais.instagrabber.viewmodels.ImageEditViewModel;
public class ImageEditFragment extends Fragment { public class ImageEditFragment extends Fragment {
@ -183,11 +181,12 @@ public class ImageEditFragment extends Fragment {
if (context == null) return; if (context == null) return;
final Uri resultUri = viewModel.getResultUri().getValue(); final Uri resultUri = viewModel.getResultUri().getValue();
if (resultUri == null) return; if (resultUri == null) return;
Utils.mediaScanFile(context, new File(resultUri.toString()), (path, uri) -> AppExecutors.getInstance().mainThread().execute(() -> {
AppExecutors.getInstance().mainThread().execute(() -> {
final NavController navController = NavHostFragment.findNavController(this); final NavController navController = NavHostFragment.findNavController(this);
setNavControllerResult(navController, resultUri); setNavControllerResult(navController, resultUri);
navController.navigateUp(); navController.navigateUp();
}));
});
// Utils.mediaScanFile(context, new File(resultUri.toString()), (path, uri) -> );
}); });
} }

21
app/src/main/java/awais/instagrabber/utils/MediaUtils.java

@ -32,9 +32,7 @@ public final class MediaUtils {
AppExecutors.getInstance().tasksThread().submit(() -> { AppExecutors.getInstance().tasksThread().submit(() -> {
try (Cursor cursor = MediaStore.Video.query(contentResolver, uri, PROJECTION_VIDEO)) { try (Cursor cursor = MediaStore.Video.query(contentResolver, uri, PROJECTION_VIDEO)) {
if (cursor == null) { if (cursor == null) {
if (listener != null) {
listener.onLoad(null); listener.onLoad(null);
}
return; return;
} }
int durationColumn = cursor.getColumnIndex(MediaStore.Video.Media.DURATION); int durationColumn = cursor.getColumnIndex(MediaStore.Video.Media.DURATION);
@ -42,7 +40,6 @@ public final class MediaUtils {
int heightColumn = cursor.getColumnIndex(MediaStore.Video.Media.HEIGHT); int heightColumn = cursor.getColumnIndex(MediaStore.Video.Media.HEIGHT);
int sizeColumn = cursor.getColumnIndex(MediaStore.Video.Media.SIZE); int sizeColumn = cursor.getColumnIndex(MediaStore.Video.Media.SIZE);
if (cursor.moveToNext()) { if (cursor.moveToNext()) {
if (listener != null) {
listener.onLoad(new VideoInfo( listener.onLoad(new VideoInfo(
cursor.getLong(durationColumn), cursor.getLong(durationColumn),
cursor.getInt(widthColumn), cursor.getInt(widthColumn),
@ -50,17 +47,10 @@ public final class MediaUtils {
cursor.getLong(sizeColumn) cursor.getLong(sizeColumn)
)); ));
} }
}
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG, "getVideoInfo: ", e); Log.e(TAG, "getVideoInfo: ", e);
if (listener != null) {
listener.onFailure(e); listener.onFailure(e);
} }
return;
}
if (listener != null) {
listener.onLoad(null);
}
}); });
} }
@ -69,24 +59,25 @@ public final class MediaUtils {
@NonNull final OnInfoLoadListener<VideoInfo> listener) { @NonNull final OnInfoLoadListener<VideoInfo> listener) {
AppExecutors.getInstance().tasksThread().submit(() -> { AppExecutors.getInstance().tasksThread().submit(() -> {
try (ParcelFileDescriptor parcelFileDescriptor = contentResolver.openFileDescriptor(uri, "r")) { try (ParcelFileDescriptor parcelFileDescriptor = contentResolver.openFileDescriptor(uri, "r")) {
if (parcelFileDescriptor == null) {
listener.onLoad(null);
return;
}
final FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); final FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
final MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever(); final MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(fileDescriptor); mediaMetadataRetriever.setDataSource(fileDescriptor);
final String duration = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
if (listener != null) {
String duration = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
if (TextUtils.isEmpty(duration)) duration = "0";
listener.onLoad(new VideoInfo( listener.onLoad(new VideoInfo(
Long.parseLong(duration), Long.parseLong(duration),
0, 0,
0, 0,
0 0
)); ));
}
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG, "getVoiceInfo: ", e); Log.e(TAG, "getVoiceInfo: ", e);
if (listener != null) {
listener.onFailure(e); listener.onFailure(e);
} }
}
}); });
} }

124
app/src/main/java/awais/instagrabber/utils/Utils.java

@ -12,8 +12,6 @@ import android.content.res.TypedArray;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.OnScanCompletedListener;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Environment; import android.os.Environment;
@ -36,7 +34,6 @@ import android.widget.Toast;
import androidx.annotation.DrawableRes; import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
@ -48,7 +45,6 @@ import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvicto
import com.google.android.exoplayer2.upstream.cache.SimpleCache; import com.google.android.exoplayer2.upstream.cache.SimpleCache;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.Ordering; import com.google.common.collect.Ordering;
import com.google.common.io.Files;
import org.json.JSONObject; import org.json.JSONObject;
@ -340,18 +336,18 @@ public final class Utils {
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
} }
public static void mediaScanFile(@NonNull final Context context,
@NonNull File file,
@NonNull final OnScanCompletedListener callback) {
//noinspection UnstableApiUsage
final String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(Files.getFileExtension(file.getName()));
MediaScannerConnection.scanFile(
context,
new String[]{file.getAbsolutePath()},
new String[]{mimeType},
callback
);
}
// public static void mediaScanFile(@NonNull final Context context,
// @NonNull File file,
// @NonNull final OnScanCompletedListener callback) {
// //noinspection UnstableApiUsage
// final String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(Files.getFileExtension(file.getName()));
// MediaScannerConnection.scanFile(
// context,
// new String[]{file.getAbsolutePath()},
// new String[]{mimeType},
// callback
// );
// }
public static void hideKeyboard(final View view) { public static void hideKeyboard(final View view) {
if (view == null) return; if (view == null) return;
@ -506,26 +502,26 @@ public final class Utils {
return tabOrderString.contains(navRootString); return tabOrderString.contains(navRootString);
} }
public static void scanDocumentFile(@NonNull final Context context,
@NonNull final DocumentFile documentFile,
@NonNull final OnScanCompletedListener callback) {
if (!documentFile.isFile() || !documentFile.exists()) {
Log.d(TAG, "scanDocumentFile: " + documentFile);
callback.onScanCompleted(null, null);
return;
}
File file = null;
try {
file = getDocumentFileRealPath(context, documentFile);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
Log.e(TAG, "scanDocumentFile: ", e);
}
if (file == null) return;
MediaScannerConnection.scanFile(context,
new String[]{file.getAbsolutePath()},
new String[]{documentFile.getType()},
callback);
}
// public static void scanDocumentFile(@NonNull final Context context,
// @NonNull final DocumentFile documentFile,
// @NonNull final OnScanCompletedListener callback) {
// if (!documentFile.isFile() || !documentFile.exists()) {
// Log.d(TAG, "scanDocumentFile: " + documentFile);
// callback.onScanCompleted(null, null);
// return;
// }
// File file = null;
// try {
// file = getDocumentFileRealPath(context, documentFile);
// } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
// Log.e(TAG, "scanDocumentFile: ", e);
// }
// if (file == null) return;
// MediaScannerConnection.scanFile(context,
// new String[]{file.getAbsolutePath()},
// new String[]{documentFile.getType()},
// callback);
// }
public static File getDocumentFileRealPath(@NonNull final Context context, public static File getDocumentFileRealPath(@NonNull final Context context,
@NonNull final DocumentFile documentFile) @NonNull final DocumentFile documentFile)
@ -572,60 +568,4 @@ public final class Utils {
// re-init DownloadUtils // re-init DownloadUtils
DownloadUtils.init(context); DownloadUtils.init(context);
} }
/**
* Ing.N.Nyerges 2019 V2.0
* <p>
* Storage Access Framework(SAF) Uri's creator from File (java.IO),
* for removable external storages
*
* @param context Application Context
* @param file File path + file name
* @return Uri[]:
* uri[0] = SAF TREE Uri
* uri[1] = SAF DOCUMENT Uri
*/
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public static Uri[] getSafUris(Context context, File file) {
Uri[] uri = new Uri[2];
String scheme = "content";
String authority = "com.android.externalstorage.documents";
// Separate each element of the File path
// File format: "/storage/XXXX-XXXX/sub-folder1/sub-folder2..../filename"
// (XXXX-XXXX is external removable number
String[] ele = file.getPath().split(File.separator);
// ele[0] = not used (empty)
// ele[1] = not used (storage name)
// ele[2] = storage number
// ele[3 to (n-1)] = folders
// ele[n] = file name
// Construct folders strings using SAF format
StringBuilder folders = new StringBuilder();
if (ele.length > 4) {
folders.append(ele[3]);
for (int i = 4; i < ele.length - 1; ++i) folders.append("%2F").append(ele[i]);
}
String common = ele[2] + "%3A" + folders.toString();
// Construct TREE Uri
Uri.Builder builder = new Uri.Builder();
builder.scheme(scheme);
builder.authority(authority);
builder.encodedPath("/tree/" + common);
uri[0] = builder.build();
// Construct DOCUMENT Uri
builder = new Uri.Builder();
builder.scheme(scheme);
builder.authority(authority);
if (ele.length > 4) common = common + "%2F";
builder.encodedPath("/document/" + common + file.getName());
uri[1] = builder.build();
return uri;
}
} }

19
app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.java

@ -3,7 +3,6 @@ package awais.instagrabber.viewmodels;
import android.app.Application; import android.app.Application;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.net.Uri; import android.net.Uri;
import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -37,7 +36,6 @@ import awais.instagrabber.utils.DownloadUtils;
import awais.instagrabber.utils.MediaController; import awais.instagrabber.utils.MediaController;
import awais.instagrabber.utils.MediaUtils; import awais.instagrabber.utils.MediaUtils;
import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.TextUtils;
import awais.instagrabber.utils.Utils;
import awais.instagrabber.utils.VoiceRecorder; import awais.instagrabber.utils.VoiceRecorder;
import static awais.instagrabber.utils.Utils.settingsHelper; import static awais.instagrabber.utils.Utils.settingsHelper;
@ -165,15 +163,7 @@ public class DirectThreadViewModel extends AndroidViewModel {
@Override @Override
public void onComplete(final VoiceRecorder.VoiceRecordingResult result) { public void onComplete(final VoiceRecorder.VoiceRecordingResult result) {
Log.d(TAG, "onComplete: recording complete. Scanning file...");
Utils.scanDocumentFile(application, result.getFile(), (path, uri) -> {
if (uri == null) {
final String msg = "Scan failed!";
Log.e(TAG, msg);
data.postValue(Resource.error(msg, null));
return;
}
Log.d(TAG, "onComplete: scan complete");
// Log.d(TAG, "onComplete: recording complete. Scanning file...");
MediaUtils.getVoiceInfo(contentResolver, result.getFile().getUri(), new MediaUtils.OnInfoLoadListener<MediaUtils.VideoInfo>() { MediaUtils.getVoiceInfo(contentResolver, result.getFile().getUri(), new MediaUtils.OnInfoLoadListener<MediaUtils.VideoInfo>() {
@Override @Override
public void onLoad(@Nullable final MediaUtils.VideoInfo videoInfo) { public void onLoad(@Nullable final MediaUtils.VideoInfo videoInfo) {
@ -182,7 +172,7 @@ public class DirectThreadViewModel extends AndroidViewModel {
result.getFile().getUri(), result.getFile().getUri(),
result.getWaveform(), result.getWaveform(),
result.getSamplingFreq(), result.getSamplingFreq(),
videoInfo == null ? 0 : videoInfo.duration,
videoInfo.duration,
result.getFile().length()); result.getFile().length());
} }
@ -191,13 +181,10 @@ public class DirectThreadViewModel extends AndroidViewModel {
data.postValue(Resource.error(t.getMessage(), null)); data.postValue(Resource.error(t.getMessage(), null));
} }
}); });
});
} }
@Override @Override
public void onCancel() {
}
public void onCancel() {}
}); });
voiceRecorder.startRecording(application); voiceRecorder.startRecording(application);
return data; return data;

5
app/src/main/java/awais/instagrabber/workers/DownloadWorker.java

@ -49,7 +49,6 @@ import awais.instagrabber.services.DeleteImageIntentService;
import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.DownloadUtils; import awais.instagrabber.utils.DownloadUtils;
import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.TextUtils;
import awais.instagrabber.utils.Utils;
import static awais.instagrabber.utils.Constants.DOWNLOAD_CHANNEL_ID; import static awais.instagrabber.utils.Constants.DOWNLOAD_CHANNEL_ID;
import static awais.instagrabber.utils.Constants.NOTIF_GROUP_NAME; import static awais.instagrabber.utils.Constants.NOTIF_GROUP_NAME;
@ -272,8 +271,8 @@ public class DownloadWorker extends Worker {
int count = 1; int count = 1;
for (final DocumentFile filePath : filePaths) { for (final DocumentFile filePath : filePaths) {
// final File file = new File(filePath); // final File file = new File(filePath);
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, filePath.getUri()));
Utils.scanDocumentFile(context, filePath, (path, uri) -> {});
// context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, filePath.getUri()));
// Utils.scanDocumentFile(context, filePath, (path, uri) -> {});
// final Uri uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file); // final Uri uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file);
final ContentResolver contentResolver = context.getContentResolver(); final ContentResolver contentResolver = context.getContentResolver();
Bitmap bitmap = null; Bitmap bitmap = null;

Loading…
Cancel
Save