スワイプビュー(2つのフラグメント)を使用してmusicplayerプロジェクトをビルドしました。1つのフラグメントにはスタートボタンがあり、スタートボタンをクリックすると、別のフラグメントに曲のメタデータ情報とシークバーが表示されます。私の問題は、曲の再生時に曲ごとに現在の時刻を取得することです。
フラグメントのコードは次のようになります。
public static class SongParameterFragment extends Fragment {
public SeekBar seekBar;
static int fragmentNR;
public ImageView cover;
public TextView songParameter, songDuration;
runnableTimeline timelineMonitor;
public SongParameterFragment(int position) {
this.fragmentNR = position;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(com.example.swipeview3.R.layout.song_parameters, container, false);
cover = (ImageView)v.findViewById(com.example.swipeview3.R.id.imageView1);
songParameter = (TextView)v.findViewById(com.example.swipeview3.R.id.textView_SongParameter);
songDuration = (TextView)v.findViewById(com.example.swipeview3.R.id.textView_SongDuration);
seekBar = (SeekBar)v.findViewById(com.example.swipeview3.R.id.seekBar);
seekBar.setOnSeekBarChangeListener(seekBarChangeListener);
timelineMonitor = new runnableTimeline();
Thread thread = new Thread(timelineMonitor);
thread.start();
return v;
}
SeekBar.OnSeekBarChangeListener seekBarChangeListener = new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(fromUser){
if(MainActivity.mp != null){
int totalDuration = MainActivity.mp.getDuration();
int currentDuration = totalDuration * progress/100;
MainActivity.mp.seekTo(currentDuration);
}
}
}
};
private class runnableTimeline implements Runnable{
int totalDuration, currentDuration, currentTime;
@Override
public void run() {
while(true){
if(MainActivity.mp != null){
totalDuration = MainActivity.mp.getDuration();
currentDuration = MainActivity.mp.getCurrentPosition();
currentTime = (int)(100 * currentDuration/totalDuration);
seekBar.setProgress(currentTime);
}
else {
seekBar.setProgress(0);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
このコードは正常に機能します。しかし、曲の現在の時刻(または曲の進行時刻)を表示したい場合は、後にコードsongDuration.setText(currentTime);
をrun()メソッドにseekBar.setProgress(currentTime);
入れて、次のエラーメッセージを受け取ります。
E/AndroidRuntime(10902): FATAL EXCEPTION: Thread-33702
E/AndroidRuntime(10902): android.content.res.Resources$NotFoundException: String resource ID #0x0
E/AndroidRuntime(10902): at android.content.res.Resources.getText(Resources.java:260)
E/AndroidRuntime(10902): at android.widget.TextView.setText(TextView.java:3680)
E/AndroidRuntime(10902): at com.example.swipeview3.MainActivity$SongParameterFragment$runnableTimeline.run(MainActivity.java:311)
E/AndroidRuntime(10902): at java.lang.Thread.run(Thread.java:856)
誰かが解決策のアイデアやアドバイスをしますか?事前にthx
編集1:
こんにちはみんな、これはエラーメッセージです。コードcurrentDuration.setText(currentTime);
を変更すると、エラーメッセージcurrentDuration.setText("" + currentTime);
もcurrentDuration.setText(Integer.toString(currentTime));
次のようになります。
02-05 19:26:32.973: E/AndroidRuntime(14221): FATAL EXCEPTION: Thread-33924
02-05 19:26:32.973: E/AndroidRuntime(14221): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
02-05 19:26:32.973: E/AndroidRuntime(14221): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4286)
02-05 19:26:32.973: E/AndroidRuntime(14221): at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:885)
02-05 19:26:32.973: E/AndroidRuntime(14221): at android.view.View.requestLayout(View.java:12881)
02-05 19:26:32.973: E/AndroidRuntime(14221): at android.view.View.requestLayout(View.java:12881)
02-05 19:26:32.973: E/AndroidRuntime(14221): at android.view.View.requestLayout(View.java:12881)
02-05 19:26:32.973: E/AndroidRuntime(14221): at android.view.View.requestLayout(View.java:12881)
02-05 19:26:32.973: E/AndroidRuntime(14221): at android.view.View.requestLayout(View.java:12881)
02-05 19:26:32.973: E/AndroidRuntime(14221): at android.view.View.requestLayout(View.java:12881)
02-05 19:26:32.973: E/AndroidRuntime(14221): at android.view.View.requestLayout(View.java:12881)
02-05 19:26:32.973: E/AndroidRuntime(14221): at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:268)
02-05 19:26:32.973: E/AndroidRuntime(14221): at android.view.View.requestLayout(View.java:12881)
02-05 19:26:32.973: E/AndroidRuntime(14221): at android.widget.TextView.checkForRelayout(TextView.java:7184)
02-05 19:26:32.973: E/AndroidRuntime(14221): at android.widget.TextView.setText(TextView.java:3513)
02-05 19:26:32.973: E/AndroidRuntime(14221): at android.widget.TextView.setText(TextView.java:3369)
02-05 19:26:32.973: E/AndroidRuntime(14221): at android.widget.TextView.setText(TextView.java:3344)
02-05 19:26:32.973: E/AndroidRuntime(14221): at com.example.swipeview3.MainActivity$SongParameterFragment$runnableTimeline.run(MainActivity.java:311)
02-05 19:26:32.973: E/AndroidRuntime(14221): at java.lang.Thread.run(Thread.java:856)
currentDuration.setText(currentTime);
線が問題だとは思いません。ハンドラーなどを実装する必要がありますか?
編集2:
public class MainActivity extends FragmentActivity implements ActivityCommunicator {
public static MediaPlayer mp;
SongParameterFragment f2;
PlayerFragment f1;
SectionsPagerAdapter mySectionsPagerAdapter;
ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(com.example.swipeview3.R.layout.main);
mySectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(com.example.swipeview3.R.id.pager);
mViewPager.setAdapter(mySectionsPagerAdapter);
}
public void PlayKlick(View v) {
mp = MediaPlayer.create(getApplicationContext(), com.example.swipeview3.R.raw.music);
mp.start();
f2 = (SongParameterFragment)mySectionsPagerAdapter.getItem(1);
f2.passDataToFragment(loadMp3DataFile());
}
private String loadMp3DataFile() {
......
return mp3_parameter;
}
public void StopKlick(View v) {
mp.stop();
}
public void ExitKlick(View v) {
mp.stop();
this.finish();
}
@Override
public void passDataToActivity(String someValue) {
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(com.example.swipeview3.R.menu.main, menu);
return true;
}
// ------------------------------#########################------------------------------
// ------------------------------#########################------------------------------
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private PlayerFragment f1;
private SongParameterFragment f2;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
if(position == 0) {
if (f1 == null) {
f1 = new PlayerFragment(position);
}
return f1;
}
else {
if (f2 == null) {
f2 = new SongParameterFragment(position);
}
return f2;
}
}
@Override
public int getCount() {
// Show 2 total pages.
return 2;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return getString(com.example.swipeview3.R.string.title_section1).toUpperCase();
case 1:
return getString(com.example.swipeview3.R.string.title_section2).toUpperCase();
}
return null;
}
}
// ------------------------------#########################------------------------------
// ------------------------------#########################------------------------------
public class PlayerFragment extends Fragment {
int fragmentNR;
public Button btnPlay, btnStop, btnExit;
public MediaPlayer mp;
public PlayerFragment(int position) {
this.fragmentNR = position;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Log.e("Test", "hello");
//position = getArguments().getInt("position");
}
@Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(com.example.swipeview3.R.layout.player, container, false);
btnPlay = (Button)v.findViewById(com.example.swipeview3.R.id.button_play);
btnStop = (Button)v.findViewById(com.example.swipeview3.R.id.button_stop);
btnExit = (Button)v.findViewById(com.example.swipeview3.R.id.button_exit);
return v;
}
}
// ------------------------------#########################------------------------------
// ------------------------------#########################------------------------------
public static class SongParameterFragment extends Fragment {
public SeekBar seekBar;
static int fragmentNR;
public ImageView cover;
public TextView songParameter, songDuration;
runnableTimeline timelineMonitor;
public SongParameterFragment(int position) {
this.fragmentNR = position;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(com.example.swipeview3.R.layout.song_parameters, container, false);
cover = (ImageView)v.findViewById(com.example.swipeview3.R.id.imageView1);
songParameter = (TextView)v.findViewById(com.example.swipeview3.R.id.textView_SongParameter);
songDuration = (TextView)v.findViewById(com.example.swipeview3.R.id.textView_SongDuration);
seekBar = (SeekBar)v.findViewById(com.example.swipeview3.R.id.seekBar);
seekBar.setOnSeekBarChangeListener(seekBarChangeListener);
timelineMonitor = new runnableTimeline();
Thread thread = new Thread(timelineMonitor);
thread.start();
return v;
}
SeekBar.OnSeekBarChangeListener seekBarChangeListener = new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(fromUser){
if(MainActivity.mp != null){
int totalDuration = MainActivity.mp.getDuration();
int currentDuration = totalDuration * progress/100;
MainActivity.mp.seekTo(currentDuration);
}
}
}
};
private class runnableTimeline implements Runnable{
int totalDuration, currentDuration, currentTime;
@Override
public void run() {
while(true){
if(MainActivity.mp != null){
totalDuration = MainActivity.mp.getDuration();
currentDuration = MainActivity.mp.getCurrentPosition();
currentTime = (int)(100 * currentDuration/totalDuration);
seekBar.setProgress(currentTime);
Line 311: songDuration.setText("" + currentTime);
}
else {
seekBar.setProgress(0);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
誰も考えませんか?:/