Android: 媒体记录器无法启动
Android: Media Recorder cannot start
我有问题。我目前正在开发一个只记录我的声音而不是手机声音的应用程序。我读到“MediaRecorder.AudioSource.VOICE_UPLINK”可以完成这个任务。
这是我的 java 代码。
package com.khagendra.zip_it;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import java.io.IOException;
public class Settings extends Fragment {
Button start,stop;
boolean fingerDown = false;
private Thread thread;
private int lastLevel;
public Settings(){
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.settings_activity,container,false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
start = (Button) view.findViewById(R.id.bstart);
stop = (Button) view.findViewById(R.id.bstop);
stop.setEnabled(false);
final SoundMeter sm = new SoundMeter();
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("level","started");
sm.start();
sm.getAmplitude();
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
v.setSelected(false);
start.setEnabled(true);
stop.setEnabled(false);
Log.d("level","stopped");
sm.stop();
}
});
}
public class SoundMeter {
private MediaRecorder mRecorder = null;
public void start() {
if (mRecorder == null) {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_UPLINK);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setOutputFile("/dev/null");
try {
mRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
try {
mRecorder.start();
}catch (Throwable t){
t.printStackTrace();
Log.d("level_error",""+t);
}
}
}
public void stop() {
thread.interrupt();
thread = null;
if (mRecorder != null) {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}
}
public void getAmplitude() {
thread = new Thread(new Runnable() {
public void run() {
while(thread != null && !thread.isInterrupted()){
//Let's make the thread sleep for a the approximate sampling time
try{Thread.sleep(75);}catch(InterruptedException ie){ie.printStackTrace();}
//readAudioBuffer();//After this call we can get the last value assigned to the lastLevel variable
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (mRecorder != null) {
lastLevel = mRecorder.getMaxAmplitude();
if(lastLevel>2000)
Log.d("level", "medium:" + lastLevel);
}
}
});
}
}
});
thread.start();
}
}
}
这是我的 logcat 输出:
06-17 18:52:37.994 12129-12129/com.khagendra.zip_it D/level﹕ started
06-17 18:52:38.034 12129-12129/com.khagendra.zip_it E/MediaRecorder﹕ start failed: -2147483648
06-17 18:52:38.054 12129-12129/com.khagendra.zip_it W/System.err﹕ java.lang.RuntimeException: start failed.
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at android.media.MediaRecorder.start(Native Method)
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at com.khagendra.zip_it.Settings$SoundMeter.start(Settings.java:103)
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at com.khagendra.zip_it.Settings.onClick(Settings.java:69)
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at android.view.View.performClick(View.java:4432)
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at android.view.View$PerformClick.run(View.java:18338)
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at android.os.Handler.handleCallback(Handler.java:725)
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:92)
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at android.os.Looper.loop(Looper.java:137)
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5283)
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method)
06-17 18:52:38.074 12129-12129/com.khagendra.zip_it W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:511)
06-17 18:52:38.074 12129-12129/com.khagendra.zip_it W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
06-17 18:52:38.074 12129-12129/com.khagendra.zip_it W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
06-17 18:52:38.074 12129-12129/com.khagendra.zip_it W/System.err﹕ at dalvik.system.NativeStart.main(Native Method)
06-17 18:52:38.074 12129-12129/com.khagendra.zip_it D/level_error﹕ java.lang.RuntimeException: start failed.
我知道有些人会建议使用“MediaRecorder.AudioSource.MIC”。所以,我试过了。它工作正常,但我希望“VOICE_UPLINK”或“VOICE_DOWNLINK”工作。 我们将不胜感激任何形式的帮助。
附加信息:我正在考虑在通话过程中实现同样的功能,这样我就可以只录制自己的声音。但现在我希望它能起作用。
此功能需要权限 CAPTURE_AUDIO_OUTPUT
。但此权限仅限系统应用使用,第三方应用无法使用。这意味着,只要您的应用不是系统应用,您就无法使用它。使您的应用程序成为系统应用程序将需要一些复杂的东西和仅在有根设备上的根 device/works。
来自文档:
VOICE_DOWNLINK
从 VOICE_DOWNLINK 来源捕获需要 CAPTURE_AUDIO_OUTPUT 权限。此权限保留供系统组件使用,第三方应用程序不可用。
VOICE_UPLINK
从 VOICE_UPLINK 来源捕获需要 CAPTURE_AUDIO_OUTPUT 权限。此权限保留供系统组件使用,第三方应用程序不可用。
我有问题。我目前正在开发一个只记录我的声音而不是手机声音的应用程序。我读到“MediaRecorder.AudioSource.VOICE_UPLINK”可以完成这个任务。
这是我的 java 代码。
package com.khagendra.zip_it;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import java.io.IOException;
public class Settings extends Fragment {
Button start,stop;
boolean fingerDown = false;
private Thread thread;
private int lastLevel;
public Settings(){
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.settings_activity,container,false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
start = (Button) view.findViewById(R.id.bstart);
stop = (Button) view.findViewById(R.id.bstop);
stop.setEnabled(false);
final SoundMeter sm = new SoundMeter();
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("level","started");
sm.start();
sm.getAmplitude();
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
v.setSelected(false);
start.setEnabled(true);
stop.setEnabled(false);
Log.d("level","stopped");
sm.stop();
}
});
}
public class SoundMeter {
private MediaRecorder mRecorder = null;
public void start() {
if (mRecorder == null) {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_UPLINK);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setOutputFile("/dev/null");
try {
mRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
try {
mRecorder.start();
}catch (Throwable t){
t.printStackTrace();
Log.d("level_error",""+t);
}
}
}
public void stop() {
thread.interrupt();
thread = null;
if (mRecorder != null) {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}
}
public void getAmplitude() {
thread = new Thread(new Runnable() {
public void run() {
while(thread != null && !thread.isInterrupted()){
//Let's make the thread sleep for a the approximate sampling time
try{Thread.sleep(75);}catch(InterruptedException ie){ie.printStackTrace();}
//readAudioBuffer();//After this call we can get the last value assigned to the lastLevel variable
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (mRecorder != null) {
lastLevel = mRecorder.getMaxAmplitude();
if(lastLevel>2000)
Log.d("level", "medium:" + lastLevel);
}
}
});
}
}
});
thread.start();
}
}
}
这是我的 logcat 输出:
06-17 18:52:37.994 12129-12129/com.khagendra.zip_it D/level﹕ started
06-17 18:52:38.034 12129-12129/com.khagendra.zip_it E/MediaRecorder﹕ start failed: -2147483648
06-17 18:52:38.054 12129-12129/com.khagendra.zip_it W/System.err﹕ java.lang.RuntimeException: start failed.
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at android.media.MediaRecorder.start(Native Method)
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at com.khagendra.zip_it.Settings$SoundMeter.start(Settings.java:103)
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at com.khagendra.zip_it.Settings.onClick(Settings.java:69)
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at android.view.View.performClick(View.java:4432)
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at android.view.View$PerformClick.run(View.java:18338)
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at android.os.Handler.handleCallback(Handler.java:725)
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:92)
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at android.os.Looper.loop(Looper.java:137)
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5283)
06-17 18:52:38.064 12129-12129/com.khagendra.zip_it W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method)
06-17 18:52:38.074 12129-12129/com.khagendra.zip_it W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:511)
06-17 18:52:38.074 12129-12129/com.khagendra.zip_it W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
06-17 18:52:38.074 12129-12129/com.khagendra.zip_it W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
06-17 18:52:38.074 12129-12129/com.khagendra.zip_it W/System.err﹕ at dalvik.system.NativeStart.main(Native Method)
06-17 18:52:38.074 12129-12129/com.khagendra.zip_it D/level_error﹕ java.lang.RuntimeException: start failed.
我知道有些人会建议使用“MediaRecorder.AudioSource.MIC”。所以,我试过了。它工作正常,但我希望“VOICE_UPLINK”或“VOICE_DOWNLINK”工作。 我们将不胜感激任何形式的帮助。
附加信息:我正在考虑在通话过程中实现同样的功能,这样我就可以只录制自己的声音。但现在我希望它能起作用。
此功能需要权限 CAPTURE_AUDIO_OUTPUT
。但此权限仅限系统应用使用,第三方应用无法使用。这意味着,只要您的应用不是系统应用,您就无法使用它。使您的应用程序成为系统应用程序将需要一些复杂的东西和仅在有根设备上的根 device/works。
来自文档:
VOICE_DOWNLINK
从 VOICE_DOWNLINK 来源捕获需要 CAPTURE_AUDIO_OUTPUT 权限。此权限保留供系统组件使用,第三方应用程序不可用。
VOICE_UPLINK
从 VOICE_UPLINK 来源捕获需要 CAPTURE_AUDIO_OUTPUT 权限。此权限保留供系统组件使用,第三方应用程序不可用。