第14天-03-音乐播放器

今天学习写一个简易音乐播放器。
首先新建一个项目,命名为MusicPlayer
看项目结构:在这里插入图片描述
ImusicService代码:

package com.glsite.musicplayer;

import java.util.List;

/**
 * @author glsite.com
 * @version $Rev$
 * @des ${TODO}
 * @updateAuthor $Author$
 * @updateDes ${TODO}
 */
public interface ImusicService {
    /**
     * 调用服务里面的播放逻辑
     *
     * 音乐资源路径集合
     * @param position
     *
     */
    public void callPlay(List<String>playList ,int position);

    /**
     * 调用停止播放的方法
     */
    public void callstop();
}

MainActivity代码:

package com.glsite.musicplayer;

import android.Manifest;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Environment;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;
import java.util.ArrayList;

public class MainActivity extends BaseActivity {

    private ListView mLv;
    private  ImusicService mImusicService;
    //public  static final String MP3DIR = Environment.getExternalStorageDirectory()+ "/Download/";
    public  static final String MP3DIR = Environment.getExternalStorageDirectory()+ "/qqmusic/song/";
    private ArrayList<String> mMp3List;
    private MyConn mConn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mLv = findViewById(R.id.lv);
        performCodeWithPermission("读取SD卡需要用到的权限", new PermissionCallback() {
            @Override
            public void hasPermission() {
                //如果有了读取权限,那么初始化播放列表
                initPlayList();
            }

            @Override
            public void noPermission() {

            }
        }, Manifest.permission.READ_EXTERNAL_STORAGE);
        Intent intent = new Intent(this, MusicPlayerService.class);
        startService(intent);
        mConn = new MyConn();
        bindService(intent, mConn,BIND_AUTO_CREATE);
        mLv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (mImusicService != null) {
                    mImusicService.callPlay(mMp3List,position);
                } else {
                    Toast.makeText(MainActivity.this,"还没有绑定服务吧", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
    private class MyConn implements ServiceConnection{

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder service) {
            mImusicService = (ImusicService) service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    }

    /**
     * 初始化播放列表
     */

    private void initPlayList() {
        File file = new File(MP3DIR);
        //用这个方法返回列表对象
        File[] files = file.listFiles();
        //建一个ArrayList来存各个文件名
        mMp3List = new ArrayList<>();
        //开始遍历
        for (File f : files){
            if(f.getName().endsWith(".mp3")){
                mMp3List.add(f.getAbsolutePath());
                System.out.println(f.getAbsoluteFile());
            }
        }
        mLv.setAdapter(new MusicListAdapter());
    }
    //如果加入菜单就要写相应的方法


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = new MenuInflater(this);
        inflater.inflate(R.menu.activity_main,menu);
        return super.onCreateOptionsMenu(menu);
    }
//这个是菜单选中事件的方法
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.item_setting) {
            //启动一个设置界面
            Intent intent = new Intent(this, SettingActivity.class);
            startActivity(intent);
        } else if (item.getItemId() == R.id.item_exit){
            //停止播放并退出
            playerExit();
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * 停止服务并退出
     */
    private void playerExit(){
        if(mImusicService != null){
            mImusicService.callstop();
        }
        if (mConn != null){
            unbindService(mConn);
            mConn = null;
        }
        Intent intent = new Intent(this, MusicPlayerService.class);
        stopService(intent);
        finish();
    }


    @Override
    protected void onDestroy() {
        playerExit();
        super.onDestroy();
    }

    private class MusicListAdapter extends BaseAdapter {
        @Override
        //列表内歌曲数量
        public int getCount() {
            return mMp3List.size();
        }
        //传入当前的对象

        @Override
        public Object getItem(int position) {
            return mMp3List.get(position);
        }
        //id

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view = View.inflate(MainActivity.this, R.layout.item_music, null);
            TextView tv_name = (TextView) view.findViewById(R.id.tv_item_name);
            String path = mMp3List.get(position);
            tv_name.setText(path.substring(path.lastIndexOf("/") + 1));
            return view;
        }
    }
}

