我用swipeview构建了一个音乐播放器项目(2个片段)。一个片段有开始按钮,当我点击开始按钮时,另一个片段显示歌曲的元数据信息以及搜索栏。 我的问题是在播放时通过一首歌获得当前时间。
片段的代码如下:
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);
放在seekBar.setProgress(currentTime);
之后的run() - 方法中,并得到以下错误-message:
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();
}
}
}
}
没人知道吗? :/
答案 0 :(得分:9)
您当前的时间是一个int值。 Android正在检测int作为资源。所以,你可以把setText(“”+ currentTime)。 这样,它将作为字符串处理,可能会解决您的问题。