mirror of https://github.com/tasks/tasks
Use third-party app for recording audio notes
parent
b59316db78
commit
47f920e32a
@ -1,92 +0,0 @@
|
|||||||
package com.todoroo.astrid.voice;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.media.MediaRecorder;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.SystemClock;
|
|
||||||
import androidx.lifecycle.ViewModel;
|
|
||||||
import java.io.IOException;
|
|
||||||
import org.tasks.files.FileHelper;
|
|
||||||
import org.tasks.preferences.Preferences;
|
|
||||||
import org.tasks.time.DateTime;
|
|
||||||
import timber.log.Timber;
|
|
||||||
|
|
||||||
@SuppressWarnings({"WeakerAccess", "RedundantSuppression"})
|
|
||||||
public class AACRecorder extends ViewModel {
|
|
||||||
|
|
||||||
private MediaRecorder mediaRecorder;
|
|
||||||
|
|
||||||
private boolean recording;
|
|
||||||
private AACRecorderCallbacks listener;
|
|
||||||
private Preferences preferences;
|
|
||||||
private long base;
|
|
||||||
private Uri uri;
|
|
||||||
|
|
||||||
public synchronized void startRecording(Context context) throws IOException {
|
|
||||||
if (recording) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uri =
|
|
||||||
FileHelper.newFile(
|
|
||||||
context,
|
|
||||||
preferences.getCacheDirectory(),
|
|
||||||
"audio/m4a",
|
|
||||||
new DateTime().toString("yyyyMMddHHmm"),
|
|
||||||
".m4a");
|
|
||||||
|
|
||||||
mediaRecorder = new MediaRecorder();
|
|
||||||
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
|
|
||||||
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
|
|
||||||
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
|
|
||||||
mediaRecorder.setOutputFile(uri.getPath());
|
|
||||||
mediaRecorder.setOnErrorListener(
|
|
||||||
(mr, what, extra) -> Timber.e("mediaRecorder.onError(mr, %s, %s)", what, extra));
|
|
||||||
mediaRecorder.setOnInfoListener(
|
|
||||||
(mr, what, extra) -> Timber.i("mediaRecorder.onInfo(mr, %s, %s)", what, extra));
|
|
||||||
|
|
||||||
try {
|
|
||||||
mediaRecorder.prepare();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
recording = true;
|
|
||||||
base = SystemClock.elapsedRealtime();
|
|
||||||
mediaRecorder.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void stopRecording() {
|
|
||||||
if (!recording) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// media recorder was cutting off end of audio
|
|
||||||
// this is a hack to keep recording
|
|
||||||
Thread.sleep(500);
|
|
||||||
} catch (InterruptedException ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
mediaRecorder.stop();
|
|
||||||
mediaRecorder.release();
|
|
||||||
recording = false;
|
|
||||||
if (listener != null) {
|
|
||||||
listener.encodingFinished(uri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getBase() {
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init(AACRecorderCallbacks listener, Preferences preferences) {
|
|
||||||
this.listener = listener;
|
|
||||||
this.preferences = preferences;
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface AACRecorderCallbacks {
|
|
||||||
|
|
||||||
void encodingFinished(Uri uri);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,120 +0,0 @@
|
|||||||
package org.tasks.dialogs;
|
|
||||||
|
|
||||||
import static android.app.Activity.RESULT_OK;
|
|
||||||
import static org.tasks.PermissionUtil.verifyPermissions;
|
|
||||||
|
|
||||||
import android.app.Dialog;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.widget.Chronometer;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.fragment.app.DialogFragment;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
|
||||||
|
|
||||||
import com.todoroo.astrid.voice.AACRecorder;
|
|
||||||
|
|
||||||
import org.tasks.R;
|
|
||||||
import org.tasks.databinding.AacRecordActivityBinding;
|
|
||||||
import org.tasks.preferences.FragmentPermissionRequestor;
|
|
||||||
import org.tasks.preferences.PermissionChecker;
|
|
||||||
import org.tasks.preferences.PermissionRequestor;
|
|
||||||
import org.tasks.preferences.Preferences;
|
|
||||||
import org.tasks.themes.Theme;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
|
||||||
public class RecordAudioDialog extends DialogFragment implements AACRecorder.AACRecorderCallbacks {
|
|
||||||
|
|
||||||
@Inject Preferences preferences;
|
|
||||||
@Inject DialogBuilder dialogBuilder;
|
|
||||||
@Inject Theme theme;
|
|
||||||
@Inject FragmentPermissionRequestor permissionRequestor;
|
|
||||||
@Inject PermissionChecker permissionChecker;
|
|
||||||
|
|
||||||
private Chronometer timer;
|
|
||||||
private AACRecorder recorder;
|
|
||||||
|
|
||||||
static RecordAudioDialog newRecordAudioDialog(Fragment target, int requestCode) {
|
|
||||||
RecordAudioDialog dialog = new RecordAudioDialog();
|
|
||||||
dialog.setTargetFragment(target, requestCode);
|
|
||||||
return dialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
|
||||||
AacRecordActivityBinding binding =
|
|
||||||
AacRecordActivityBinding.inflate(theme.getLayoutInflater(getContext()));
|
|
||||||
timer = binding.timer;
|
|
||||||
binding.stopRecording.setOnClickListener(v -> stopRecording());
|
|
||||||
recorder = new ViewModelProvider(this).get(AACRecorder.class);
|
|
||||||
recorder.init(this, preferences);
|
|
||||||
|
|
||||||
if (permissionChecker.canAccessMic()) {
|
|
||||||
startRecording();
|
|
||||||
} else if (savedInstanceState == null) {
|
|
||||||
permissionRequestor.requestMic();
|
|
||||||
}
|
|
||||||
|
|
||||||
return dialogBuilder
|
|
||||||
.newDialog(R.string.audio_recording_title)
|
|
||||||
.setView(binding.getRoot())
|
|
||||||
.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startRecording() {
|
|
||||||
try {
|
|
||||||
recorder.startRecording(getContext());
|
|
||||||
timer.setBase(recorder.getBase());
|
|
||||||
timer.start();
|
|
||||||
} catch (IOException e) {
|
|
||||||
stopRecording();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCancel(DialogInterface dialog) {
|
|
||||||
super.onCancel(dialog);
|
|
||||||
|
|
||||||
stopRecording();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void stopRecording() {
|
|
||||||
recorder.stopRecording();
|
|
||||||
timer.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void encodingFinished(Uri uri) {
|
|
||||||
Intent intent = new Intent();
|
|
||||||
intent.setData(uri);
|
|
||||||
Fragment target = getTargetFragment();
|
|
||||||
if (target != null) {
|
|
||||||
target.onActivityResult(getTargetRequestCode(), RESULT_OK, intent);
|
|
||||||
}
|
|
||||||
dismiss();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRequestPermissionsResult(
|
|
||||||
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
|
||||||
if (requestCode == PermissionRequestor.REQUEST_MIC) {
|
|
||||||
if (verifyPermissions(grantResults)) {
|
|
||||||
startRecording();
|
|
||||||
} else {
|
|
||||||
dismiss();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
** Copyright (c) 2012 Todoroo Inc
|
|
||||||
**
|
|
||||||
** See the file "LICENSE" for the full license governing this code.
|
|
||||||
-->
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="10dip"
|
|
||||||
android:layout_marginEnd="10dip"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<Chronometer
|
|
||||||
android:id="@+id/timer"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="10dip"
|
|
||||||
android:gravity="center"
|
|
||||||
android:textSize="24sp"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/stop_recording"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="35dip"
|
|
||||||
android:layout_marginBottom="10dip"
|
|
||||||
android:layout_marginStart="10dip"
|
|
||||||
android:layout_marginEnd="10dip"
|
|
||||||
android:background="@color/overdue"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="@string/audio_stop_recording"
|
|
||||||
android:textColor="@android:color/white"
|
|
||||||
android:textSize="24sp"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
Loading…
Reference in New Issue