지금은 Android 개발에 더욱 익숙해 지려고합니다. 물론 Android Studio를 사용하고 있습니다. 프로젝트로서, MediaPlayer
클래스의 URL에서 스트리밍을 처리하는 애플리케이션을 작성 중입니다.Android Studio 코딩 규칙 및 가능한 컨텍스트 오류
나는이 기능을 가지고 있으며 정확히 내가해야 할 일을합니다. 그러나, MainActivity가 자신의 클래스에 저장 될 수있는 메소드와 변수로 복잡해지기를 원하지 않았습니다.
는이 작업을 수행하는 기존의인가 :
나는 이것에 대해 몇 가지 질문이? 또는 모든 코드와 메소드를 각각의 활동에 포함시켜야합니까? 아니면 자신의 클래스로 옮기고 해당 활동이 필요로하는 곳에서 액세스 할 수 있습니까?
MediaPlayer를 다른 클래스로 이동할 때 제대로 작동하는 데 문제가 있습니다. 나는 그 메소드를 호출 할 때
Context
메소드를 제공해야한다고 읽었습니다. 그래서 아래에 보시 듯이Context
이있는 객체를 사용하여 메소드를 호출했습니다.
저는 이런 종류의 개발에 새로운 것이므로 팁, 좋은 습관 및 도움이되는 힌트를 언제나 환영합니다.
public class Streaming extends AppCompatActivity {
private SeekBar musicSeek;
private TextView currentTime;
private TextView totalTime;
private ImageButton play_pause;
private Handler seekHandler = new Handler();
private MediaPlayer mp = new MediaPlayer();
Context context;
Utilities util = new Utilities();
//Default Constructor
public Streaming(){}
//Contructor
public Streaming(Context context){
this.context = context;
}
//Method to run the runnable to update the seekbar
public void updateSeekBar(){
seekHandler.postDelayed(mUpdateTimeTask, 100);
}
public void prepareStreaming() throws IOException {
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setDataSource("http://tricountynaz.net/media/audio/2017-11-08-The%20Compassion%20of%20the%20Christ.mp3");
mp.prepare();
}
public void startStreaming(){
mp.start();
}
public void pauseStreaming(){
mp.pause();
}
//Runnable to update the seekbar with the current position.
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
int totalDuration = mp.getDuration();
int currentPosition = (mp.getCurrentPosition());
//Displaying Total Duration time
totalTime = (TextView)((Activity)context).findViewById(R.id.totalTime);
totalTime.setText(util.milliSecondsToTimer(totalDuration));
// Displaying time completed playing
currentTime = (TextView)((Activity)context).findViewById(R.id.currentTime);
currentTime.setText(util.milliSecondsToTimer(currentPosition));
//Set the bars total duration, based on the song duration (converted to seconds)
musicSeek = (SeekBar)((Activity)context).findViewById(R.id.music_seek);
musicSeek.setMax(totalDuration/1000);
// Updating progress bar
musicSeek.setProgress(mp.getCurrentPosition()/1000);
// Running this thread after 100 milliseconds
seekHandler.postDelayed(this, 100);
}
};
//What happens when the user interacts with the button
public void onPlayClick(){
play_pause = (ImageButton)((Activity)context).findViewById(R.id.playButton);
play_pause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
play_pause.setImageResource(R.drawable.ic_pause_name);
try {
prepareStreaming();
} catch (IOException e) {
e.printStackTrace();
}
if (mp.isPlaying()) {
pauseStreaming();
play_pause.setImageResource(R.drawable.ic_play_name);
} else {
//mediaPlayer.start();
startStreaming();
}
}
});
}
//Handles when the user interacts with the seekbar
public void onDrag(){
musicSeek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if(b) {
//seeks to the current position of the slider when the user (b) interacts.
mp.seekTo(i*1000);
musicSeek.setProgress(i);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});}
당신은 Utilities
을 알 수 있습니다 : I라는 그 모든 방법은
public class MainActivity extends AppCompatActivity {
Streaming stream = new Streaming(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
stream.updateSeekBar();
stream.onPlayClick();
stream.onDrag();
}
당신은 여기에서 볼 수 있습니다 여기에
내가Streaming
클래스에 넣어 메소드를 호출 내
MainActivity
입니다 수업. 현재로서는, 초 단위로 변환하는 방법 만 보유하고 있으므로
TextView
MP3를 스트리밍하는 현재 진행 상태 항목을 업데이트 할 수 있습니다.
내가받는 특정 오류는 onDrag
메서드에서 발생하는 NullPointerException
입니다. 이유를 이해할 수없는 것 같습니다.
죄송합니다. 중복 인 경우 다른 곳에서는 찾을 수 없습니다.
편집 좀 내 onDrag
방법을 변경 않았다
//Handles when the user interacts with the seekbar
public void onDrag(){
musicSeek = (SeekBar)((Activity)context).findViewById(R.id.music_seek);
musicSeek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if(b) {
//seeks to the current position of the slider when the user (b) interacts.
mp.seekTo(i*1000);
musicSeek.setProgress(i);
}
}
이 지금은 로그에이 오류를 얻을 제외하고는, NullPointerException가 해결 되었습니까 :
E/MediaPlayerNative: Attempt to call getDuration in wrong state: mPlayer=0x0, mCurrentState=0
편집 2 내 문제를 해결했다고 생각합니다. 가장 최근의 오류를 조사하자 마자 MainActivity에서 MediaPlayer를 호출하지 않았다는 것을 알게되었습니다. 따라서 아무것도로드되지 않고 스트리밍되지 않았습니다. Here은 내 솔루션의 일부를 발견 한 곳입니다.
내 playbutton
이 작동하지 않고 스트림이 자동으로 시작되는 문제가 계속 발생하지만이 문제는 간단하고 쉽게 해결할 수 있습니다. 그러나 나는 여전히 내 코드에 "잘못된"것이 있는지 알고 싶어합니다.
감사합니다. 이것은 정확하게 내가 알고 싶어하는 것이 었습니다. 그래서 지금부터 내 onCreate 안에 모든 필드 (MediaPlayer, Textviews 등)를 유지해야합니까? 보통 외부 수업이 필요하지 않습니까? 적어도 내 TextViews 및 Button과의 상호 작용에 관해서는? – brettsalyer
@brettsalyer 일반적으로 Activity 나 Fragment 하위 클래스에서 내 견해를 유지합니다. 내가 생각할 수있는 유일한 예외는보기를 사용해야하는 사용자 지정 목록 어댑터 클래스입니다. MediaPlayer로 아무 것도하지 않았지만 다른 클래스에서 사용하는 것이 도움이 될 수 있습니다. 핵심은 활동 라이프 사이클 내에서 작업하는지 확인하는 것입니다. –