Demand analysis:

1. Read all local audio files

2. Use MediaPlayer to play audio files

3. Clip the audio files, intercept the audio clips you want, support auditioning

The resulting renderings are as follows:

First, add the required permissions to the androidmanifest.xml manifest file

< USES – permission android: name = “android. Permission. RECORD_AUDIO” / >

 

Here are some code for important XML layout files:

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/mainActivity_root"  
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingTop="10dp"
            android:paddingBottom="10dp"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:textSize="16dp"
            android:text="Local Music" />
    </RelativeLayout>
    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:alpha="0.3"
        android:background="# 666" />
    <ListView
        android:id="@+id/music_listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
         >
    </ListView>

</LinearLayout>
Copy the code

music_cut_dialog.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/shape_circle_dialog_bg"
    android:orientation="vertical"
    android:paddingTop="30dp"
    android:paddingBottom="10dp"
     >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/popupWindow_music_cut_tv_musicName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:text="Singer-song title.mp3"
            android:textSize="20sp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/popupWindow_music_cut_tv_musicName"
            android:layout_centerHorizontal="true"
            android:paddingTop="15dp"
            android:text="Drag the slider to edit the music."
            android:textColor="# 999"
            android:textSize="12sp" />
    </RelativeLayout>
 	<TextView
            android:id="@+id/popupWindow_music_cut_tv_delta_rule"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center_horizontal"
            android:text="Zero seconds have been cut."
            android:visibility="gone"
            android:textSize="12sp"
            android:textColor="# 999" />
    <com.t20.audiodemo.view.DoubleSlideSeekBar
        android:id="@+id/popupWindow_music_cut_doubleSlideSeekBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        custom:equal="1"
        custom:hasRule="false"
        custom:imageBig="@drawable/green_ball"
        custom:imageLow="@drawable/grey_ball"
        custom:imageheight="20dp"
        custom:imagewidth="20dp"
        custom:inColor="#B7D54E"
        custom:lineHeight="3dp"
        custom:outColor="#C3CBC9"
        custom:ruleColor="#0e0e0e"
        custom:ruleLineHeight="10dp"
        custom:ruleTextColor="#f74104"
        custom:ruleTextSize="6sp"
        custom:textColor="#DE5B78"
        custom:textSize="12sp" />
	<RelativeLayout 
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"
	    >
	    
        <TextView
            android:id="@+id/popupWindow_music_cut_tv_musicTest"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true"
            android:paddingBottom="15dp"
            android:textSize="10sp"
            android:textColor="#3D91FE"
            android:drawableLeft="@drawable/music_audio_test"
            android:drawablePadding="2dp"
            android:text="Click and listen to it." />
	</RelativeLayout>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/popupWindow_music_cut_tv_line"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:alpha="0.7"
            android:text="|"
            android:textColor="#C3CBC9"
            android:textSize="18sp"
            android:typeface="serif" />

        <Button
            android:id="@+id/popupWindow_music_cut_btn_cancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginRight="20dp"
            android:layout_toLeftOf="@id/popupWindow_music_cut_tv_line"
            android:background="@null"
            android:text="Cancel"
            android:textColor="# 666"
            android:textSize="16sp" />

        <Button
            android:id="@+id/popupWindow_music_cut_btn_sure"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="20dp"
            android:layout_toRightOf="@id/popupWindow_music_cut_tv_line"
            android:background="@null"
            android:text="Sure"
            android:textColor="#DE5B78"
            android:textSize="16sp" />

    </RelativeLayout>

</LinearLayout>
Copy the code

music_listview_item.xml


      
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="10dp" >

    <FrameLayout
        android:layout_width="60dp"
        android:layout_height="60dp" >

        <ImageView
            android:id="@+id/music_iv_pic"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/selector_music_play_pic" />

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

            <ImageView
                android:id="@+id/music_iv_play"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:layout_centerHorizontal="true"
                android:layout_centerVertical="true"
                android:alpha="0.7"
                android:background="@drawable/shape_play_button_background"
                android:src="@drawable/music_play" />
        </RelativeLayout>
    </FrameLayout>

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical"
        android:paddingLeft="5dp" >

        <TextView
            android:id="@+id/music_tv_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Song"
            android:textColor="# 666"
            android:textSize="13sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/music_tv_singer"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingTop="3dp"
            android:text="Singer"
            android:textColor="# 999"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/music_tv_duration"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingTop="3dp"
            android:text="Prefer"
            android:textColor="# 999"
            android:textSize="12sp" />
    </LinearLayout>

    <ImageView
        android:id="@+id/music_iv_cut"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_gravity="center"
        android:src="@drawable/music_cut" />

</LinearLayout>
Copy the code

Second, rewrite the View to implement a bidirectional sliding SeekBar control

DoubleSlideSeekBar.java

package com.t20.audiodemo.view;

import com.t20.audiodemo.R;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
/** * Bidirectional slide SeekBar *@author admin
 *
 */
/ * * *@author admin
 *
 */
