录制的文件名错误

时间:2017-11-30 21:13:12

标签: java android xml

首先,我将解释App的预期行为。

该应用程序做了什么?

当我运行App时,我看到了这个观点:

现在,如果点击“+”按钮,您将看到此对话框:

点击添加,此条目将添加到ListView。我添加了两个项目。这看起来像这样:

预期结果

现在当我触摸并按住列表项的麦克风图标时,它应该开始通过设备麦克风录制音频,然后使用粗体条目的名称保存此录音,这意味着例如第一个录音将获得名称 A.3gp ,第二个录音将 B.3gp 等等。

实际结果(更新07.12.2017)

目前的状态是:

  • 列表中的每个项目都会获得“自己的”录音。这意味着如果我触摸并按住列表中第一个项目的麦克风图标,它就会做它应该做的事情。列表中的所有其他项目也是如此。
  • 当我添加第一项 A 时,触摸其记录图标,将创建一个名为 A.3gp 的文件(这是正确的行为)。< / LI>
  • 当我添加第二项 B 然后不执行任何操作,然后添加第三项 C 并触摸 B 的记录图标时,将使用名称 C.3gp 创建文件(是正确的行为,它应该是 B.3gp )。

现在到了有趣的部分。

代码(更新07.12.2017)

1。模型

public class Word {

    private String mForeignTranslation;
    private String mDefaultTranslation;
    private ImageView mRecordIconImageResourceId;
    private MediaRecorder mMediaRecorder;

    public Word(String foreignTranslation, String defaultTranslation, ImageView recordIconImageResourceId) {
        this.mForeignTranslation = foreignTranslation;
        this.mDefaultTranslation = defaultTranslation;
        this.mRecordIconImageResourceId = recordIconImageResourceId;
    }

    public Word(String foreignTranslation, String defaultTranslation) {
        this.mForeignTranslation = foreignTranslation;
        this.mDefaultTranslation = defaultTranslation;
    }

    public String getDefaultTranslation() {
        return mDefaultTranslation;
    }

    public String getForeignTranslation() {
        return mForeignTranslation;
    }

    public ImageView getRecordIconImageResourceId() {
        return mRecordIconImageResourceId;
    }

    public MediaRecorder getMediaRecorder() {
        return mMediaRecorder;
    }

    public void setDefaultTranslation(String mDefaultTranslation) {
        this.mDefaultTranslation = mDefaultTranslation;
    }

    public void setForeignTranslation(String mForeignTranslation) {
        this.mForeignTranslation = mForeignTranslation;
    }

    public void setRecordIconImageResourceId(ImageView recordIconImageResourceId) {
        this.mRecordIconImageResourceId = recordIconImageResourceId;
    }

    public void setMediaRecorder(MediaRecorder mMediaRecorder) {
        this.mMediaRecorder = mMediaRecorder;
    }
}

2。适配器

public class WordAdapter extends ArrayAdapter<Word> {

    private ArrayList<Word> wordsArrayList = new ArrayList<>();
    private MediaRecorder mediaRecorder = new MediaRecorder();


    public WordAdapter(@NonNull Context context, ArrayList<Word> words) {
        super(context, 0, words);
    }

    @NonNull
    @Override
    public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        View listItemView = convertView;

        if (listItemView == null) {
            listItemView = LayoutInflater.from(getContext()).inflate(R.layout.my_word_list_items,parent,false);
        }

        Word currentWord = getItem(position);

        TextView foreignWord = listItemView.findViewById(R.id.myForeignWord);
        foreignWord.setText(currentWord.getForeignTranslation());

        TextView defaultWord = listItemView.findViewById(R.id.myDefaultWord);
        defaultWord.setText(currentWord.getDefaultTranslation());

        final ImageView recordIconImageView = listItemView.findViewById(R.id.recordIconImageView);

        wordsArrayList = MyWordsActivity.getWordsArrayList();

