今、私は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
に気づくでしょう:私はと呼ばれるこれらのメソッドのすべて、あなたがここで見ることができます
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
ですクラス。これは現在のところ、秒に変換するメソッドしか保持していないので、MP3のストリームの現在の進行状況を更新することができます(TextView
)。
私は受け付けており、特定のエラーがonDrag
方法から来るNullPointerException
です。なぜ私は理解できないようです。
申し訳ありませんが重複している場合は、他の場所でこれを見つけることができませんでした。
EDIT私は少し私の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
EDIT 2私は私の問題を解決したと思う。最近のエラーを調べたところ、私はMainActivityでMediaPlayerを呼び出すことはなかったことに気付きました。したがって、ロードされていないものも何もストリーミングされていませんでした。 Hereは、私が私の解決策の一部を見つけた場所です。
私のplaybutton
がまだ動作していないという問題と、ストリームが自動的に開始されますが、これは小さな問題で簡単に解決できると思います。しかし、私はまだ自分のコードで何か「間違っている」かどうかを知ることに興味があります。
ありがとうございます!これはまさに私が知りたいものでした。だから今から私のonCreate内のすべてのフィールド(MediaPlayer、Textviewsなど)を保持する必要がありますか?通常、外部のクラスは必要ありませんか?少なくとも、それは私のTextViewsとButtonsとのやりとりになるのですか? – brettsalyer
@brettsalyer私は通常、アクティビティまたはフラグメントのサブクラスに自分のビューを保持します。これについて私が考えることができる唯一の例外は、ビューを使用するカスタムリストアダプタクラスです。私はMediaPlayerで何もしていませんが、別のクラスで使用するとどのように役立つのか分かります。重要な点は、アクティビティのライフサイクルの中で作業することです。 –