public class DoubleSlideSeekBar extends View {
    /** * Width of the line (progress bar) */
    private int lineWidth;
    /** * The length of the line (progress bar) */
    private int lineLength=getWidth();
    /** ** the height of the word */
    private int textHeight;
    /** * cursor image width */
    private int imageWidth;
    /** * cursor image height */
    private int imageHeight;
    /** * whether there is a scale line */
    private boolean hasRule;
    /** * is the cursor on the left moving */
    private boolean isLowerMoving;
    /** * whether the cursor on the right is moving */
    private boolean isUpperMoving;
    /** ** the size of the word */
    private int textSize;
    /** ** the color of the word */
    private int textColor;
    /** * The color of the inner lines (progress bars) of the two cursors */
    private int inColor = Color.BLUE;
    /** * The color of the two cursor outer lines (progress bars) */
    private int outColor = Color.BLUE;
    /** * scale color */
    private int ruleColor = Color.BLUE;
    /** * the color of the word on the scale */
    private int ruleTextColor = Color.BLUE;
    /** * The image of the left icon */
    private Bitmap bitmapLow;
    /** ** The image of the right icon */
    private Bitmap bitmapBig;
    /** * the position of the left icon on the X-axis */
    private int slideLowX;
    /** ** The position of the right icon on the X axis */
    private int slideBigX;
    /** * icon (cursor) height */
    private int bitmapHeight;
    /**
     * 图标(游标) 宽度
     */
    private int bitmapWidth;
    /** * add some padding for our custom view to display the full */
    private int paddingLeft = 30;
    private int paddingRight = 30;
    private int paddingTop = 10;
    private int paddingBottom = 10;
    /** ** where the line (progress bar) starts */
    private int lineStart = paddingLeft;
    /** ** the Y position of the line */
    private int lineY;
    /** * the end position of the line (progress bar) */
    private int lineEnd = lineLength + paddingLeft;
    /** * The maximum value of the selector */
    private int bigValue = 100;
    /** * the minimum value of the selector */
    private int smallValue = 0;
    /** * the current minimum value of the selector */
    private float smallRange;
    /** * The current maximum value of the selector */
    private float bigRange;
    /** ** unit */
    private String unit = "";
    /** * unit number */
    private int equal = 20;
    /** * scale unit $*/
    private String ruleUnit = "";
    /** * the size of the text on the scale */
    private int ruleTextSize = 20;
    /** * The height of the scale line */
    private int ruleLineHeight = 20;
    private Paint linePaint;
    private Paint bitmapPaint;
    private Paint textPaint;
    private Paint paintRule;

    public DoubleSlideSeekBar(Context context) {
        this(context, null);
    }

