Ответ 1
я нашел это: http://code.google.com/p/android/issues/detail?id=4075
У меня есть прошивка android G1 1.6, я пытаюсь записать голос из приложения с помощью следующего кода.
MediaRecorder recorder = new MediaRecorder(); recorder.setAudioSource(MediaRecorder.AudioSource.MIC); recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); recorder.setOutputFile(PATH_NAME); recorder.prepare(); recorder.start();
У моего manifest.xml есть:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
Я получил:
09-23 14:41:05.531: ERROR/AndroidRuntime(1718): Uncaught handler: thread main exiting due to uncaught exception 09-23 14:41:05.551: ERROR/AndroidRuntime(1718): java.lang.RuntimeException: setAudioSource failed. 09-23 14:41:05.551: ERROR/AndroidRuntime(1718): at android.media.MediaRecorder.setAudioSource(Native Method)
как правильно записать голос?
я нашел это: http://code.google.com/p/android/issues/detail?id=4075
Откройте "AndroidManifest.xml
" →
добавить
<uses-permission android:name="android.permission.RECORD_AUDIO" />
Я знаю, что это очень старый вопрос, но в Android Marshmallow вам нужно перейти в "Настройки" > "Приложения" > "Приложение" > "Разрешения" и включить разрешение микрофона.
Если вы используете Android M, вам необходимо запросить разрешения на запись звука при первом запуске. Чтобы выполнить это, спросите пользователя, можете ли вы записывать звук при запуске приложения:
private static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 29;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (mContext.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO},
MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
} else {
Log.d("Home", "Already granted access");
initializeView(v);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d("Home", "Permission Granted");
initializeView(v);
} else {
Log.d("Home", "Permission Failed");
Toast.makeText(getActivity().getBaseContext(), "You must allow permission record audio to your mobile device.", Toast.LENGTH_SHORT).show();
getActivity().finish();
}
}
// Add additional cases for other permissions you may have asked for
}
}
ВАЖНО - в течение последних нескольких часов я попытался выяснить, как проверить, попал ли MIC в другое приложение или нет. Я заметил, что если 2 приложения адрес в MediaRecorder в то же время RuntimeException будет брошен, и вы не сможете использовать микрофон, если вы не перезапустите устройство (!) Я не знаю, было ли это лучшим решением, но это сработало для меня. возможно, это спасет некоторых из вас через несколько часов.
private void validateMicAvailability() throws MicUnaccessibleException {
AudioRecord recorder =
new AudioRecord(AudioSource.MIC, 44100,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_DEFAULT, 44100);
try{
if(recorder.getRecordingState() != AudioRecord.RECORDSTATE_STOPPED ){
throw new MicUnaccessibleException("Mic didn't successfully initialized");
}
recorder.startRecording();
if(recorder.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING){
recorder.stop();
throw new MicUnaccessibleException("Mic is in use and can't be accessed");
}
recorder.stop();
} finally{
recorder.release();
recorder = null;
}
}
У меня была эта точная проблема, она решила это для меня:
На устройстве, которое вы используете для отладки, перейдите в Настройки → Приложения → {ваше приложение}. Затем убедитесь, что разрешены все разрешения приложения (в данном случае аудиозапись и запись внешнего хранилища).
Как правило, при установке приложения не через Google Play Store вы не получаете разрешение на предоставление разрешений и на некоторых телефонах это приведет к тому, что ваше приложение для отладки не получит некоторые разрешения.
Проверьте это, даже если некоторые разрешения в файле манифеста становятся узнаваемыми (например, доступ в Интернет), потому что для меня некоторые работали, а некоторые автоматически блокировались.
Надеюсь, что это поможет.
Запросите Manifest.permission.RECORD_AUDIO
разрешение динамически для Marshmallow и выше версии.
Для API 23+ вам необходимо запросить разрешения на чтение и запись, даже если они уже находятся в вашем манифесте.
// Check for permissions
int permission = ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
// If we don't have permissions, ask user for permissions
if (permission != PackageManager.PERMISSION_GRANTED) {
String[] PERMISSIONS_STORAGE = {
android.Manifest.permission.READ_EXTERNAL_STORAGE,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
};
int REQUEST_EXTERNAL_STORAGE = 1;
ActivityCompat.requestPermissions(
getActivity(),
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
Для API 23+ проверьте разрешение звуковой записи как в Manifest.xml <uses-permission android:name="android.permission.RECORD_AUDIO" />
, так и в Java Code
if (ActivityCompat.checkSelfPermission(cnt, Manifest.permission.RECORD_AUDIO)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(cnt, arrayOf(
Manifest.permission.RECORD_AUDIO
),0)
return
}
Это выглядит правильно. Убедитесь, что другие другие приложения еще не используют MIC. Возможно, перезапустите телефон и повторите попытку.
Этот код работал у меня
mRecorder = new MediaRecorder();
mRecorder.reset();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
Мое предложение может показаться глупым, но это сработало для меня:)
Попробуйте дать разрешение в виде вложенного тега. Я считаю, что проблема с XML-синтаксисом где-то с библиотекой упаковки Android.
Ответ "validateMicAvailability() выбрасывает MicUnaccessibleException" не работает для меня. Исключение MicUnaccessibleException, похоже, не существует. Я что-то не понимаю?
Как пользователь Cyanogenmod я должен был
Settings
→ Apps
→ Выберите ваше приложение → Permissions
→ Проверить все разрешения (должны быть те, которые запрашиваются манифестом) (на устройстве)После этого перекодировка работала для меня.
попробуйте этот код, он поможет вам и его понятным.....
public class MainActivity extends Activity {
MediaRecorder mRecorder;
MediaPlayer mediaPlayer;
Button start, stop, play,stop_play;
String FileName="";
File outfile ;
public static final int request_code = 1000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start=(Button)findViewById(R.id.btn_start_main);
stop=(Button)findViewById(R.id.btn_stop_main);
play=(Button)findViewById(R.id.btn_play_main);
stop_play=(Button)findViewById(R.id.btn_playstop_main);
if (checkPermissionFromDevice()){
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FileName= Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+
UUID.randomUUID()+"AudioFile.3gp";
SetupMediaRecorder();
try {
mRecorder.prepare();
mRecorder.start();
} catch (IOException e) {
e.printStackTrace();
}
start.setEnabled(false);
stop.setEnabled(true);
play.setEnabled(false);
stop_play.setEnabled(false);
Toast.makeText(getApplicationContext(),"recording....",Toast.LENGTH_SHORT).show();
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mRecorder.stop();
play.setEnabled(true);
start.setEnabled(true);
stop.setEnabled(false);
stop_play.setEnabled(false);
Toast.makeText(getApplicationContext(),"recording stoped....",Toast.LENGTH_SHORT).show();
}
});
play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mediaPlayer=new MediaPlayer();
try {
mediaPlayer.setDataSource(FileName);
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
start.setEnabled(false);
stop.setEnabled(false);
play.setEnabled(false);
stop_play.setEnabled(true);
Toast.makeText(getApplicationContext(),"playing..",Toast.LENGTH_SHORT).show();
}
});
stop_play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mediaPlayer.stop();
SetupMediaRecorder();
start.setEnabled(true);
stop_play.setEnabled(false);
play.setEnabled(false);
}
});
}
else {
requestPermissionFromDevice();
}
}
private void SetupMediaRecorder() {
mRecorder=new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setOutputFile(FileName);
}
private void requestPermissionFromDevice() {
ActivityCompat.requestPermissions(this,new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.RECORD_AUDIO},
request_code);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case request_code:
{
if (grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED ){
Toast.makeText(getApplicationContext(),"permission granted...",Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(getApplicationContext(),"permission denied...",Toast.LENGTH_SHORT).show();
}
}
break;
}
}
private boolean checkPermissionFromDevice() {
int storage_permission= ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE);
int recorder_permssion=ContextCompat.checkSelfPermission(this,Manifest.permission.RECORD_AUDIO);
return storage_permission == PackageManager.PERMISSION_GRANTED && recorder_permssion == PackageManager.PERMISSION_GRANTED;
}
}
Я переместил его в другой поток. Все работает.
Вот код:
new Thread(() -> {
mediaRecorder.reset();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setOutputFile("/audiorecordtest.3gp");
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mediaRecorder.prepare();
mediaRecorder.start();
//do something here
mediaRecorder.stop();
} catch (IOException e) {
e.printStackTrace();
Log.d("Audio","unable to prepare");
}
}).start();
Изменить
<uses-permission android:name="android.permission.RECORD_AUDIO" />
to
<uses-permission android:name="android.permission.RECORD_AUDIO" ></uses-permission>
Работал для меня.