본문 바로가기

아옳옳의 코딩공부/아옳옳의 안드로이드스튜디오

2021-03-31안드로이드 스튜디오(브로드캐스트 와 서비스이용 예제2)

반응형

어제의 예제 연장선이라 생각해볼수 있다 

 

이렇게 플레이 버튼을 누르면 노래를 시작하고 정지 버튼을 누르면 노래를 정지 시킬것이다.. 

그럼과 동시에 프로그래스 바가 이동하며 움직이는 프로그램을 작성해볼것이다. 

 

메인액티비티 

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    ImageView playbtn, stopbtn;
    ProgressBar progressBar;
    TextView textView;
    String filePath;
    boolean runThread = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        playbtn= findViewById(R.id.lab1_play);
        stopbtn= findViewById(R.id.lab1_stop                );
        progressBar= findViewById(R.id.lab1_progress);
        textView= findViewById(R.id.lab1_title);

        playbtn.setOnClickListener(this);
        stopbtn.setOnClickListener(this);
        stopbtn.setEnabled(false); //버튼 활성화 할것인지 말것인지 (false : 못씀 , true : 사용가능)

        // 엠피쓰리 파일 위치정보를 담고있다 // 옆에(디바이스) 눌러서 아래 주소에 업로드 해줌 넣어줬다
        filePath = "data/data/com.example.playmusicservice/sample.mp3";

        //위험권한을 허용했는지 물어본다 //처음엔 무조건 허용하지 않았으니 , ActivityCompat.requestPermissions 이걸로
        //Manifest.permission.READ_EXTERNAL_STORAGE 이거에 대한 허용권한을 물어보게 된다
        if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(this , new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},100);
        }
        // 1 . 서비스로 filePath 전달해주기
        Intent intent =new Intent(this , PlaySevice.class);
        intent.putExtra("filePath",filePath);
        startService(intent);

        //리시버 등록
        registerReceiver(receiver , new IntentFilter("com.example.PLAY_TO_ACTIVITY"));
    }

    //4.  그 어떤 버튼이 눌렸는지에 따라 실행
    @Override
    public void onClick(View v) {

        if(v== playbtn){
            Intent intent = new Intent("com.example.PLAY_TO_SERVICE"); // 4-1 액션값을 가진 인텐트 생성
            intent.putExtra("mode", "start"); // 4-2 데이터 저장 해주고
            sendBroadcast(intent); //4-3 브로드캐스트로 보내줌

            runThread = true; //  8 . 쓰레드 컨트롤하기 위한 boolean 값
            ProgressThread thread = new ProgressThread(); // 9 쓰래드 생성
            thread.start(); // 스레드 시작
            playbtn.setEnabled(false); //  플레이버튼 비활성화
            stopbtn.setEnabled(true); //  플레이버튼 활성화
        }else {
            Intent intent = new Intent("com.example.PLAY_TO_SERVICE");
            intent.putExtra("mode", "stop");
            sendBroadcast(intent);
            runThread = false;
            progressBar.setProgress(0);
            playbtn.setEnabled(true);
            stopbtn.setEnabled(false);
        }

    }
    //7 . 서비스에서 보낸 방송 수신함
    BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String mode = intent.getStringExtra("mode");
            if(mode!=null){
                if(mode.equals("start")){ // 안 내용물이 같은 글자인지 보고 참 거짓
                    int duration = intent.getIntExtra("duration",0);
                    progressBar.setMax(duration); // 프로그래스바 길이를 음악의 길이와 맞춤
                    progressBar.setProgress(0); // 프로그래스바 0으로 셋팅
                }else if(mode.equals("stop")){
                    runThread=false;
                    progressBar.setProgress(0);
                    playbtn.setEnabled(true);
                    stopbtn.setEnabled(false);
                }
            }
        }
    };

    // 9 . 실행의 흐름을 다르게 해줄 쓰레드 클래스
    class ProgressThread extends Thread{
        @Override
        public void run() {
            while (runThread){
                progressBar.incrementProgressBy(1000);
                SystemClock.sleep(1000);
                if(progressBar.getProgress()==progressBar.getMax()){
                    progressBar.setProgress(0);
                    runThread =false;
                }
            }

            //super.run(); 자동생성되는 데 필요없다
        }
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }

}

서비스 

public class PlaySevice extends Service implements MediaPlayer.OnCompletionListener {
    MediaPlayer player;
    String filePath;
    public PlaySevice() {
    }
    //2 . 서비스 생성되면 제일먼저 실행되는 메소드
    //    생성되면 아래 메소드 실행 되면서 리시버 등록
    @Override
    public void onCreate() {
        super.onCreate();
        //생성되면서 리시버 등록
        registerReceiver(receiver,new IntentFilter("com.example.PLAY_TO_SERVICE"));
    }
    // 3. 서비스 생명주기에 따라 2번 다음으로 3번 실행
    // 매번 보내는 주소 값이 달라질수 있으니 서비스 실행 될때마다 파일패스에 그 엠피쓰리 저장
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        filePath = intent.getStringExtra("filePath");

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    // 5. 메인에서 보낸 방송을 수신
    BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            //수신한 데이터 받아 작업
            String mode = intent.getStringExtra("mode");
            if(mode!=null){
                if(mode.equals("start")){
                    try {
                        if(player!= null &&player.isPlaying()) {// 플레이되고 있는 상황이라면
                            player.stop(); //멈추고
                            player.release(); // 리셋
                            player=null;  // 리셋
                        }
                        player = new MediaPlayer();
                        player.setDataSource(filePath); // 데이터 넣기
                        player.prepare(); // 실행
                        player.start(); // 실행

                        // 6. 메인으로 방송 송출
                        Intent intent2 = new Intent("com.example.PLAY_TO_ACTIVITY");
                        intent2.putExtra("mode" , "start");
                        intent2.putExtra("duration", player.getDuration()); // 파일의 길이 듀레이션 보내주기
                        sendBroadcast(intent2); //메인의 프로그래스바를 실행하기위하여 다시 브로드 캐스드 송신
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }else if (mode.equals("stop")) { //스탑에 관한
                    if(player!= null &&player.isPlaying()) {// 플레이되고 있는 상황이라면
                        player.stop(); //멈추고
                        player.release(); // 리셋
                        player=null;  // 리셋
                    }
                }
            }

        }
    };


    @Override// 미디어 플레이어가 재생완료시 콜백 메소드
    public void onCompletion(MediaPlayer mp) {
        Intent intent = new Intent("com.example.PLAY_TO_ACTIVITY");
        intent.putExtra("mode","stop");
        sendBroadcast(intent);
        stopSelf();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }
}

순서대로 주석처리 되어있으니 참조하면 되겠다~ 

반응형