Вызов аудиомагнитофона и получение результирующего файла

Я пытаюсь вызывать аудиозапись на Android 2.2.1 (устройство Samsung Galaxy POP), используя следующий код:

private static final int ACTIVITY_RECORD_SOUND = 1; Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION); startActivityForResult(intent, ACTIVITY_RECORD_SOUND); 

Это успешно активирует рекордер. В результате моей работы я делаю следующее:

 protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == Activity.RESULT_OK) { switch (requestCode) { case ACTIVITY_RECORD_SOUND: data.getDataString(); break; } } } 

После того, как я завершу запись, я снова вернусь к звукозаписывающему устройству, которое вернет элемент управления методу onActivityResult, как и ожидалось, но мой resultCode всегда равен 0 (это Activity.RESULT_CANCELED), а мои данные равны нулю. Я что-то пропустил? Пожалуйста, помогите мне с этим. Это работает на эмуляторе, но не на устройстве. Заранее спасибо.

Это работает для меня:

  @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch(requestCode) { case Flashum.TAKE_MUSIC: case Flashum.TAKE_VOICE: if (resultCode == Activity.RESULT_OK) { Log.i(Flashum.LOG_TAG, "onActivityResult got new music"); Bundle extras = data.getExtras(); try { Uri u = data.getData(); String imageUri; try { imageUri = getRealPathFromURI(u); } catch (Exception ex) { imageUri = u.getPath(); } File file = new File(imageUri); FragmentFlash fragmentFlash = (FragmentFlash)mTabsAdapter.getFragment("flash"); if (fragmentFlash != null) fragmentFlash.gotMusic(file.getPath()); } catch (Exception ex) { String s = ex.toString(); Log.i(Flashum.LOG_TAG, "onActivityResult " + s); } } else { Log.i(Flashum.LOG_TAG, "onActivityResult Failed to get music"); } break; } } public String getRealPathFromURI(Uri contentUri) { String[] proj = { MediaStore.Images.Media.DATA }; Cursor cursor = managedQuery(contentUri, proj, null, null, null); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } 

Я, наконец, нашел обходной путь для своей проблемы, используя FileObserver. Я достиг этого, выполнив следующие действия:

 package com.pravaa.audiointent; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Enumeration; import java.util.Vector; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.os.FileObserver; import android.provider.MediaStore; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; import android.widget.Toast; public class AudioActivity extends Activity implements OnClickListener { /** Called when the activity is first created. */ private Button sampleButton; private FileObserver mFileObserver; private Vector<String> audioFileNames; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); audioFileNames = new Vector<String>(); LinearLayout finalContainer = new LinearLayout(this); sampleButton = new Button(this); sampleButton.setOnClickListener(this); sampleButton.setText("Start Audio Intent"); finalContainer.addView(sampleButton); setContentView(finalContainer); addObserver(); } private void addObserver() { this.mFileObserver = new FileObserver("/sdcard/Sounds/") { @Override public void onEvent(int event, String path) { if (event == FileObserver.CREATE) { if (path != null) { int index = path.indexOf("tmp"); String tempFileName = (String) path.subSequence(0, index - 1); audioFileNames.add(tempFileName); } } else if (event == FileObserver.DELETE) { if (path != null) { int index = path.indexOf("tmp"); String tempFileName = (String) path.subSequence(0, index - 1); if (audioFileNames.contains(tempFileName)) { audioFileNames.remove(tempFileName); } } } } }; } private void readFile(String fileName) { File attachment = new File("/sdcard/Sounds/" + fileName); if (attachment.exists()) { FileInputStream fis; try { fis = new FileInputStream(attachment); byte[] bytes = new byte[(int) attachment.length()]; try { fis.read(bytes); fis.close(); attachment.delete(); saveMedia("Test" + fileName, bytes); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); mFileObserver.startWatching(); } public void saveMedia(String fileName, byte[] data) { String imagePath = "/sdcard/sam/"; System.out.println("Inside Folder"); File file = new File(imagePath, fileName); System.out.println("File Created"); FileOutputStream fileOutputStream = null; try { fileOutputStream = new FileOutputStream(file); DataOutputStream dataOutputStream = new DataOutputStream( fileOutputStream); System.out.println("Writting File"); dataOutputStream.write(data, 0, data.length); System.out.println("Finished writting File"); dataOutputStream.flush(); dataOutputStream.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void onClick(View arg0) { // TODO Auto-generated method stub Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION); startActivityForResult(intent, 2); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { // TODO Auto-generated method stub if (requestCode == 2) { if (mFileObserver != null) { mFileObserver.stopWatching(); } Enumeration<String> audioFileEnum = audioFileNames.elements(); while (audioFileEnum.hasMoreElements()) { readFile((String) audioFileEnum.nextElement()); } } }} 

Я столкнулся с одной и той же проблемой. Поэтому вместо использования намерения я использовал класс MediaRecorder и связанные с ним методы, такие как setAudioEncoder, setAudioSource, готовить, запускать, останавливать, устанавливатьOutputFormat и setOutputFile .. Теперь он отлично работает.

Я также согласен с наилучшим ответом до сих пор (проголосовал за вопрос-владелец), но он не может прочитать файл, поскольку это другой путь. Мое предложение состоит в том, чтобы сохранить имя файла в качестве переменной-члена и вызвать getFilename () только один раз.

Существует известная проблема с устройствами Android Galaxy, где исходные значения имеют значение null, где вы ожидаете, что они будут содержать фотографию. Это может также применяться здесь. См. http://kevinpotgieter.wordpress.com/2011/03/30/null-intent-passed-back-on-samsung-galaxy-tab/ .

Один из способов решения этого вопроса – добавить

 intent.putExtra(MediaStore.EXTRA_OUTPUT, someFileUri); 

К вашему намерению, явно сообщая целевому приложению, где хранить полученный файл.

Проверьте этот пример, если вам нужна помощь в создании хорошего файла Uri.