MusicPlayerService代码:

package com.glsite.musicplayer;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.IBinder;

import java.io.IOException;
import java.util.List;

public class MusicPlayerService extends Service {

    public static final int MUSIC_STOP = 0;
    public static final int MUSIC_PLAYING = 1;
    public static final int MUSIC_PAUSE = 2;
    private SharedPreferences mSp;
    private MediaPlayer mMediaPlayer;
    public static  int playingstatus = 0;

    public MusicPlayerService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return new Mybinder();

    }

    @Override
    public void onCreate() {
        System.out.println("音乐播放器服务开启了");
        mSp = getSharedPreferences("config", MODE_PRIVATE);
        mMediaPlayer = new MediaPlayer();
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        System.out.println("音乐服务播放器关闭了");
        super.onDestroy();
    }
    private  class Mybinder extends Binder implements ImusicService{
        @Override
        public void callPlay(List<String> playList, int position) {
            play(playList,position);
        }

        @Override
        public void callstop() {
            stopPlayer();

        }
    }

    /**
     * 停止播放
     */

    private void stopPlayer() {
        if(mMediaPlayer != null){
            mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
        NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        nm.cancelAll();

    }

    /**
     * 播放音乐
     * @param playList
     * 所有音频播放列表
     * @param position
     * 当前播放的音频
     */

    private void play(final List<String> playList, final int position) {

        try {
            if(mMediaPlayer.isPlaying()){
                mMediaPlayer.stop();
            }
            mMediaPlayer.reset();
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            System.out.println(playList.get(position));
            mMediaPlayer.setDataSource(playList.get(position));
            mMediaPlayer.prepare();
            mMediaPlayer.start();
            String path = playList.get(position);
            showNotification(path.substring(path.lastIndexOf("/") + 1));
            mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    int mode = mSp.getInt("mode", 0);
                    if (mode == SettingActivity.CYCLE) {
                        play(playList,position);
                    } else if (mode == SettingActivity.NEXT){
                        //播放下一曲
                        int newposition = position+1;
                        if(newposition>playList.size()){
                            newposition = 0;
                        }
                        play(playList,newposition);
                    }else if (mode == SettingActivity.STOP){
                        //设置状态为停止
                        playingstatus = MUSIC_STOP;
                    }

                }
            });
        } catch (Exception e) {
            e.printStackTrace();
            playingstatus = MUSIC_STOP;

        }


    }

    /**
     * 显示播放器的音乐通知提醒
     * @param filename
     *        音乐名
     */

    private void showNotification(String filename) {
        int importance = NotificationManager.IMPORTANCE_LOW;
        //判断如果当前的sdk版本>=8.0
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            String id = "channel_1";
            NotificationChannel channel = new NotificationChannel(id, "123", importance);
            Notification noti = new Notification.Builder(this,id).setContentTitle("酷狗音乐正在播放")
                    .setContentText(filename)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher_round))
                    .build();
            NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            nm.createNotificationChannel(channel);
            nm.notify(0,noti);
        }
        //判断如果当前的sdk版本<8.0
        else{

            Notification noti = new Notification.Builder(this).setContentTitle("酷狗音乐正在播放")
                    .setContentText(filename)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher_round))
                    .build();
            NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            nm.notify(0,noti);
        }

    }
}

SettingActivity代码:

package com.glsite.musicplayer;

import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.RadioButton;
import android.widget.RadioGroup;

public class SettingActivity extends AppCompatActivity {

