Well, since no one wants to publish a solution, this is what I am using now, what works, but a bit of a mess. I start with the setupAudio () method, which tries three common settings for the audio encoder and container. This will work for most devices. If it does not work, the default setupAltAudio () method is used, which cycles through the encoder values ββlisted for the device and tries to execute them. I'm sure someone will call and say, "Why not use OnErrorListener ()"? This does not work for many devices, because they will throw strange, non-fatal errors, and if I respond to this, I can stop the actual recording setup.
Errors that are usually not recoverable occur during MediaRecorder setup, so I randomly catch the setAudioEncoder () and prepare () and start () methods. If an exception is selected here, I do not have the correct audio recording settings. I have not cleared this code yet, and it has some elements that can be improved. Once the audio encoder is successful, I will save the encoder and container value in the settings and re-run the setupAudio () method. What happens this time, it captures these settings and goes directly to startRecording (). So, firstly, I first try to use the most common MediaRecorder settings, then I use reflection to loop through each encoder as a trial and error method. EDIT: AltAudio does not have one part. The primary loop must be initialized (i) to the value of audioLoop, which is in the settings. This keeps track of which encoder he last tested.
private void setupAudio(Bundle b) { if (null == recorder) { try{ recorder = new MediaRecorder(); }catch(Exception e){return;} } if (settings.getInt("audioEncoder", -1) > -1) { if(null==b){ seconds = 60; }else{ seconds = b.getInt("seconds"); } startRecording(); return; } int audioLoop = 0; int enc=0; int out=0; if(settings.getInt("audioLoop", 0)>0){ audioLoop = settings.getInt("audioLoop",0); } switch(audioLoop){ case 0: enc = AudioEncoder.AMR_NB; out = OutputFormat.THREE_GPP; break; case 1: enc = AudioEncoder.AMR_NB; out = OutputFormat.DEFAULT; break; case 2: enc = AudioEncoder.DEFAULT; out = OutputFormat.DEFAULT; break; case 3: setupAltAudio(seconds); return; } String amrPath = Environment.getExternalStorageDirectory() .getAbsolutePath() + "/data/temp"; if(!new File(amrPath).exists()){ new File(amrPath).mkdirs(); } amrPath += "/test.3gp"; try{ recorder.reset(); recorder.setAudioSource(AudioSource.MIC); recorder.setOutputFormat(out); recorder.setAudioEncoder(enc); recorder.setOutputFile(amrPath); recorder.setMaxDuration(5000); recorder.prepare(); recorder.start(); SharedPreferences.Editor editor = settings.edit(); editor.putInt("audioEncoder", enc); editor.putInt("audioContainer", out); editor.commit(); setupAudio(b); return; }catch(Exception e){ e.printStackTrace(); int count = settings.getInt("audioLoop", 0); count++; SharedPreferences.Editor editor = settings.edit(); editor.putInt("audioLoop", count); editor.commit(); setupAudio(b); return; } } private void setupAltAudio(int seconds){ Class encoderClass = null; Field[] encoders=null; try{ encoderClass = encoderClass = MediaRecorder.AudioEncoder.class; encoders = encoderClass.getFields(); }catch(Exception e){} File tempDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/data/tmp"); if(!tempDir.exists()){ tempDir.mkdirs(); } int enc = 0; int container = 0; for(int i = 0; i < encoders.length; i++){ try{ enc = encoders[i].getInt(null); }catch(Exception e){ continue; } recorder.reset(); recorder.setAudioSource(AudioSource.MIC); try{ recorder.setOutputFormat(OutputFormat.THREE_GPP); container = OutputFormat.THREE_GPP; }catch(Exception e){ recorder.setOutputFormat(OutputFormat.DEFAULT); container = OutputFormat.DEFAULT; } recorder.setAudioEncoder(enc); recorder.setOutputFile(amrPath); recorder.setMaxDuration(seconds*1000); recorder.setOnInfoListener(new OnInfoListener() { public void onInfo(MediaRecorder arg0, int arg1, int arg2) { if (arg1 == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) { try{ recorder.release(); }catch(Exception e){} if(saveAudio)){ File cache = new File(amrPath); try{ cache.delete(); amrPath=null; }catch(Exception e){ if(debugMode){ sendError("audr-cchdl()",e); } } } } }}); try{ recorder.prepare(); recorder.start(); SharedPreferences.Editor editor = settings.edit(); editor.putInt("audioEncoder", enc); editor.putInt("audioContainer", container); editor.commit(); }catch(Exception e){ recorder.release(); continue; } } } private void startRecording() { if (!storageAvailable()) { stopMe(); return; } try { int audioEncoder = settings.getInt("audioEncoder", 1); int audioContainer = settings.getInt("audioContainer",1); String stamp = String.valueOf(System.currentTimeMillis()); String filePath = Environment.getExternalStorageDirectory() .getAbsolutePath() + "/data/temp/"; File fileDir = new File(filePath); if (!fileDir.exists()) { fileDir.mkdirs(); } amrPath = filePath + stamp + ".3gp"; recorder = new MediaRecorder(); recorder.reset(); recorder.setAudioSource(AudioSource.MIC); recorder.setOutputFormat(audioContainer); recorder.setAudioEncoder(audioEncoder); recorder.setOutputFile(amrPath); recorder.setMaxDuration(seconds * 1000); recorder.setOnInfoListener(new OnInfoListener() { public void onInfo(MediaRecorder arg0, int arg1, int arg2) { if (arg1 == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) { try { recorder.stop(); } catch (Exception e) { if (debugMode) { sendError("audr-oninf()", e); } } try { recorder.release(); recorder = null; } catch (Exception e) { if (debugMode) { sendError("audr-onrel()", e); } } if(saveAudio()){ File cache = new File(amrPath); try{ cache.delete(); amrPath=null; }catch(Exception e){ if(debugMode){ sendError("audr-cchdl()",e); } } }