        recordIconImageView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN: {
                        recordIconImageView.setImageResource(R.drawable.mic_red);
                        startAudioRecording();
                        break;
                    }
                    case MotionEvent.ACTION_UP: {
                        recordIconImageView.setImageResource(R.drawable.mic_black);
                        stopAudioRecording();
                        break;
                    }
                }
                return true;
            }
        });

        return listItemView;
    }

    private ArrayList<Word> getWordsArrayList() {
        return wordsArrayList;
    }

    private void startAudioRecording() {

        if (wordsArrayList != null) {
            Log.i("ArrayListe", wordsArrayList.toArray().toString());
            getMediaRecorderReady();

            try {
                mediaRecorder.prepare();
                mediaRecorder.start();
            } catch (IllegalStateException | IOException e) {
                e.printStackTrace();
            }
            Toast.makeText(this.getContext(), "Recording started", Toast.LENGTH_SHORT).show();
        }
    }

    private void stopAudioRecording() {
        try {
            mediaRecorder.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Toast.makeText(this.getContext(), "Recording stopped", Toast.LENGTH_SHORT).show();
    }

    private void getMediaRecorderReady() {
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mediaRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
        mediaRecorder.setOutputFile(Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+"speakmylanguage"+"/"+MyWordsActivity.getForeignWord()+".3gp");
    }
}

3。活动

public class MyWordsActivity extends AppCompatActivity {

    private static String defaultWord, foreignWord;
    private static ArrayList<Word> wordsArrayList = new ArrayList<>();
    WordAdapter wordAdapter;

    // Main Activity Views
    TextView hintTextView;
    ListView myWordsListView;
    FloatingActionButton floatingButtonAddNewWord;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_words);

        // Init Main Activity Views
        hintTextView = findViewById(R.id.hintTextView);
        myWordsListView = findViewById(R.id.myWordsList);
        floatingButtonAddNewWord = findViewById(R.id.fabAddNewWord);

        floatingButtonAddNewWord.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                final Dialog addNewWordsDialog = new Dialog(MyWordsActivity.this);
                addNewWordsDialog.setContentView(R.layout.activity_add_new_words);
                final EditText addForeignWordEditText = addNewWordsDialog.findViewById(R.id.addForeignWordEditText);
                final EditText addDefaultWordEditText = addNewWordsDialog.findViewById(R.id.addDefaultWordEditText);
                final Button addNewWordButton = addNewWordsDialog.findViewById(R.id.addNewWordButton);
                addNewWordsDialog.show();

                addNewWordButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        if (!addDefaultWordEditText.getText().toString().equals("") &&
                                !addForeignWordEditText.getText().toString().equals("")) {
                            foreignWord = addForeignWordEditText.getText().toString();
                            defaultWord = addDefaultWordEditText.getText().toString();
                            wordsArrayList.add(new Word(foreignWord, defaultWord));
                            hintTextView.setVisibility(View.GONE);
                            addNewWordsDialog.dismiss();
                        } else {
                            Toast.makeText(MyWordsActivity.this, "Please enter two words", Toast.LENGTH_SHORT).show();
                        }
                    }
                });

                wordAdapter = new WordAdapter(MyWordsActivity.this, getWordsArrayList());
                myWordsListView.setAdapter(wordAdapter);
            }
        });
    }

    public static String getDefaultWord() {
        return defaultWord;
    }

    public static void setDefaultWord(String defaultWord) {
        MyWordsActivity.defaultWord = defaultWord;
    }

    public static String getForeignWord() {
        return foreignWord;
    }

    public static void setForeignWord(String foreignWord) {
        MyWordsActivity.foreignWord = foreignWord;
    }

    public static ArrayList<Word> getWordsArrayList() {
        return wordsArrayList;
    }

}

4。布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/myRelativeLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <LinearLayout
        android:id="@+id/myWordsListItems"
        android:layout_width="match_parent"
        android:layout_height="88dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="16dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/myForeignWord"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="bottom"
            android:textAppearance="?android:textAppearanceMedium"
            android:textSize="24sp"
            android:textStyle="bold"
            tools:text="foreign word" />

        <TextView
            android:id="@+id/myDefaultWord"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="top"
            android:textAppearance="?android:textAppearanceMedium"
            android:textSize="24sp"
            tools:text="default word" />
    </LinearLayout>

    <ImageView
        android:id="@+id/playIconImageView"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_alignParentEnd="true"
        android:layout_centerVertical="true"
        android:layout_marginEnd="16dp"
        android:clickable="true"
        android:src="@drawable/play_icon" />

    <ImageView
        android:id="@+id/recordIconImageView"
        android:layout_width="42dp"
        android:layout_height="42dp"
        android:layout_alignParentEnd="true"
        android:layout_centerVertical="true"
        android:layout_marginEnd="72dp"
        android:clickable="true"
        android:src="@drawable/mic_black" />
</RelativeLayout>

