问题描述
我正在尝试通过youtube教程([链接] [1])使用Android Studio创建一个录音应用。除了通常的教程之外,我还想添加另一个Button来使用Anychart指向带有图形的页面。我设置了整个页面而没有错误,但是在模拟器上,该应用程序一直崩溃,没有任何解释。
我的代码:
RecordFragment.java
import android.Manifest;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import android.os.SystemClock;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Chronometer;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* A simple {@link Fragment} subclass.
*/
public class RecordFragment extends Fragment implements View.OnClickListener {
private NavController navController;
private ImageButton listBtn;
private ImageButton chartBtn;
private ImageButton recordBtn;
private TextView filenameText;
private boolean isRecording = false;
private String recordPermission = Manifest.permission.RECORD_AUdio;
private int PERMISSION_CODE = 21;
private MediaRecorder mediaRecorder;
private String recordFile;
private Chronometer timer;
public RecordFragment() {
// required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_record,container,false);
}
@Override
public void onViewCreated(@NonNull View view,@Nullable Bundle savedInstanceState) {
super.onViewCreated(view,savedInstanceState);
//Intitialize Variables
navController = Navigation.findNavController(view);
listBtn = view.findViewById(R.id.record_list_btn);
chartBtn = view.findViewById(R.id.chart_btn);
recordBtn = view.findViewById(R.id.record_btn);
timer = view.findViewById(R.id.record_timer);
filenameText = view.findViewById(R.id.record_filename);
/* Setting up on click listener
- Class must implement 'View.OnClickListener' and override 'onClick' method
*/
listBtn.setonClickListener(this);
chartBtn.setonClickListener(this);
recordBtn.setonClickListener(this);
}
@Override
public void onClick(View v) {
/* Check,which button is pressed and do the task accordingly
*/
switch (v.getId()) {
case R.id.record_list_btn:
/*
Navigation Controller
Part of Android Jetpack,used for navigation between both fragments
*/
if(isRecording){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(getContext());
alertDialog.setPositiveButton("OKAY",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,int which) {
navController.navigate(R.id.action_recordFragment_to_audioListFragment);
isRecording = false;
}
});
alertDialog.setNegativeButton("CANCEL",null);
alertDialog.setTitle("Audio Still recording");
alertDialog.setMessage("Are you sure,you want to stop the recording?");
alertDialog.create().show();
} else {
navController.navigate(R.id.action_recordFragment_to_audioListFragment);
}
break;
case R.id.chart_btn:
/*
Navigation Controller
Part of Android Jetpack,int which) {
navController.navigate(R.id.action_recordFragment_to_chartFragment);
isRecording = false;
}
});
alertDialog.setNegativeButton("CANCEL",you want to stop the recording?");
alertDialog.create().show();
} else {
navController.navigate(R.id.action_recordFragment_to_chartFragment);
}
break;
case R.id.record_btn:
if(isRecording) {
//Stop Recording
stopRecording();
// Change button image and set Recording state to false
recordBtn.setimageDrawable(getResources().getDrawable(R.drawable.record_btn_stopped,null));
isRecording = false;
} else {
//Check permission to record audio
if(checkPermissions()) {
//Start Recording
startRecording();
// Change button image and set Recording state to false
recordBtn.setimageDrawable(getResources().getDrawable(R.drawable.record_btn_recording,null));
isRecording = true;
}
}
break;
}
}
private void stopRecording() {
//Stop Timer,very obvIoUs
timer.stop();
//Change text on page to file saved
filenameText.setText("Recording Stopped,File Saved : " + recordFile);
//Stop media recorder and set it to null for further use to record new audio
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
}
private void startRecording() {
//Start timer from 0
timer.setBase(SystemClock.elapsedRealtime());
timer.start();
//Get app external directory path
String recordpath = getActivity().getExternalFilesDir("/").getAbsolutePath();
//Get current date and time
SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_hh_mm_ss",Locale.CANADA);
Date Now = new Date();
//initialize filename variable with date and time at the end to ensure the new file wont overwrite prevIoUs file
recordFile = "Recording_" + formatter.format(Now) + ".3gp";
filenameText.setText("Recording,File Name : " + recordFile);
//Setup Media Recorder for recording
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setoutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setoutputFile(recordpath + "/" + recordFile);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mediaRecorder.prepare();
} catch (IOException e) {
e.printstacktrace();
}
//Start Recording
mediaRecorder.start();
}
private boolean checkPermissions() {
//Check permission
if (ActivityCompat.checkSelfPermission(getContext(),recordPermission) == PackageManager.PERMISSION_GRANTED) {
//Permission Granted
return true;
} else {
//Permission not granted,ask for permission
ActivityCompat.requestPermissions(getActivity(),new String[]{recordPermission},PERMISSION_CODE);
return false;
}
}
@Override
public void onStop() {
super.onStop();
if(isRecording){
stopRecording();
}
}
}
ChartFragment.java :
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.anychart.APIlib;
import com.anychart.AnyChart;
import com.anychart.AnyChartView;
import com.anychart.chart.common.dataentry.DataEntry;
import com.anychart.chart.common.dataentry.ValueDataEntry;
import com.anychart.chart.common.listener.Event;
import com.anychart.chart.common.listener.ListenersInterface;
import com.anychart.charts.Radar;
import com.anychart.core.radar.series.Line;
import com.anychart.data.Mapping;
import com.anychart.data.Set;
import com.anychart.enums.Align;
import com.anychart.enums.MarkerType;
import java.util.ArrayList;
import java.util.List;
/**
* A simple {@link Fragment} subclass.
*/
abstract class ChartFragment extends Fragment implements View.OnClickListener{
private NavController navController;
private AnyChartView chart1;
private AnyChartView chart2;
private AnyChartView chart3;
public ChartFragment() {
// required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater,Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_chart,container);
}
@Override
public void onViewCreated(@NonNull View view,savedInstanceState);
navController = Navigation.findNavController(view);
chart1 = view.findViewById(R.id.any_chart_view);
chart2 = view.findViewById(R.id.any_chart_view1);
chart3 = view.findViewById(R.id.any_chart_view2);
Radar radar = AnyChart.radar();
radar.title("Evidence Parsing Statistics");
radar.yScale().minimum(0d);
radar.yScale().minimumGap(0d);
radar.yScale().ticks().interval(50d);
radar.xAxis().labels().padding(5d,5d,5d);
radar.legend()
.align(Align.CENTER)
.enabled(true);
List<DataEntry> data1 = new ArrayList<>();
data1.add(new CustomDataEntry("Doubts",136,199,43));
data1.add(new CustomDataEntry("Engagement",179,125,56));
data1.add(new CustomDataEntry("PLE",149,173,101));
data1.add(new CustomDataEntry("pulse",135,33,202));
data1.add(new CustomDataEntry("Resources",158,64,196));
Set set = Set.instantiate();
set.data(data1);
Mapping shamanData = set.mapAs("{ x: 'x',value: 'value' }");
Mapping warriorData = set.mapAs("{ x: 'x',value: 'value2' }");
Mapping priestData = set.mapAs("{ x: 'x',value: 'value3' }");
Line shamanLine = radar.line(shamanData);
shamanLine.name("History");
shamanLine.markers()
.enabled(true)
.type(MarkerType.CIRCLE)
.size(3d);
Line warriorLine = radar.line(warriorData);
warriorLine.name("Math");
warriorLine.markers()
.enabled(true)
.type(MarkerType.CIRCLE)
.size(3d);
Line priestLine = radar.line(priestData);
priestLine.name("Geography");
priestLine.markers()
.enabled(true)
.type(MarkerType.CIRCLE)
.size(3d);
radar.tooltip().format("Value: {%Value}");
chart1.setChart(radar);
}
private class CustomDataEntry extends ValueDataEntry {
public CustomDataEntry(String x,Number value,Number value2,Number value3) {
super(x,value);
setValue("value2",value2);
setValue("value3",value3);
}
}
}
activity_main.xml :
<androidx.coordinatorlayout.widget.CoordinatorLayout 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"
tools:context=".MainActivity">
<fragment
android:id="@+id/fragment_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:navGraph="@navigation/nav_graph"
app:defaultNavHost="true"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Navgraph.xml :
<navigation 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:id="@+id/nav_graph"
app:startDestination="@id/recordFragment">
<fragment
android:id="@+id/recordFragment"
android:name="com.tvacstudio.audiorecorder.RecordFragment"
android:label="fragment_record"
tools:layout="@layout/fragment_record" >
<action
android:id="@+id/action_recordFragment_to_audioListFragment"
app:destination="@id/audioListFragment"
app:exitAnim="@anim/fade_out"
app:popEnteranim="@anim/fade_in"
app:enteranim="@anim/slide_in"
app:popExitAnim="@anim/slide_out"
/>
<action
android:id="@+id/action_recordFragment_to_chartFragment"
app:destination="@id/chartFragment"
app:enteranim="@anim/slide_out"
app:exitAnim="@anim/fade_out"
app:popEnteranim="@anim/fade_in"
app:popExitAnim="@anim/slide_in" />
</fragment>
<fragment
android:id="@+id/audioListFragment"
android:name="com.tvacstudio.audiorecorder.AudioListFragment"
android:label="fragment_audio_list"
tools:layout="@layout/fragment_audio_list" />
<fragment
android:id="@+id/chartFragment"
android:name="com.tvacstudio.audiorecorder.ChartFragment"
android:label="ChartFragment" />
</navigation>
Fragment_chart.xml :
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".MainActivity">
<com.anychart.AnyChartView
android:id="@+id/any_chart_view"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="@id/any_chart_view1"
app:layout_constraintTop_toTopOf="parent" />
<com.anychart.AnyChartView
android:id="@+id/any_chart_view1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/any_chart_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@+id/any_chart_view2"
/>
<com.anychart.AnyChartView
android:id="@+id/any_chart_view2"
android:layout_width="match_parent"
android:layout_height="400dp"
app:layout_constraintTop_toBottomOf="@+id/any_chart_view1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
我是Android Studio的新手,所以我们将不胜感激。 :) [1]:https://www.youtube.com/watch?v=ErJTqF14Ofk
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)