2

我已经建立了一个带有 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);放在 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)

任何人的想法或解决方案的建议?提前谢谢

编辑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();
                }
            }
        }
    }

没人知道吗?:/

4

1 回答 1

9

您当前的时间是一个 int 值。Android 正在将该 int 检测为资源。所以,你可以把 setText("" + currentTime). 这样,它将作为字符串处理,可能会解决您的问题。

于 2013-02-05T17:51:24.127 回答