    public static final int CYCLE = 1;
    public static final int NEXT = 2;
    public static final int STOP = 3;
    private RadioGroup mRgMode;
    private SharedPreferences mSp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_setting);
        mRgMode = findViewById(R.id.rg_mode);
        mSp = getSharedPreferences("config", MODE_PRIVATE);
        //使用这个方法可以在下一次打开时保持上次离开时的状态,你懂吧
        //你想想看,如果不使用sp文件,那么点击返回会直接将当前activity结束,到时候返回值就是空
        int mode = mSp.getInt("mode", 0);
        RadioButton rb;
        switch (mode) {
            case CYCLE:
                rb = findViewById(R.id.rb_cycle);
                rb.setChecked(true);
                break;
            case NEXT:
                rb = findViewById(R.id.rb_next);
                rb.setChecked(true);
                break;
            case STOP:
                rb = findViewById(R.id.rb_stop);
                rb.setChecked(true);
                break;

            default:
                break;
        }


        mRgMode.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int checkedId) {
                SharedPreferences.Editor editor = mSp.edit();
                switch (checkedId) {
                    case R.id.rb_cycle:
                        editor.putInt("mode",CYCLE);
                        break;
                    case R.id.rb_next:
                        editor.putInt("mode",NEXT);
                        break;
                    case R.id.rb_stop:
                        editor.putInt("mode",STOP);
                        break;

                    default:
                        break;
                }
                editor.commit();

            }
        });
    }

}

layout下activi_main代码:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <ListView
        android:id="@+id/lv"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </ListView>

</android.support.constraint.ConstraintLayout>

activity_setting代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SettingActivity"
    android:orientation="vertical">

    <RadioGroup
        android:id="@+id/rg_mode"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <RadioButton
            android:id="@+id/rb_cycle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="单曲循环" />

        <RadioButton
            android:id="@+id/rb_next"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="下一曲" />

        <RadioButton
            android:id="@+id/rb_stop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="播放后停止" />
    </RadioGroup>
</LinearLayout>

item_music代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/tv_item_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:layout_marginLeft="5dp"
        android:text="歌曲名称"
        android:textColor="#99ff0000"
        android:paddingTop="5dp"
        android:paddingBottom="5dp"
        android:textSize="20sp"/>


    <ImageView
        android:layout_width="25dp"
        android:layout_height="25dp"
        android:layout_alignParentRight="true"
        android:layout_marginRight="5dp"
        android:layout_centerVertical="true"
        app:srcCompat="@mipmap/ic_launcher" />


</RelativeLayout>

menu下activity_main代码:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:id="@+id/item_setting"
        android:title="设置界面"/>
    <item android:id="@+id/item_exit"
        android:title="关闭播放器"/>


</menu>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像识别技术在病虫害检测中的应用是一个快速发展的领域,它结合了计算机视觉和机器学习算法来自动识别和分类植物上的病虫害。以下是这一技术的一些关键步骤和组成部分: 1. **数据收集**:首先需要收集大量的植物图像数据,这些数据包括健康植物的图像以及受不同病虫害影响的植物图像。 2. **图像预处理**:对收集到的图像进行处理,以提高后续分析的准确性。这可能包括调整亮度、对比度、去噪、裁剪、缩放等。 3. **特征提取**:从图像中提取有助于识别病虫害的特征。这些特征可能包括颜色、纹理、形状、边缘等。 4. **模型训练**:使用机器学习算法(如支持向量机、随机森林、卷积神经网络等)来训练模型。训练过程中,算法学习如何根据提取的特征来识别不同的病虫害。 5. **模型验证和测试**:在独立的测试集上验证模型的性能,以确保其准确性和泛化能力。 6. **部署和应用**:将训练好的模型部署到实际的病虫害检测系统中,可以是移动应用、网页服务或集成到智能农业设备中。 7. **实时监测**:在实际应用中,系统可以实时接收植物图像,并快速给出病虫害的检测结果。 8. **持续学习**:随着时间的推移,系统可以不断学习新的病虫害样本,以提高其识别能力。 9. **用户界面**:为了方便用户使用,通常有一个用户友好的界面,显示检测结果,并提供进一步的指导或建议。 这项技术的优势在于它可以快速、准确地识别出病虫害,甚至在早期阶段就能发现问题,从而及时采取措施。此外,它还可以减少对化学农药的依赖,支持可持续农业发展。随着技术的不断进步,图像识别在病虫害检测中的应用将越来越广泛。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值