diff options
author | Christian S <christian@pix-art.de> | 2016-05-05 22:14:56 +0200 |
---|---|---|
committer | Christian S <christian@pix-art.de> | 2016-05-05 22:55:01 +0200 |
commit | 429e27894859bdadb1e55cac7eeb8dc51fe05410 (patch) | |
tree | 9fe4ad3c7bfe3de67ca7199fb231d6987afdcb82 /src/main | |
parent | dc8885dc32acc6009a1280a9044cc1c7418b1675 (diff) |
add audio recorder
Diffstat (limited to 'src/main')
-rw-r--r-- | src/main/AndroidManifest.xml | 11 | ||||
-rw-r--r-- | src/main/java/eu/siacs/conversations/ui/ConversationActivity.java | 10 | ||||
-rw-r--r-- | src/main/java/eu/siacs/conversations/ui/RecordingActivity.java | 159 | ||||
-rw-r--r-- | src/main/res/layout/activity_recording.xml | 52 | ||||
-rw-r--r-- | src/main/res/values/strings.xml | 2 | ||||
-rw-r--r-- | src/main/res/values/themes.xml | 6 |
6 files changed, 235 insertions, 5 deletions
diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 57fdd4c69..9b85f1a4d 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -14,6 +14,7 @@ <uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.NFC"/> <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/> + <uses-permission android:name="android.permission.RECORD_AUDIO"/> <uses-permission android:name="android.permission.READ_PHONE_STATE" @@ -162,6 +163,16 @@ android:value=".services.ContactChooserTargetService"/> </activity> <activity + android:theme="@style/ConversationsDialog" + android:name=".ui.RecordingActivity" + android:label="@string/app_name" + android:configChanges="orientation|screenSize"> + <intent-filter> + <action android:name="android.provider.MediaStore.RECORD_SOUND" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + <activity android:name=".ui.TrustKeysActivity" android:label="@string/trust_omemo_fingerprints" android:windowSoftInputMode="stateAlwaysHidden" /> diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index f7cb3d1b8..b336d98e2 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -552,11 +552,11 @@ public class ConversationActivity extends XmppActivity intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setAction(Intent.ACTION_GET_CONTENT); break; - case ATTACHMENT_CHOICE_RECORD_VOICE: - intent.setAction(MediaStore.Audio.Media.RECORD_SOUND_ACTION); - fallbackPackageId = "eu.siacs.conversations.voicerecorder"; - break; - case ATTACHMENT_CHOICE_LOCATION: + case ATTACHMENT_CHOICE_RECORD_VOICE: + intent.setAction(MediaStore.Audio.Media.RECORD_SOUND_ACTION); + intent.setPackage("eu.siacs.conversations"); + break; + case ATTACHMENT_CHOICE_LOCATION: intent.setAction("eu.siacs.conversations.location.request"); fallbackPackageId = "eu.siacs.conversations.sharelocation"; break; diff --git a/src/main/java/eu/siacs/conversations/ui/RecordingActivity.java b/src/main/java/eu/siacs/conversations/ui/RecordingActivity.java new file mode 100644 index 000000000..4c2a79a08 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/ui/RecordingActivity.java @@ -0,0 +1,159 @@ +package eu.siacs.conversations.ui; + +import android.app.Activity; +import android.content.Intent; +import android.media.MediaRecorder; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +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 eu.siacs.conversations.R; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +import eu.siacs.conversations.Config; + +public class RecordingActivity extends Activity implements View.OnClickListener { + + private TextView mTimerTextView; + private Button mCancelButton; + private Button mStopButton; + + 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 + public void run() { + tick(); + mHandler.postDelayed(mTickExecutor,100); + } + }; + private File mOutputFile; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_recording); + this.mTimerTextView = (TextView) this.findViewById(R.id.timer); + this.mCancelButton = (Button) this.findViewById(R.id.cancel_button); + this.mCancelButton.setOnClickListener(this); + this.mStopButton = (Button) this.findViewById(R.id.share_button); + this.mStopButton.setOnClickListener(this); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + + @Override + protected void onStart() { + super.onStart(); + Log.d(Config.LOGTAG, "output: " + getOutputFile()); + startRecording(); + } + + @Override + protected void onStop() { + super.onStop(); + if (mRecorder != null) { + stopRecording(false); + } + } + + private void 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.setOutputFile(mOutputFile.getAbsolutePath()); + + try { + mRecorder.prepare(); + mRecorder.start(); + mStartTime = SystemClock.elapsedRealtime(); + mHandler.postDelayed(mTickExecutor, 100); + Log.d(Config.LOGTAG,"started recording to "+mOutputFile.getAbsolutePath()); + } catch (IOException e) { + Log.e(Config.LOGTAG, "prepare() failed "+e.getMessage()); + } + } + + protected void stopRecording(boolean saveFile) { + mRecorder.stop(); + mRecorder.release(); + mRecorder = null; + mStartTime = 0; + mHandler.removeCallbacks(mTickExecutor); + if (!saveFile && mOutputFile != null) { + mOutputFile.delete(); + } + } + + private File getOutputFile() { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmssSSS", Locale.US); + return new File(Environment.getExternalStorageDirectory().getAbsolutePath().toString() + + "/Pix-Art Messenger/Recording" + + dateFormat.format(new Date()) + + ".m4a"); + } + + 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; + } + } + } + + @Override + public void onClick(View view) { + switch (view.getId()) { + case R.id.cancel_button: + 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(); + break; + } + } +}
\ No newline at end of file diff --git a/src/main/res/layout/activity_recording.xml b/src/main/res/layout/activity_recording.xml new file mode 100644 index 000000000..2e5ea7307 --- /dev/null +++ b/src/main/res/layout/activity_recording.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/grey50"> + + <LinearLayout + android:id="@+id/button_bar" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_below="@+id/timer" + android:layout_alignParentLeft="true" + android:layout_alignParentStart="true"> + + <Button + android:id="@+id/cancel_button" + style="?android:attr/borderlessButtonStyle" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:text="@string/cancel" + android:textColor="@color/primary" /> + + <View + android:layout_width="1dp" + android:layout_height="fill_parent" + android:layout_marginBottom="7dp" + android:layout_marginTop="7dp" + android:background="@color/accent" /> + + <Button + android:id="@+id/share_button" + style="?android:attr/borderlessButtonStyle" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:text="@string/share" + android:textColor="@color/primary" /> + </LinearLayout> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="50sp" + android:text="0:00.0" + android:textColor="@color/primary" + android:typeface="monospace" + android:textStyle="bold" + android:id="@+id/timer" + android:layout_alignParentTop="true" + android:layout_centerHorizontal="true"/> +</RelativeLayout>
\ No newline at end of file diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 136c3983e..ecc715de9 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -671,5 +671,7 @@ <string name="presence_dnd">Busy</string> <string name="secure_password_generated">A secure password has been generated</string> <string name="device_does_not_support_battery_op">Your device does not support opting out of battery optimization</string> + <string name="share">Teilen</string> + <string name="no_mic_permissions">No permissions to record audio</string> </resources> diff --git a/src/main/res/values/themes.xml b/src/main/res/values/themes.xml index db86770fe..f3592b823 100644 --- a/src/main/res/values/themes.xml +++ b/src/main/res/values/themes.xml @@ -55,5 +55,11 @@ <style name="ConversationsActionBarTabs" parent="@android:style/Widget.Holo.ActionBar.TabView"> <item name="android:background">@drawable/actionbar_tab_indicator</item> </style> + <style name="ConversationsDialog" parent="@android:style/Theme.Holo.Light.Dialog"> + <item name="android:windowNoTitle">true</item> + <item name="TextSizeInfo">12sp</item> + <item name="TextSizeBody">14sp</item> + <item name="TextSizeHeadline">20sp</item> + </style> </resources>
\ No newline at end of file |