    public DoubleSlideSeekBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DoubleSlideSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.DoubleSlideSeekBar, defStyleAttr, 0);
        int size = typedArray.getIndexCount();
        for (int i = 0; i < size; i++) {
            int type = typedArray.getIndex(i);
            switch (type) {
                case R.styleable.DoubleSlideSeekBar_inColor:
                    inColor = typedArray.getColor(type, Color.BLACK);
                    break;
                case R.styleable.DoubleSlideSeekBar_lineHeight:
                    lineWidth = (int) typedArray.getDimension(type, dip2px(getContext(), 10));
                    break;
                case R.styleable.DoubleSlideSeekBar_outColor:
                    outColor = typedArray.getColor(type, Color.YELLOW);
                    break;
                case R.styleable.DoubleSlideSeekBar_textColor:
                    textColor = typedArray.getColor(type, Color.BLUE);
                    break;
                case R.styleable.DoubleSlideSeekBar_textSize:
                    textSize = typedArray.getDimensionPixelSize(type, (int) TypedValue.applyDimension(
                            TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
                    break;
                case R.styleable.DoubleSlideSeekBar_imageLow:
                    bitmapLow = BitmapFactory.decodeResource(getResources(), typedArray.getResourceId(type, 0));
                    break;
                case R.styleable.DoubleSlideSeekBar_imageBig:
                    bitmapBig = BitmapFactory.decodeResource(getResources(), typedArray.getResourceId(type, 0));
                    break;
                case R.styleable.DoubleSlideSeekBar_imageheight:
                    imageHeight = (int) typedArray.getDimension(type, dip2px(getContext(), 20));
                    break;
                case R.styleable.DoubleSlideSeekBar_imagewidth:
                    imageWidth = (int) typedArray.getDimension(type, dip2px(getContext(), 20));
                    break;
                case R.styleable.DoubleSlideSeekBar_hasRule:
                    hasRule = typedArray.getBoolean(type, false);
                    break;
                case R.styleable.DoubleSlideSeekBar_ruleColor:
                    ruleColor = typedArray.getColor(type, Color.BLUE);
                    break;
                case R.styleable.DoubleSlideSeekBar_ruleTextColor:
                    ruleTextColor = typedArray.getColor(type, Color.BLUE);
                    break;
                case R.styleable.DoubleSlideSeekBar_unit:
                    unit = typedArray.getString(type);
                    break;
                case R.styleable.DoubleSlideSeekBar_equal:
                    equal = typedArray.getInt(type, 10);
                    break;
                case R.styleable.DoubleSlideSeekBar_ruleUnit:
                    ruleUnit = typedArray.getString(type);
                    break;
                case R.styleable.DoubleSlideSeekBar_ruleTextSize:
                    ruleTextSize = typedArray.getDimensionPixelSize(type, (int) TypedValue.applyDimension(
                            TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
                    break;
                case R.styleable.DoubleSlideSeekBar_ruleLineHeight:
                    ruleLineHeight = (int) typedArray.getDimension(type, dip2px(getContext(), 10));
                    break;
                case R.styleable.DoubleSlideSeekBar_bigValue:
                    bigValue = typedArray.getInteger(type, 100);
                    break;
                case R.styleable.DoubleSlideSeekBar_smallValue:
                    smallValue = typedArray.getInteger(type, 100);
                    break;


                default:
                    break;
            }
        }
        typedArray.recycle();
        init();
    }

    private void init(a) {
        /** The default cursor graph */
        if (bitmapLow == null) {
            bitmapLow = BitmapFactory.decodeResource(getResources(), R.drawable.grey_ball);
        }
        if (bitmapBig == null) {
            bitmapBig = BitmapFactory.decodeResource(getResources(), R.drawable.green_ball);
        }
        /** Cursor the true height of the image after scaling to set the image to the desired size */
        bitmapHeight = bitmapLow.getHeight();
        bitmapWidth = bitmapLow.getWidth();
        // Set the desired size
        int newWidth = imageWidth;
        int newHeight = imageHeight;
        // Calculate the scale
        float scaleWidth = ((float) newWidth) / bitmapWidth;
        float scaleHeight = ((float) newHeight) / bitmapHeight;
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        /** Zoom the image */
        bitmapLow = Bitmap.createBitmap(bitmapLow, 0.0, bitmapWidth, bitmapHeight, matrix, true);
        bitmapBig = Bitmap.createBitmap(bitmapBig, 0.0, bitmapWidth, bitmapHeight, matrix, true);
        /** Reobtains the width and height of the cursor image */
        bitmapHeight = bitmapLow.getHeight();
        bitmapWidth = bitmapLow.getWidth();
        /** Initializes the positions of both cursors */
        slideLowX = lineStart;
        slideBigX = lineEnd;
        smallRange = smallValue;
        bigRange = bigValue;
        if (hasRule) {
            PaddingTop is the maximum value between (the height of the text) and (the height of the scale plus the height of the text above the scale)
            paddingTop = paddingTop + Math.max(textSize, ruleLineHeight + ruleTextSize);
        } else {
            PaddingTop plus the height of text without scalepaddingTop = paddingTop + textSize; }}@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = getMyMeasureWidth(widthMeasureSpec);
        int height = getMyMeasureHeight(heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    private int getMyMeasureHeight(int heightMeasureSpec) {
        int mode = MeasureSpec.getMode(heightMeasureSpec);
        int size = MeasureSpec.getSize(heightMeasureSpec);
        if (mode == MeasureSpec.EXACTLY) {
            // Matchparent or fixed size view the minimum should be paddingBottom + paddingTop + bitmapHeight + 10 otherwise the display is incomplete
            size = Math.max(size, paddingBottom + paddingTop + bitmapHeight + 10);
        } else {
            //wrap content
            int height = paddingBottom + paddingTop + bitmapHeight + 10;
            size = Math.min(size, height);
        }
        return size;
    }

    private int getMyMeasureWidth(int widthMeasureSpec) {
        int mode = MeasureSpec.getMode(widthMeasureSpec);
        int size = MeasureSpec.getSize(widthMeasureSpec);
        if (mode == MeasureSpec.EXACTLY) {

            size = Math.max(size, paddingLeft + paddingRight + bitmapWidth * 2);

        } else {
            //wrap content
            int width = paddingLeft + paddingRight + bitmapWidth * 2;
            size = Math.min(size, width);
        }
        // match parent or fixed size Can get the length of the line (progress bar)
        lineLength = size - paddingLeft - paddingRight - bitmapWidth;
        // End position of the line (progress bar)
        lineEnd = lineLength + paddingLeft + bitmapWidth / 2;
        // Start position of line (progress bar)
        lineStart = paddingLeft + bitmapWidth / 2;
        // Initializes the cursor position
        slideBigX = lineEnd;
        slideLowX = lineStart;
        return size;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // Y coordinates
        lineY = getHeight() - paddingBottom - bitmapHeight / 2;
        // The height of the word is 100$
        textHeight = lineY - bitmapHeight / 2 - 10;
        // Whether to scale
        if (hasRule) {
            drawRule(canvas);
        }
        if (linePaint == null) {
            linePaint = new Paint();
        }
        // Draw the inner line
        linePaint.setAntiAlias(true);
        linePaint.setStrokeWidth(lineWidth);
        linePaint.setColor(inColor);
        linePaint.setStrokeCap(Paint.Cap.ROUND);
        canvas.drawLine(slideLowX, lineY, slideBigX, lineY, linePaint);
        linePaint.setColor(outColor);
        linePaint.setStrokeCap(Paint.Cap.ROUND);
        // Draw the outer line
        canvas.drawLine(lineStart, lineY, slideLowX, lineY, linePaint);
        canvas.drawLine(slideBigX, lineY, lineEnd, lineY, linePaint);
        / / draw the cursor
        if (bitmapPaint == null) {
            bitmapPaint = new Paint();
        }
        canvas.drawBitmap(bitmapLow, slideLowX - bitmapWidth / 2, lineY - bitmapHeight / 2, bitmapPaint);
        canvas.drawBitmap(bitmapBig, slideBigX - bitmapWidth / 2, lineY - bitmapHeight / 2, bitmapPaint);
        // Draw the words above the cursor
        if (textPaint == null) {
            textPaint = new Paint();
        }
        textPaint.setColor(textColor);
        textPaint.setTextSize(textSize);
        textPaint.setAntiAlias(true);
        canvas.drawText(String.format("%.0f" + unit, smallRange), slideLowX - bitmapWidth / 2, textHeight, textPaint);
        canvas.drawText(String.format("%.0f" + unit, bigRange), slideBigX - bitmapWidth / 2, textHeight, textPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // The event mechanism
        super.onTouchEvent(event);
        float nowX = event.getX();
        float nowY = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // Press on the cursor range
                boolean rightY = Math.abs(nowY - lineY) < bitmapHeight / 2;
                // Press on the left cursor
                boolean lowSlide = Math.abs(nowX - slideLowX) < bitmapWidth / 2;
                // Press on the right cursor
                boolean bigSlide = Math.abs(nowX - slideBigX) < bitmapWidth / 2;
                if (rightY && lowSlide) {
                    isLowerMoving = true;
                } else if (rightY && bigSlide) {
                    isUpperMoving = true;
                    // Click on the line outside the cursor
                } else if (nowX >= lineStart && nowX <= slideLowX - bitmapWidth / 2 && rightY) {
                    slideLowX = (int) nowX;
                    updateRange();
                    postInvalidate();
                } else if (nowX <= lineEnd && nowX >= slideBigX + bitmapWidth / 2 && rightY) {
                    slideBigX = (int) nowX;
                    updateRange();
                    postInvalidate();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                // The left cursor is the motion state
                if (isLowerMoving) {
                    // The current X coordinate is on line and to the left of the right cursor
                    if (nowX <= slideBigX - bitmapWidth && nowX >= lineStart - bitmapWidth / 2) {
                        slideLowX = (int) nowX;
                        if (slideLowX < lineStart) {
                            slideLowX = lineStart;
                        }
                        // Update progressupdateRange(); postInvalidate(); }}else if (isUpperMoving) {
                    // The current X coordinate is on line and to the right of the left cursor
                    if (nowX >= slideLowX + bitmapWidth && nowX <= lineEnd + bitmapWidth / 2) {
                        slideBigX = (int) nowX;
                        if (slideBigX > lineEnd) {
                            slideBigX = lineEnd;
                        }
                        // Update progressupdateRange(); postInvalidate(); }}break;
            // Raise your finger
            case MotionEvent.ACTION_UP:
                isUpperMoving = false;
                isLowerMoving = false;
                break;
            default:
                break;
        }

        return true;
    }

    private void updateRange(a) {
        // The current left cursor value
        smallRange = computRange(slideLowX);
        // The current value of the right cursor
        bigRange = computRange(slideBigX);
        // The interface implements value passing
        if(onRangeListener ! =null) { onRangeListener.onRange(smallRange, bigRange); }}/** * gets the current value */
    private float computRange(float range) {
        return (range - lineStart) * (bigValue - smallValue) / lineLength + smallValue;
    }

    public int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5 f);
    }

    /** ** /
    protected void drawRule(Canvas canvas) {
        if (paintRule == null) {
            paintRule = new Paint();
        }
        paintRule.setStrokeWidth(1);
        paintRule.setTextSize(ruleTextSize);
        paintRule.setTextAlign(Paint.Align.CENTER);
        paintRule.setAntiAlias(true);
        // Iterate over the equal section
        for (int i = smallValue; i <= bigValue; i += (bigValue - smallValue) / equal) {
            float degX = lineStart + i * lineLength / (bigValue - smallValue);
            intdegY = lineY - ruleLineHeight; paintRule.setColor(ruleColor); canvas.drawLine(degX, lineY, degX, degY, paintRule); paintRule.setColor(ruleTextColor); canvas.drawText(String.valueOf(i) + ruleUnit, degX, degY, paintRule); }}/** * write an interface to pass the maximum and minimum values */
    public interface onRangeListener {
        void onRange(float low, float big);
    }

    private onRangeListener onRangeListener;

    public void setOnRangeListener(DoubleSlideSeekBar.onRangeListener onRangeListener) {
        this.onRangeListener = onRangeListener;
    }
    // Set the maximum value of the selector

	public void setBigValue(int bigValue) {
		this.bigValue = bigValue;
	}
	// Set the maximum value of the selector

	public void setBigRange(float bigRange) {
		this.bigRange = bigRange; }}Copy the code

The above DoubleSlideSeekBar needs to create a new attrs.xml file under res/values/ with the following contents:


      
<resources>
  <! -- Line width -->
    <attr name="lineHeight" format="dimension" />
    <! -- Word size -->
    <attr name="textSize" format="dimension" />
    <! -- Word color -->
    <attr name="textColor" format="color" />
    <! -- Color of both cursor inner lines (progress bars) -->
    <attr name="inColor" format="color" />
    <! -- Color of two cursor outer lines (progress bar) -->
    <attr name="outColor" format="color" />
    <! -- Image of the left icon -->
    <attr name="imageLow" format="reference"/>
    <! -- Image of the icon on the right -->
    <attr name="imageBig" format="reference"/>
    <! -- Cursor image width -->
    <attr name="imagewidth" format="dimension" />
    <! -- Cursor image height -->
    <attr name="imageheight" format="dimension" />
    <! -- Is there a scale line -->
    <attr name="hasRule" format="boolean" />
    <! -- Scale color -->
    <attr name="ruleColor" format="color" />
    <! -- Color of the word on the scale -->
    <attr name="ruleTextColor" format="color" />
    <! -- Unit element -->
    <attr name="unit" format="string"/>
    <! -- Unit number -->
    <attr name="equal" format="integer"/>
    <! $-->
    <attr name="ruleUnit" format="string"/>
    <! -- Size of text on scale -->
    <attr name="ruleTextSize" format="dimension" />
    <! -- Height of scale line -->
    <attr name="ruleLineHeight" format="dimension" />
    <! -- Maximum value of selector -->
    <attr name="bigValue" format="integer"/>
    <! -- Select minimum value -->
    <attr name="smallValue" format="integer"/>

    <declare-styleable name="DoubleSlideSeekBar">
        <attr name="lineHeight" />
        <attr name="textSize" />
        <attr name="textColor" />
        <attr name="inColor" />
        <attr name="outColor" />
        <attr name="imageLow"/>
        <attr name="imageBig"/>
        <attr name="imagewidth" />
        <attr name="imageheight" />
        <attr name="hasRule" />
        <attr name="ruleColor" />
        <attr name="ruleTextColor" />
        <attr name="unit" />
        <attr name="equal" />
        <attr name="ruleUnit" />
        <attr name="ruleTextSize" />
        <attr name="ruleLineHeight" />
        <attr name="bigValue" />
        <attr name="smallValue" />
    </declare-styleable>
    <! -- lineHeight Dimension Controls the width (height) of our line (example 20DP) textSize Dimension Specifies the size of the words on the top of the cursor (example 16SP) textColor Color of the words on the top of the cursor (Example #e40627) inColor color The color of the progress bar between two cursors (example #e40627) outColor Color of the progress bar between two cursors (example #e40627) imageLow reference ImageBig Reference Image of the right cursor (example @mipmap/imgv_slide) ImageWidth Dimension The width of the cursor image (example 20dp) Imagewidth Dimension Cursor image height (example 20DP) hasRule Boolean Specifies whether there are scale lines (example true or false). RuleColor Color Specifies the color of the scale line (example #e40627). RuleTextColor Specifies the color of the word on the scale (example #e40627) unit String Equal INTEGER Specifies the number of units divided into equal portions. BigValue is 100, equal is 10, RuleUnit String The unit of the text on the scale (example $) ruleTextSize Dimension The size of the text on the scale (example 20sp) ruleLineHeight Dimension Scale height (example 16dp) bigValue INTEGER Specifies the maximum value of the selectors. SmallValue Integer Specifies the minimum value of the selectors.
</resources>
Copy the code

The clip window uses the PopupWindow PopupWindow, so you need to customize a musiccutpopupwindow.java

package com.t20.audiodemo.view;

import com.t20.audiodemo.R;

import android.app.ActionBar.LayoutParams;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.PopupWindow;
import android.widget.TextView;

public class MusicCutPopupWindow extends PopupWindow {
	private Button mButtonCancel; // Cancel button
	private Button mButtonSure;   // Confirm button
	private DoubleSlideSeekBar mDoubleSlideSeekBar; // Custom bidirectional slider progress bar
	private TextView mTextViewName;    // Music name
	private TextView mTextViewDeltaRule;/ / difference
	private TextView mTextViewMusicTest;// Listen button
	private View mMenuView; 

	private float minRule=0;
	private float maxRule=0;
	
	public float getMinRule(a) {
		return minRule;
	}
	public void setMinRule(float minRule) {
		this.minRule = minRule;
	}
	public float getMaxRule(a) {
		return maxRule;
	}
	public void setMaxRule(float maxRule) {
		this.maxRule = maxRule;
	}
	
	public MusicCutPopupWindow(Context context,OnClickListener itemsOnClick) {  
        super(context);  
        LayoutInflater inflater = (LayoutInflater) context  
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
        mMenuView = inflater.inflate(R.layout.music_cut_dialog, null);  
        mButtonCancel = (Button) mMenuView.findViewById(R.id.popupWindow_music_cut_btn_cancel);  
        mButtonSure = (Button) mMenuView.findViewById(R.id.popupWindow_music_cut_btn_sure);  
        mDoubleSlideSeekBar=(DoubleSlideSeekBar) mMenuView.findViewById(R.id.popupWindow_music_cut_doubleSlideSeekBar);
        mTextViewDeltaRule= (TextView) mMenuView.findViewById(R.id.popupWindow_music_cut_tv_delta_rule);
        mTextViewName=(TextView) mMenuView.findViewById(R.id.popupWindow_music_cut_tv_musicName);
        mTextViewMusicTest=(TextView) mMenuView.findViewById(R.id.popupWindow_music_cut_tv_musicTest);
/ * / / cancel button mButtonCancel. SetOnClickListener (new an OnClickListener () {public void onClick (View v) {/ / destruction of pop-up dismiss (); }}); * /
        // Slide control
        mDoubleSlideSeekBar.setOnRangeListener(new DoubleSlideSeekBar.onRangeListener() {
            @Override
            public void onRange(float low, float big) {
            	minRule=low;
            	maxRule=big;
            	float delta=big-low;
            	mTextViewDeltaRule.setVisibility(View.VISIBLE);
            	mTextViewDeltaRule.setText("Intercepted" + String.format("%.0f" , delta)+"Seconds"); }});// Set button listener
        mButtonCancel.setOnClickListener(itemsOnClick);
        mButtonSure.setOnClickListener(itemsOnClick);
        mTextViewMusicTest.setOnClickListener(itemsOnClick);
        // Set SelectPicPopupWindow's View
        this.setContentView(mMenuView);  
        // Set the width of the SelectPicPopupWindow popup form
        this.setWidth(LayoutParams.FILL_PARENT);  
        // Set the height of the SelectPicPopupWindow popup form
        this.setHeight(LayoutParams.WRAP_CONTENT);  
        // Set SelectPicPopupWindow to pop up the form clickable
        this.setFocusable(true); 
		// Set the window outside can also click (click outside, the window can close)
        this.setOutsideTouchable(true);
        // Set SelectPicPopupWindow to pop up the form animation
        this.setAnimationStyle(R.style.circleDialog);  
        // instantiate a ColorDrawable color to translucency
        ColorDrawable dw = new ColorDrawable(0x00000000);  
        // Sets the background of the SelectPicPopupWindow popup form
        this.setBackgroundDrawable(dw);  
    }  
	/** * Set the music message *@param name
	 * @param duration
	 */
	public void setMusicInfo(String name,long duration){
		mTextViewName.setText(name);
		int big=Integer.parseInt(String.valueOf(duration/1000)); mDoubleSlideSeekBar.setBigValue(big); mDoubleSlideSeekBar.setBigRange(big); maxRule=big; }}Copy the code

Write two more utility classes: MusicPlayer for playing music, MusicUtil for editing music

MusicPlayer.java

package com.t20.audiodemo.util;

import android.content.Context;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Handler;

/** * music player *@author admin
 *
 */
public class MusicPlayer {
	// Multimedia player
	private static MediaPlayer mediaPlayer;
	
	public static MediaPlayer getMediaPlayer(a) {
		return mediaPlayer;
	}
	public static void setMediaPlayer(MediaPlayer mediaPlayer) {
		MusicPlayer.mediaPlayer = mediaPlayer;
	}
	
	
	// Use Handler to stop the song when it reaches the end position
	public static long endProgress=0;// End the progress
	public static Handler handler = new Handler();
	public static Runnable run = new Runnable() {

			public void run(a) {
				if(endProgress! =0) {if(MusicPlayer.getMediaPlayer().isPlaying()&&MusicPlayer.getMediaPlayer().getCurrentPosition()>=endProgress){
						MusicPlayer.reset();
						handler.removeCallbacks(run);
					}
					handler.postDelayed(run, 1000); }}};/** * play */
	public static void play(Context context,String path,final int progress){	
		if(mediaPlayer==null) {/ / initialization
			mediaPlayer=new MediaPlayer();
		}
		// Reset the music
		if(mediaPlayer.isPlaying()){
			mediaPlayer.reset();
		}
		try {
			mediaPlayer.setDataSource(path);
			// Make MediaPlayer ready
			mediaPlayer.prepareAsync();
			// Play music
			mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
				
				@Override
				public void onPrepared(MediaPlayer mp) {
					// TODO Auto-generated method stub
					if(progress! =0){
						mediaPlayer.seekTo(progress);
					}
					mediaPlayer.start();
					// Loop
					mediaPlayer.setLooping(true); }}); }catch (Exception e) {
			// TODO Auto-generated catch blocke.printStackTrace(); }}/** * play (usually used for pause after play) */
	public static void reStart(a){
		if(mediaPlayer! =null){ mediaPlayer.start(); }}/** * pause */
	public static void pause(a){
		if(mediaPlayer! =null&&mediaPlayer.isPlaying()){ mediaPlayer.pause(); }}/** * stop */
	public static void stop(a){
		if(handler! =null){
			handler.removeCallbacks(run);
		}
		if(mediaPlayer! =null&&mediaPlayer.isPlaying()){
			mediaPlayer.stop();
			mediaPlayer.release();
			mediaPlayer=null; }}/** * reset */
	public static void reset(a){
		if(mediaPlayer! =null&&mediaPlayer.isPlaying()){ mediaPlayer.reset(); }}}Copy the code

MusicUtil.java

package com.t20.audiodemo.util;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;

import android.annotation.SuppressLint;
import android.media.MediaExtractor;
import android.media.MediaFormat;

/** * Tools for cutting MP3 music *@author admin
 *
 */
public class MusicUtil {
	// Adjust the SAMPLE_SIZE appropriately to crop the music more accurately
	private static final int SAMPLE_SIZE = 1024*200;
	
	  @SuppressLint("InlinedApi")
	public static boolean clipMp3(String inputPath, String outputPath, int start, int end){
	      MediaExtractor extractor = null;
	      BufferedOutputStream outputStream = null;
	      try {
	          extractor = new MediaExtractor();
	          extractor.setDataSource(inputPath);
	          int track = getAudioTrack(extractor);
	          if(track < 0) {return false;
	          }
	          // Select the audio track
	          extractor.selectTrack(track);
	          outputStream = new BufferedOutputStream(
	          new FileOutputStream(outputPath), SAMPLE_SIZE);
	          start = start * 1000;
	          end = end * 1000;
	          // Jump to the starting clipping position
	          extractor.seekTo(start, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
	          while (true){
	              ByteBuffer buffer = ByteBuffer.allocate(SAMPLE_SIZE);
	              int sampleSize = extractor.readSampleData(buffer, 0);
	              long timeStamp = extractor.getSampleTime();
	              // >= 1000000 is to clipping stop and specify clipping end is not less than 1 second, otherwise it may produce 9 seconds of audio
	              // Clipped to only 8.6 seconds, most music players are rounded down so that for players it becomes 8 seconds,
	              // So crop the edge one second longer than 9 seconds
	              if(timeStamp > end && timeStamp - end >= 1000000) {break;
	              }
	              if(sampleSize <= 0) {break;
	              }
	              byte[] buf = new byte[sampleSize];
	              buffer.get(buf, 0, sampleSize);
	              // Write to the file
	              outputStream.write(buf);
	              // Track data read forwardextractor.advance(); }}catch (IOException e) {
	          e.printStackTrace();
	      }finally {
	          if(extractor ! =null){
	              extractor.release();
	          }
	          if(outputStream ! =null) {try {
	                  outputStream.close();
	              } catch(IOException e) { e.printStackTrace(); }}}return true;
	  }

	  /** * Get audio data track *@param extractor
	   * @return* /
	  @SuppressLint("InlinedApi")
	private static int getAudioTrack(MediaExtractor extractor) {
	      for(int i = 0; i < extractor.getTrackCount(); i++){
	          MediaFormat format = extractor.getTrackFormat(i);
	          String mime = format.getString(MediaFormat.KEY_MIME);
	          if(mime.startsWith("audio")) {returni; }}return -1; }}Copy the code

5. Define an entity class music.java

package com.t20.audiodemo.entity;

import java.io.Serializable;

public class Music implements Serializable {
	private String name;   // Song name
	private String singer; / / singer
	private long duration; // The length of the song
	private String path;   // Song path
	
	public Music(a) {
		super(a); }public Music(String name, String singer, long duration, String path) {
		super(a);this.name = name;
		this.singer = singer;
		this.duration = duration;
		this.path = path;
	}
	public String getName(a) {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSinger(a) {
		return singer;
	}
	public void setSinger(String singer) {
		this.singer = singer;
	}
	public long getDuration(a) {
		return duration;
	}
	public void setDuration(long duration) {
		this.duration = duration;
	}
	public String getPath(a) {
		return path;
	}
	public void setPath(String path) {
		this.path = path; }}Copy the code

The mainActivity. Java implementation method is implemented in mainactivity. Java

package com.t20.audiodemo;

import java.util.ArrayList;
import java.util.List;

import com.t20.audiodemo.adapter.MusicListViewAdapter;
import com.t20.audiodemo.adapter.MusicListViewAdapter.OnplayMusicListener;
import com.t20.audiodemo.entity.Music;
import com.t20.audiodemo.util.MusicPlayer;

import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Toast;

public class MainActivity extends Activity {

	private static final String TAG = "MainActivity";
	// The music ListView
	private ListView mListViewMusic;
	// Music collection
	private List<Music> mMusicList;
	//ListView adapter
	private MusicListViewAdapter musicListViewAdapter;
	// Start playback progress
	private long startProgress=0;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// 1, hide the title bar, set before loading the layout (compatible with Android2.3.3 version)
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		// hide the status bar
		// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setContentView(R.layout.activity_main);
		// Get the control
		mListViewMusic=(ListView) findViewById(R.id.music_listView);
		initData();
		// Set the adapter
		musicListViewAdapter=new MusicListViewAdapter(this, mMusicList);
		mListViewMusic.setAdapter(musicListViewAdapter);
		// Listen on events
		initEvent();
	}

	private void initData(a) {
		// TODO Auto-generated method stub
		// Read the music file in the phone
		mMusicList = new ArrayList<Music>();
		/* * Uri: specifies the name of the database to be queried plus the name of the table. Projection: * Specifies which columns in the database table to query and which cursors will be returned containing the corresponding information. Null returns all information. Selection: specifies the selection criteria. * ectionargs: specifies the selection criteria. The notation is, you can replace the question mark with the actual value. If selection doesn't have this? If so, the String array can be null. * SortOrder: specifies the order of query results */
		Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
		ContentResolver contentResolver = getContentResolver();
		String selection = MediaStore.Audio.Media.MIME_TYPE + "=? ";
		String[] selectionArgs = new String[] { "audio/mpeg" };
		/ / the cursor
		Cursor cursor = contentResolver.query(uri, null.null.null,
				MediaStore.Audio.AudioColumns.IS_MUSIC);
		if(cursor ! =null) {
			while (cursor.moveToNext()) {
				String name = cursor
						.getString(cursor
								.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));
				String singer = cursor.getString(cursor
						.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
				String path = cursor.getString(cursor
						.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
				long duration = cursor
						.getLong(cursor
								.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));
				long size = cursor.getLong(cursor
						.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));

				// Separate the name of the song from the artist
				// if (size > 1000 * 800) {
				if (name.contains("-")) {
					String[] str = name.split("-");
					singer = str[0];
					if (str[1].contains(".")) {
						name = str[1].substring(0, str[1].indexOf('. '));
					} else {
						name = str[1]; }}else if (name.contains(".")) {
					name = name.substring(0, name.indexOf('. '));
				}
				Music music = new Music(name, singer, duration, path);
				mMusicList.add(music);
				// }
			}
		}
		cursor.close();
	}

	private void initEvent(a) {
		// TODO Auto-generated method stub
		/** * Listen for music in the ListView */
		musicListViewAdapter.setOnplayMusicListener(new OnplayMusicListener() {
			// Play the full song
			@Override
			public void playForFull(a) {
				// TODO Auto-generated method stub
				if(musicListViewAdapter! =null){
					musicListViewAdapter.setSelectItem(musicListViewAdapter.getSelectItem());
					musicListViewAdapter.setHidePlayBtn(true);
					musicListViewAdapter.notifyDataSetChanged();
				}
				Music music=musicListViewAdapter.getCurrentMusic();
				MusicPlayer.play(MainActivity.this,music.getPath(), 0);			
			}
			// Play snippets of songs
			@Override
			public void playforPart(a) {
				// TODO Auto-generated method stub
				startProgress=musicListViewAdapter.getCutMusicStartProgress();
				MusicPlayer.endProgress=musicListViewAdapter.getCutMusicEndProgress();
				String path=musicListViewAdapter.getCutMusicPath();
				MusicPlayer.play(MainActivity.this, path,(int)startProgress); MusicPlayer.handler.post(MusicPlayer.run); }});/** * listen for click events on ListView items */
		mListViewMusic.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<? > parent, View view,int position,
					long id) {
				// TODO Auto-generated method stub
				
				if(musicListViewAdapter! =null){
					musicListViewAdapter.setHidePlayBtn(false); musicListViewAdapter.setSelectItem(position); musicListViewAdapter.notifyDataSetChanged(); } MusicPlayer.reset(); }}); }}Copy the code

Seven, ListView adapter MusicListViewAdapter. Java

package com.t20.audiodemo.adapter;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import com.t20.audiodemo.MainActivity;
import com.t20.audiodemo.R;
import com.t20.audiodemo.entity.Music;
import com.t20.audiodemo.util.MusicPlayer;
import com.t20.audiodemo.util.MusicUtil;
import com.t20.audiodemo.view.MusicCutPopupWindow;

import android.content.Context;
import android.os.Environment;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MusicListViewAdapter extends BaseAdapter {

	private Context context;
	private List<Music> mMusicList;
	private MusicCutPopupWindow musicCutPopupWindow;
	private Music currentMusic;

	public Music getCurrentMusic(a) {
		return currentMusic;
	}

	public void setCurrentMusic(Music currentMusic) {
		this.currentMusic = currentMusic;
	}

	public MusicListViewAdapter(Context context, List<Music> mMusicList) {
		super(a);this.context = context;
		this.mMusicList = mMusicList;
	}

	@Override
	public int getCount(a) {
		// TODO Auto-generated method stub
		return mMusicList.size();
	}

	@Override
	public Object getItem(int arg0) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public long getItemId(int arg0) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		final Music music = mMusicList.get(position);
		final int currentId=position;
		// Load the layout
		View view;
		final ViewHolder viewHolder;
		if (convertView == null) {
			view = LayoutInflater.from(context).inflate(
					R.layout.music_listview_item, null);
			viewHolder = new ViewHolder();
			// Get the control
			viewHolder.textViewName = (TextView) view
					.findViewById(R.id.music_tv_name);
			viewHolder.textViewSinger = (TextView) view
					.findViewById(R.id.music_tv_singer);
			viewHolder.textViewDuration = (TextView) view
					.findViewById(R.id.music_tv_duration);
			viewHolder.imageViewPlay = (ImageView) view
					.findViewById(R.id.music_iv_play);
			viewHolder.imageViewPic = (ImageView) view
					.findViewById(R.id.music_iv_pic);
			viewHolder.imageViewCut = (ImageView) view
					.findViewById(R.id.music_iv_cut);
			view.setTag(viewHolder);
		} else {
			view = convertView;
			// Retrieve the ViewHolder
			viewHolder = (ViewHolder) view.getTag();
		}
		// Set the control
		viewHolder.textViewName.setText(music.getName());
		viewHolder.textViewSinger.setText(music.getSinger());
		viewHolder.textViewDuration.setText(formatTime(music.getDuration()));

		if(selectItem ! = -1 && selectItem == position) {
			viewHolder.imageViewPic.setEnabled(false);
			if (hidePlayBtn) {
				viewHolder.imageViewPlay.setVisibility(View.GONE);
			} else{ viewHolder.imageViewPlay.setVisibility(View.VISIBLE); }}else {
			viewHolder.imageViewPic.setEnabled(true);
			viewHolder.imageViewPlay.setVisibility(View.VISIBLE);
		}
		// Check whether the play icon is displayed
		/* * if(viewHolder.imageViewPlay.getVisibility()==View.GONE){ * viewHolder.imageViewPic.setEnabled(false); }else{ * viewHolder.imageViewPic.setEnabled(true); } * /
		// Play music button
		viewHolder.imageViewPlay.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View view) {
				// TODO Auto-generated method stub
				if(onplayMusicListener ! =null) { currentMusic = music; onplayMusicListener.playForFull(); selectItem = currentId; }}});// Music clip
		viewHolder.imageViewCut.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View view) {
				// TODO Auto-generated method stub
				currentMusic = music;
				musicCutPopupWindow = new MusicCutPopupWindow(context,
						itemsOnClick);
				// Set the music information
				musicCutPopupWindow.setMusicInfo(currentMusic.getSinger()
						+ "-" + currentMusic.getName(),
						currentMusic.getDuration());
				// Display window
				musicCutPopupWindow.showAtLocation(((MainActivity) context)
						.findViewById(R.id.mainActivity_root), Gravity.BOTTOM,
						0.0); }});return view;

	}
		
    // Implement listener classes for pop-ups
    private OnClickListener  itemsOnClick = new OnClickListener(){  
  
        public void onClick(View v) {  
        	
            switch (v.getId()) { 
            // Confirm button
            case R.id.popupWindow_music_cut_btn_sure:  
            	// Get the minimum value
            	float min=musicCutPopupWindow.getMinRule();
            	// Get the maximum value
            	float max=musicCutPopupWindow.getMaxRule();
            	// Start cutting music
            	if(currentMusic==null) {return;
            	}
            	// The path of the music to cut
            	String inputPath=currentMusic.getPath();
            	Date date=Calendar.getInstance().getTime();
            	SimpleDateFormat sdf= new SimpleDateFormat("yyyyMMddHHmmss");
            	String str=sdf.format(date);
            	// The path to the clipped music file
            	File sdDir = null;
        		boolean sdCardExist = Environment.getExternalStorageState().equals(
        				android.os.Environment.MEDIA_MOUNTED);// Check whether the SD card exists
        		if(! sdCardExist) { Toast.makeText(context,"SD card does not exist, save failed", Toast.LENGTH_SHORT).show();
        			return;
        			
        		}else{
        			sdDir = Environment.getExternalStorageDirectory();// Get the root directory
        		}
            	File flie=new File(sdDir +"/audio");
            	// The directory is automatically created when it does not exist
	            if(! flie.exists()){ flie.mkdirs(); } String outputPath=flie.getPath()+"/new"+"_"+currentMusic.getName()+".mp3"; 
            	File audioPath=new File(outputPath);
            	// Delete files as soon as they exist
            	if(audioPath.exists()){          		
            		try {
            			audioPath.delete();
						audioPath.createNewFile();
					} catch (IOException e) {
						// TODO Auto-generated catch blocke.printStackTrace(); }}boolean flag=MusicUtil.clipMp3(inputPath, outputPath, (int)min*1000, (int)max*1000);
            	if(flag){
            		Toast.makeText(context, "Clip successful, save path:"+outputPath, Toast.LENGTH_SHORT).show();
            		musicCutPopupWindow.dismiss();
            	}else{
            		Toast.makeText(context, "Editing failure", Toast.LENGTH_SHORT).show();
            	}
            	break; 
            // Cancel button
             case R.id.popupWindow_music_cut_btn_cancel:
            	// Close the popover
         		musicCutPopupWindow.dismiss();
         		// Reset the music
         		MusicPlayer.reset();
            	break;
             // Listen button
             case R.id.popupWindow_music_cut_tv_musicTest:
            	 cutMusicStartProgress=(long) ((int)musicCutPopupWindow.getMinRule()*1000);
            	 cutMusicEndProgress=(long) ((int)musicCutPopupWindow.getMaxRule()*1000);
            	 cutMusicPath=currentMusic.getPath();
            	 if(onplayMusicListener! =null){
            		 onplayMusicListener.playforPart();
            	 }
            	break; }}};class ViewHolder{
		TextView textViewName;
		TextView textViewSinger;
		TextView textViewDuration;
		ImageView imageViewPlay;
		ImageView imageViewPic;
		ImageView imageViewCut;
	}
	
	private Integer selectItem=-1;

	public Integer getSelectItem(a) {
		return selectItem;
	}

	public void setSelectItem(Integer selectItem) {
		this.selectItem = selectItem;
	}
	// Indicates whether to hide the play button
	private boolean hidePlayBtn;

	public void setHidePlayBtn(boolean hidePlayBtn) {
		this.hidePlayBtn = hidePlayBtn;
	}
	/** * Convert song time format *@param time
	 * @return* /
	  public static String formatTime(long time) {
	      if (time / 1000 % 60 < 10) {
	          String t = time / 1000 / 60 + : "0" + time / 1000 % 60;
	          return t;
	      } else {
	          String t = time / 1000 / 60 + ":" + time / 1000 % 60;
	          returnt; }}// Clip the song path
	private String cutMusicPath;
	// Start editing the song
	private long cutMusicStartProgress;
	// Edit the end of the song
	private long cutMusicEndProgress;
	public String getCutMusicPath(a) {
		return cutMusicPath;
	}
	public void setCutMusicPath(String cutMusicPath) {
		this.cutMusicPath = cutMusicPath;
	}			
	public long getCutMusicStartProgress(a) {
		return cutMusicStartProgress;
	}
	public void setCutMusicStartProgress(long cutMusicStartProgress) {
		this.cutMusicStartProgress = cutMusicStartProgress;
	}
	public long getCutMusicEndProgress(a) {
		return cutMusicEndProgress;
	}
	public void setCutMusicEndProgress(long cutMusicEndProgress) {
		this.cutMusicEndProgress = cutMusicEndProgress;
	}
	/** * Define the interface for playing music *@author admin
	 *
	 */
	private OnplayMusicListener onplayMusicListener;
	
	public void setOnplayMusicListener( OnplayMusicListener onplayMusicListener) {
		this.onplayMusicListener = onplayMusicListener;
	}

	public interface OnplayMusicListener{
		// Play the full song
		void playForFull(a);
		// Play snippets of songs
		void playforPart(a); }}Copy the code