activity_my_words.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.yousef.mustafa.speakmylanguage.View.MyWordsActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:title="@string/app_name"
        app:titleTextColor="@color/colorWhite" />

    <ListView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/myWordsList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/toolbar"
        android:drawSelectorOnTop="true"
        android:orientation="vertical"
        tools:context=".View.MyWordsActivity" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fabAddNewWord"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_gravity="bottom|center"
        android:layout_marginBottom="32dp"
        android:tint="@color/colorWhite"
        app:backgroundTint="@color/colorGrey"
        app:srcCompat="@drawable/icon_add" />

    <TextView
        android:id="@+id/hintTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="155dp"
        android:gravity="center"
        android:text="@string/hint"
        android:textSize="24sp"
        android:textStyle="bold" />

</RelativeLayout>

activity_add_new_words.xml

<?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="match_parent"
    android:background="@color/colorDialogBackground">

    <LinearLayout
        android:id="@+id/addNewWordLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginBottom="8dp"
            android:layout_marginTop="12dp"
            android:text="@string/add_word_title"
            android:textColor="@color/colorBlack"
            android:textSize="24sp"
            android:textStyle="bold" />

        <EditText
            android:id="@+id/addForeignWordEditText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginBottom="4dp"
            android:layout_marginEnd="12dp"
            android:layout_marginStart="12dp"
            android:layout_weight="5"
            android:gravity="center_horizontal"
            android:hint="@string/enter_foreign_word"
            android:inputType="textPersonName|textCapWords"
            android:textSize="24sp" />

        <EditText
            android:id="@+id/addDefaultWordEditText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginEnd="12dp"
            android:layout_marginStart="12dp"
            android:layout_marginTop="4dp"
            android:layout_weight="5"
            android:gravity="center_horizontal"
            android:hint="@string/enter_default_word"
            android:inputType="textPersonName|textCapWords"
            android:textSize="24sp" />

        <Button
            android:id="@+id/addNewWordButton"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="16dp"
            android:layout_marginEnd="16dp"
            android:layout_marginStart="16dp"
            android:layout_marginTop="16dp"
            android:text="@string/button_add"
            android:textAllCaps="false"
            android:textSize="18sp" />
    </LinearLayout>
</RelativeLayout>

我将不胜感激任何帮助。提前谢谢。

2 个答案:

答案 0 :(得分:1)

在Activity的startAudioRecording()方法中,您可以从foreignWord字段设置输出文件名。问题是每次用户在“添加Word”对话框中提交单词对时,foreignWord字段都设置为最近添加的外来单词。因此,每次用户开始录制时,输出文件的名称将被设置为最后添加的外来词。

不应使用recordingImageViewforeignWorddefaultWordforeignWordaudioSavePathmediaRecorder的字段,而应将其设为本地变量,并通过以下步骤将它们作为参数传递给record()startAudioRecording()stopAudioRecording()方法:

  1. 只需从类的开头删除这些字段,以便在使用字段时看到一些编译错误。

  2. 如果在分配的左侧看到未定义的变量,请将变量设为本地(在Android Studio中为Ctrl + V)。

  3. 如果在别处看到未定义的变量,请将变量设为方法的参数(Ctrl + P)。

  4. 它应该在这些变化之后起作用。

    `

答案 1 :(得分:1)

请移动此代码段

  recordingImageView.setOnTouchListener(new View.OnTouchListener() 
 { 
 @Override public boolean onTouch(View view, MotionEvent motionEvent) 
 {   
      switch (motionEvent.getAction()) 
      { 
           case MotionEvent.ACTION_DOWN: 
            { recordingImageView.setImageResource(g startAudioRecording(position); 
                break; 
      } 
      case MotionEvent.ACTION_UP: 
      { 
           recordingImageView.setImageResource(R.drawable.mic_black); 
            stopAudioRecording(); 
            break; 
      } 
      } 
      return true; 
 } 
 });

在Adapter中,getView(...)下面访问recordImageView。

将startAudioRecording(),stopAudioRecording()放在同一个适配器中或所有相关的录制方法都在适配器中。

因此,您将在每个单独的图像视图中单击。以前,当您获取它时,它只会占用任何一个图像视图的实例。

现在将“startAudioRecording()”上的代码更新为:

 private void startAudioRecording() 
 { 
      if (checkPermission()) 
      { 
           if (wordsArrayList != null) 
           { 
                audioSavePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + wordsArrayList.get(position) + ".3gp"; 
                getMediaRecorderReady(); 
           } 
      }
 }

现在是你的第二点,用任何名字保存它的名字。将通过以上代码覆盖。

感谢和快乐的编码