From 9a22917951a9dacc9470633f94b769c4d7187943 Mon Sep 17 00:00:00 2001 From: Christian Schneppe Date: Sun, 29 Apr 2018 23:24:05 +0200 Subject: migrate recording activity to view binder --- .../pixart/messenger/ui/ConversationFragment.java | 87 ++++------- .../de/pixart/messenger/ui/RecordingActivity.java | 159 ++++++++++----------- .../pixart/messenger/ui/util/AttachmentTool.java | 5 +- .../de/pixart/messenger/utils/ThemeHelper.java | 15 ++ 4 files changed, 122 insertions(+), 144 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java index cad1beb44..def3c00f6 100644 --- a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java +++ b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java @@ -304,7 +304,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke return false; } } - if (hasStoragePermission(REQUEST_ADD_EDITOR_CONTENT)) { + if (hasPermissions(REQUEST_ADD_EDITOR_CONTENT, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { attachImageToConversation(inputContentInfo.getContentUri()); } else { mPendingEditorContent = inputContentInfo.getContentUri(); @@ -1561,22 +1561,16 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke } public void attachFile(final int attachmentChoice) { - if (attachmentChoice == ATTACHMENT_CHOICE_TAKE_FROM_CAMERA) { - if (!hasStorageAndCameraPermission(attachmentChoice)) { - return; - } - } else if (attachmentChoice != ATTACHMENT_CHOICE_LOCATION) { - if (!Config.ONLY_INTERNAL_STORAGE && !hasStoragePermission(attachmentChoice)) { + if (attachmentChoice == ATTACHMENT_CHOICE_RECORD_VOICE) { + if (!hasPermissions(attachmentChoice, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO)) { return; } - } - if (attachmentChoice == ATTACHMENT_CHOICE_RECORD_VOICE) { - if (!activity.hasMicPermission(attachmentChoice)) { + } else if (attachmentChoice == ATTACHMENT_CHOICE_TAKE_FROM_CAMERA) { + if (!hasPermissions(attachmentChoice, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA)) { return; } - } - if (attachmentChoice == ATTACHMENT_CHOICE_LOCATION) { - if (!activity.hasLocationPermission(attachmentChoice)) { + } else if (attachmentChoice != ATTACHMENT_CHOICE_LOCATION) { + if (!hasPermissions(attachmentChoice, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { return; } } @@ -1654,7 +1648,10 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke } } else { @StringRes int res; - if (Manifest.permission.CAMERA.equals(getFirstDenied(grantResults, permissions))) { + String firstDenied = getFirstDenied(grantResults, permissions); + if (Manifest.permission.RECORD_AUDIO.equals(firstDenied)) { + res = R.string.no_microphone_permission; + } else if (Manifest.permission.CAMERA.equals(firstDenied)) { res = R.string.no_camera_permission; } else { res = R.string.no_storage_permission; @@ -1665,7 +1662,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke } public void startDownloadable(Message message) { - if (!Config.ONLY_INTERNAL_STORAGE && !hasStoragePermission(REQUEST_START_DOWNLOAD)) { + if (!hasPermissions(REQUEST_START_DOWNLOAD, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { this.mPendingDownloadableMessage = message; return; } @@ -1684,26 +1681,6 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke } } - private boolean hasStorageAndCameraPermission(int requestCode) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - List missingPermissions = new ArrayList<>(); - if (!Config.ONLY_INTERNAL_STORAGE && activity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - missingPermissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); - } - if (activity.checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { - missingPermissions.add(Manifest.permission.CAMERA); - } - if (missingPermissions.size() == 0) { - return true; - } else { - requestPermissions(missingPermissions.toArray(new String[missingPermissions.size()]), requestCode); - return false; - } - } else { - return true; - } - } - @SuppressLint("InflateParams") protected void clearHistoryDialog(final Conversation conversation) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); @@ -1728,13 +1705,22 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke builder.create().show(); } - private boolean hasStoragePermission(int requestCode) { + private boolean hasPermissions(int requestCode, String... permissions) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - if (activity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode); - return false; - } else { + final List missingPermissions = new ArrayList<>(); + for (String permission : permissions) { + if (Config.ONLY_INTERNAL_STORAGE && permission.equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) { + continue; + } + if (activity.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { + missingPermissions.add(permission); + } + } + if (missingPermissions.size() == 0) { return true; + } else { + requestPermissions(missingPermissions.toArray(new String[missingPermissions.size()]), requestCode); + return false; } } else { return true; @@ -1747,7 +1733,6 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke final PresenceSelector.OnPresenceSelected callback = () -> { final Intent intent = new Intent(); boolean chooser = false; - String fallbackPackageId = null; switch (attachmentChoice) { case ATTACHMENT_CHOICE_CHOOSE_IMAGE: intent.setAction(Intent.ACTION_GET_CONTENT); @@ -1807,8 +1792,6 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke } else { startActivityForResult(intent, attachmentChoice); } - } else if (fallbackPackageId != null) { - startActivity(getInstallApkIntent(fallbackPackageId)); } }; if (account.httpUploadAvailable() || attachmentChoice == ATTACHMENT_CHOICE_LOCATION) { @@ -1821,26 +1804,8 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke } } - private Intent getInstallApkIntent(final String packageId) { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse("market://details?id=" + packageId)); - if (intent.resolveActivity(getActivity().getPackageManager()) != null) { - return intent; - } else { - intent.setData(Uri.parse("http://play.google.com/store/apps/details?id=" + packageId)); - return intent; - } - } - @Override public void onResume() { - new Handler().post(() -> { - final Activity activity = getActivity(); - if (activity == null) { - return; - } - getActivity().invalidateOptionsMenu(); - }); super.onResume(); binding.messagesView.post(this::fireReadEvent); } diff --git a/src/main/java/de/pixart/messenger/ui/RecordingActivity.java b/src/main/java/de/pixart/messenger/ui/RecordingActivity.java index b49566c27..545acd197 100644 --- a/src/main/java/de/pixart/messenger/ui/RecordingActivity.java +++ b/src/main/java/de/pixart/messenger/ui/RecordingActivity.java @@ -1,41 +1,40 @@ package de.pixart.messenger.ui; +import android.annotation.SuppressLint; import android.app.Activity; +import android.content.Context; import android.content.Intent; +import android.databinding.DataBindingUtil; import android.media.MediaRecorder; import android.net.Uri; -import android.os.Build; import android.os.Bundle; +import android.os.FileObserver; import android.os.Handler; import android.os.SystemClock; import android.util.Log; import android.view.View; import android.view.WindowManager; -import android.widget.Button; -import android.widget.TextView; import android.widget.Toast; import java.io.File; +import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import de.pixart.messenger.Config; import de.pixart.messenger.R; +import de.pixart.messenger.databinding.ActivityRecordingBinding; import de.pixart.messenger.persistance.FileBackend; +import de.pixart.messenger.utils.ThemeHelper; -public class RecordingActivity extends XmppActivity implements View.OnClickListener { +public class RecordingActivity extends Activity implements View.OnClickListener { - private TextView mTimerTextView; - private Button mCancelButton; - private Button mStopButton; + private ActivityRecordingBinding binding; private MediaRecorder mRecorder; private long mStartTime = 0; - private int[] amplitudes = new int[100]; - private int i = 0; - private Handler mHandler = new Handler(); private Runnable mTickExecutor = new Runnable() { @Override @@ -44,38 +43,28 @@ public class RecordingActivity extends XmppActivity implements View.OnClickListe mHandler.postDelayed(mTickExecutor, 100); } }; + private File mOutputFile; + private boolean mShouldFinishAfterWrite = false; + + private FileObserver mFileObserver; @Override protected void onCreate(Bundle savedInstanceState) { + setTheme(ThemeHelper.findDialog(this)); super.onCreate(savedInstanceState); - setContentView(R.layout.activity_recording); - this.mTheme = findTheme(); - setTheme(this.mTheme); - this.mTimerTextView = this.findViewById(R.id.timer); - this.mCancelButton = this.findViewById(R.id.cancel_button); - this.mCancelButton.setOnClickListener(this); - this.mStopButton = this.findViewById(R.id.share_button); - this.mStopButton.setOnClickListener(this); + this.binding = DataBindingUtil.setContentView(this,R.layout.activity_recording); + this.binding.cancelButton.setOnClickListener(this); + this.binding.shareButton.setOnClickListener(this); this.setFinishOnTouchOutside(false); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - this.setTitle(R.string.attach_record_voice); - } - - @Override - protected void refreshUiReal() { - } @Override protected void onStart() { super.onStart(); - this.mTheme = findTheme(); - setTheme(this.mTheme); - Log.d(Config.LOGTAG, "output: " + getOutputFile()); if (!startRecording()) { - mStopButton.setEnabled(false); - mStopButton.setTextColor(0x8a000000); + this.binding.shareButton.setEnabled(false); Toast.makeText(this, R.string.unable_to_start_recording, Toast.LENGTH_SHORT).show(); } } @@ -84,29 +73,22 @@ public class RecordingActivity extends XmppActivity implements View.OnClickListe protected void onStop() { super.onStop(); if (mRecorder != null) { + mHandler.removeCallbacks(mTickExecutor); stopRecording(false); } - } - - @Override - void onBackendConnected() { - + if (mFileObserver != null) { + mFileObserver.stopWatching(); + } } private boolean startRecording() { mRecorder = new MediaRecorder(); mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); - mRecorder.setAudioEncodingBitRate(48000); - } else { - mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); - mRecorder.setAudioEncodingBitRate(48000); - } - mRecorder.setAudioSamplingRate(48000); - mOutputFile = getOutputFile(); - mOutputFile.getParentFile().mkdirs(); + mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mRecorder.setAudioEncodingBitRate(48000); + mRecorder.setAudioSamplingRate(16000); + setupOutputFile(); mRecorder.setOutputFile(mOutputFile.getAbsolutePath()); try { @@ -114,79 +96,96 @@ public class RecordingActivity extends XmppActivity implements View.OnClickListe mRecorder.start(); mStartTime = SystemClock.elapsedRealtime(); mHandler.postDelayed(mTickExecutor, 100); - Log.d(Config.LOGTAG, "started recording to " + mOutputFile.getAbsolutePath()); + Log.d("Voice Recorder", "started recording to " + mOutputFile.getAbsolutePath()); return true; } catch (Exception e) { - Log.e(Config.LOGTAG, "prepare() failed " + e.getMessage()); + Log.e("Voice Recorder", "prepare() failed " + e.getMessage()); return false; } } protected void stopRecording(boolean saveFile) { - mRecorder.stop(); + mShouldFinishAfterWrite = saveFile; + try { + mRecorder.stop(); + } catch (RuntimeException stopException) { + //handle cleanup here + } mRecorder.release(); mRecorder = null; mStartTime = 0; - mHandler.removeCallbacks(mTickExecutor); if (!saveFile && mOutputFile != null) { - mOutputFile.delete(); + if (mOutputFile.delete()) { + Log.d(Config.LOGTAG,"deleted canceled recording"); + } } } - private File getOutputFile() { + private static File generateOutputFilename(Context context) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmssSSS", Locale.US); return new File(FileBackend.getConversationsDirectory("Audios", true) + "/" + dateFormat.format(new Date()) + ".m4a"); } + private void setupOutputFile() { + mOutputFile = generateOutputFilename(this); + File parentDirectory = mOutputFile.getParentFile(); + if (parentDirectory.mkdirs()) { + Log.d(Config.LOGTAG, "created " + parentDirectory.getAbsolutePath()); + } + File noMedia = new File(parentDirectory, ".nomedia"); + if (!noMedia.exists()) { + try { + if (noMedia.createNewFile()) { + Log.d(Config.LOGTAG, "created nomedia file in " + parentDirectory.getAbsolutePath()); + } + } catch (IOException e) { + Log.d(Config.LOGTAG, "unable to create nomedia file in " + parentDirectory.getAbsolutePath(), e); + } + } + setupFileObserver(parentDirectory); + } + + private void setupFileObserver(File directory) { + mFileObserver = new FileObserver(directory.getAbsolutePath()) { + @Override + public void onEvent(int event, String s) { + if (s != null && s.equals(mOutputFile.getName()) && event == FileObserver.CLOSE_WRITE) { + if (mShouldFinishAfterWrite) { + setResult(Activity.RESULT_OK, new Intent().setData(Uri.fromFile(mOutputFile))); + finish(); + } + } + } + }; + mFileObserver.startWatching(); + } + + @SuppressLint("SetTextI18n") private void tick() { long time = (mStartTime < 0) ? 0 : (SystemClock.elapsedRealtime() - mStartTime); int minutes = (int) (time / 60000); int seconds = (int) (time / 1000) % 60; int milliseconds = (int) (time / 100) % 10; - mTimerTextView.setText(minutes + ":" + (seconds < 10 ? "0" + seconds : seconds) + "." + milliseconds); - if (mRecorder != null) { - amplitudes[i] = mRecorder.getMaxAmplitude(); - //Log.d(Config.LOGTAG,"amplitude: "+(amplitudes[i] * 100 / 32767)); - if (i >= amplitudes.length - 1) { - i = 0; - } else { - ++i; - } - } + this.binding.timer.setText(minutes + ":" + (seconds < 10 ? "0" + seconds : seconds) + "." + milliseconds); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.cancel_button: + mHandler.removeCallbacks(mTickExecutor); stopRecording(false); setResult(RESULT_CANCELED); finish(); break; case R.id.share_button: - stopRecording(true); - Uri uri = Uri.parse("file://" + mOutputFile.getAbsolutePath()); - Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); - scanIntent.setData(uri); - sendBroadcast(scanIntent); - setResult(Activity.RESULT_OK, new Intent().setData(uri)); - finish(); + this.binding.shareButton.setEnabled(false); + this.binding.shareButton.setText(R.string.please_wait); + mHandler.removeCallbacks(mTickExecutor); + mHandler.postDelayed(() -> stopRecording(true), 500); break; } } - - public boolean isDarkTheme() { - return this.mTheme == R.style.ConversationsDialog_Dark; - } - - protected int findTheme() { - final Boolean dark = getPreferences().getString(SettingsActivity.THEME, getResources().getString(R.string.theme)).equals("dark"); - if (dark) { - return R.style.ConversationsDialog_Dark; - } else { - return R.style.ConversationsDialog; - } - } } \ No newline at end of file diff --git a/src/main/java/de/pixart/messenger/ui/util/AttachmentTool.java b/src/main/java/de/pixart/messenger/ui/util/AttachmentTool.java index 28b8cd42e..c56f27ebf 100644 --- a/src/main/java/de/pixart/messenger/ui/util/AttachmentTool.java +++ b/src/main/java/de/pixart/messenger/ui/util/AttachmentTool.java @@ -33,7 +33,6 @@ import android.annotation.SuppressLint; import android.content.ClipData; import android.content.Intent; import android.net.Uri; -import android.os.Build; import java.util.ArrayList; import java.util.List; @@ -45,8 +44,8 @@ public class AttachmentTool { if (intent == null) { return uris; } - Uri uri = intent.getData(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && uri == null) { + final Uri uri = intent.getData(); + if (uri == null) { final ClipData clipData = intent.getClipData(); if (clipData != null) { for (int i = 0; i < clipData.getItemCount(); ++i) { diff --git a/src/main/java/de/pixart/messenger/utils/ThemeHelper.java b/src/main/java/de/pixart/messenger/utils/ThemeHelper.java index 3568a488a..27a48f069 100644 --- a/src/main/java/de/pixart/messenger/utils/ThemeHelper.java +++ b/src/main/java/de/pixart/messenger/utils/ThemeHelper.java @@ -59,6 +59,21 @@ public class ThemeHelper { } } + public static int findDialog(Context context) { + final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); + final Resources resources = context.getResources(); + final boolean dark = sharedPreferences.getString(SettingsActivity.THEME, resources.getString(R.string.theme)).equals("dark"); + final String fontSize = sharedPreferences.getString("font_size", resources.getString(R.string.default_font_size)); + switch (fontSize) { + case "medium": + return dark ? R.style.ConversationsTheme_Dark_Dialog_Medium : R.style.ConversationsTheme_Dialog_Medium; + case "large": + return dark ? R.style.ConversationsTheme_Dark_Dialog_Large : R.style.ConversationsTheme_Dialog_Large; + default: + return dark ? R.style.ConversationsTheme_Dark_Dialog: R.style.ConversationsTheme_Dialog; + } + } + public static boolean isDark(@StyleRes int id) { switch (id) { case R.style.ConversationsTheme_Dark: -- cgit v1.2.3