Im trying to set up the MediaController so I can have controls when playing back audio but when I try to declare it the "this" is coming up as an error. What am I doing wrong?
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class MainActivity extends AppCompatActivity implements MediaRecorder.OnInfoListener {
private boolean cont;
private MediaRecorder mediaRecorder;
private MediaPlayer mediaPlayer;
private String OUTPUT_FILE;
private MediaController mediaController;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
OUTPUT_FILE = Environment.getExternalStorageDirectory()+"/androidaudio1.3gpp";
cont=true;
}
public void buttonClicked(View view){
switch (view.getId()){
case R.id.startRec:
beginRecord();
break;
case R.id.stopRec:
stopRecord();
break;
case R.id.startPlay:
try {
begginPlaying();
} catch (IOException e) {
e.printStackTrace();
}
break;
case R.id.stopPlay:
stopPlaying();
break;
}
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void begginPlaying() throws IOException {
if (mediaPlayer != null)
mediaPlayer.release();
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(OUTPUT_FILE);
mediaController = new MediaController(this);
mediaController.setMediaPlayer(this);
mediaController.show();
mediaPlayer.prepare();
mediaPlayer.start();
}
private void stopPlaying(){
if (mediaPlayer!= null){
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.release();
mediaPlayer=null;
}
#Override
public void start() {
mediaPlayer.start();
}
#Override
public void pause() {
mediaPlayer.pause();
}
#Override
public int getDuration() {
return mediaPlayer.getDuration();
}
#Override
public int getCurrentPosition() {
return mediaPlayer.getCurrentPosition();
}
#Override
public void seekTo(int pos) {
mediaPlayer.seekTo(pos);
}
#Override
public boolean isPlaying() {
return mediaPlayer.isPlaying();
}
#Override
public int getBufferPercentage() {
return 0;
}
#Override
public boolean canPause() {
return true;
}
#Override
public boolean canSeekBackward() {
return true;
}
#Override
public boolean canSeekForward() {
return true;
}
#Override
public int getAudioSessionId() {
return 0;
}
}
MediaController requires the context to be passed to the constructor. Without anymore code or knowing where you declared the MediaController, my best guess is that you don't have access to the context in the place where you declared the MediaController. Either pass the context from the activity where you would like to use the MediaController, or put this code in that activity.
https://developer.android.com/reference/android/widget/MediaController.html
EDIT:
I tried your code, check your imports & ensure you have, import android.widget.MediaController & not import android.media.session.MediaController.
Try this
if you are using in Activity then you can pass this
if you are using in Fragment then use getActivity() or context
and to set MediaController
use this code
video.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.setOnVideoSizeChangedListener(new OnVideoSizeChangedListener() {
#Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
/*
* add media controller
*/
mc = new MediaController(YourActivity.this);
video.setMediaController(mc);
/*
* and set its position on screen
*/
mc.setAnchorView(video);
}
});
}
});
Related
I have tried to create a barcode scanner in my application. But it doesn't show the camera, it shows a black screen last week, it still works. How can I solve this. My code is here
public class ScanBarcodeCartActivity extends AppCompatActivity {
private SurfaceView surfaceView;
private CameraSource cameraSource;
private TextView text_code,re_scan;
private Button btn_confirm_cart;
private BarcodeDetector barcodeDetector;
private String id_order;
private String phone;
private String cart,dateid,date;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan_barcode_cart);
surfaceView = findViewById(R.id.camera_preview);
text_code = findViewById(R.id.text_code);
btn_confirm_cart = findViewById(R.id.confirm_cart);
re_scan = findViewById(R.id.re_scan);
barcodeDetector = new BarcodeDetector.Builder(this)
.setBarcodeFormats(
Barcode.QR_CODE
).build();
cameraSource = new CameraSource.Builder(this,barcodeDetector)
.setRequestedPreviewSize(640,480).setAutoFocusEnabled(true).build();
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return;
}
try {
cameraSource.start(holder);
}catch (IOException e){
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
cameraSource.stop();
}
});
barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
#Override
public void release() {
}
#Override
public void receiveDetections(Detector.Detections<Barcode> detections) {
final SparseArray<Barcode> qrcode = detections.getDetectedItems();
if (qrcode.size() != 0) {
text_code.post(new Runnable() {
#Override
public void run() {
text_code.setText(qrcode.valueAt(0).displayValue);
}
});
}
}
});
}
}
I've tried many methods and still can't.
I don't know if it's because of the camera or surface view.
And thanks for the advice.
There will be a lot of code. I had to leave it for you to understand logic of an application.
Here is the MainActivity. Called on starting.
public class MainActivity extends AppCompatActivity {
private GameView gameView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//some unnecessary code
setContentView(R.layout.activity_main);
}
public void startSurvival(View view) {
gameView = new GameView(this, this, "survival");
setContentView(gameView);
}
public void chooseData(View view){
setContentView(new DView(this, this));
}
public void backToMenu(){
setContentView(R.layout.activity_main);
gameView = null;
}
#Override
protected void onResume() {
super.onResume();
try {
gameView.update();
} catch (NullPointerException e) {}
}
}
This Activity is a List of options. You choose one and then GameView sets as content View with appropriate parameters.
Here is no questions so I cut almost all the code.
public class DView extends ListView {
DView(final Context context, final MainActivity mainActivity){
super(context);
this.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String[] columns = {"data"};
String having = "id = " + ids[position];
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.query("levels", columns, null, null, ID, having, null);
if (cursor.moveToFirst()){
int dataInd = cursor.getColumnIndex(DATA);
mainActivity.setContentView(new GameView(context, mainActivity, cursor.getString(dataInd)));
}//everything here works fine. This just shows that setContentView can be done multiple times
//without bugs
cursor.close();
dbHelper.close();
}
});
}
}
And here comes the problem. When win() method is called display turns black. Application does not crash.
public class GameView extends SurfaceView{
public MainActivity mainActivity;
GameThread gameThread;
public Player player = null;
public Canvas canvas;
public ExtraData data;
public GameView (Context context, MainActivity mainActivity, String data){
super(context);
this.mainActivity = mainActivity;
if (data.equals("survival")) {
this.data = new ExtraData("RandomSpawn47",null, this);
} else {
this.data = new ExtraData("UsingData", data, this);
}
update();
}
void update(){
gameThread = new GameThread(this);
getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
gameThread.running(true);
if (gameThread.getState() == Thread.State.NEW)
gameThread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
gameThread.running(false);
}
});
if (player == null)
player = new Player(this);
}
public class GameThread extends Thread{
private GameView gameView;
public GameThread(GameView gameView) {
this.gameView = gameView;
}
public void running(boolean run){
running = run;
}
#Override
public void run() {
while (running){
canvas = null;
try{
canvas = gameView.getHolder().lockCanvas(null);
synchronized (gameView.getHolder()){
draw(canvas);
this.wait(45);
}
} catch(Exception e) {}
finally {
if((canvas != null)&&(running)){
gameView.getHolder().unlockCanvasAndPost(canvas);
}
}
}
}
}
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
canvas.drawColor(Color.BLUE);
data.onDraw();
}
public void win(){
mainActivity.backToMenu();//not switching the menu
}
}
Other classes like ExtraData and Player are not important.
GameThread and SurfaceView destroyes (I checked them with Logs in onDestroy() and in the end of run() method).
You are calling method of Activity from another class. Instead of mainActivity.backToMenu(), create one interface, implement it in MainActivity and pass the reference in GameView to initialize the interface. And where you are calling win method, call interface method instead of calling the public method of MainActivity.
Create one interface like:
public interface UpdateActivity{
void updateActivity();
}
In MainActivity
public class MainActivity extends AppCompatActivity implements UpdateActivity
then override the method of interface
void updateActivity(){
setContentView(R.layout.activity_main);
gameView = null;
}
Pass the reference in GameView instead of passing the MainActivity reference.
public GameView (Context context, UpdateActivity updateActivity , String data) {
super(context);
this.updateActivity = updateActivity ;
if (data.equals("survival")) {
this.data = new ExtraData("RandomSpawn47",null, this);
} else {
this.data = new ExtraData("UsingData", data, this);
}
update();
}
Now call the method where you want to call:
updateActivity.updateActivity();
I have a toggle button and i need the 'mp' sound to play every second if that button is toggled.The code below is what i tried and it does play the sound every second but the button stops responding so i can't turn it off.
ToggleButton btn = findViewById(R.id.button);
final MediaPlayer mp = MediaPlayer.create(this, R.raw.beat);
btn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
while (isChecked) {
mp.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thank you in advance.
Never use Thread.sleep(1000) it is the terrible thing you can do to the app. Your app is not
responsding because you are putting Main thread of app to sleep.
I have created this class for you for desmonstration. you can tweak is further to your needs.
private Handler soundHandler = new Handler();
private int delay = 1000;
private Runnable soundRunnable;
private MediaPlayer mediaPlayer;
private boolean isToggleChecked;
#Override protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ToggleButton toggleButton = findViewById(R.id.button);
mediaPlayer = MediaPlayer.create(this, R.raw.beat);
toggleButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked){
isToggleChecked = isChecked;
if(isChecked){
playSound();
}else {
stopSound();
}
}
});
}
#Override protected void onResume(){
super.onResume();
if(isToggleChecked){
playSound();
}
}
// this will make sure sound stops when app stops or goes in background
#Override
protected void onPause() {
soundHandler.removeCallbacks(soundRunnable);
super.onPause();
}
private void playSound(){
soundHandler.postDelayed(new Runnable() {
public void run() {
soundRunnable = this;
if(mediaPlayer != null) {
mediaPlayer.start();
}
soundHandler.postDelayed(soundRunnable, delay);
}
}, delay);
}
private void stopSound(){
if(mediaPlayer != null){
if(mediaPlayer.isPlaying()){
mediaPlayer.stop();
soundHandler.removeCallbacks(soundRunnable);
}
}
}
I found an answer to another question and modified it to fit my needs and now it works perfectly.Here is the solution/code.
public class MainActivity extends AppCompatActivity {
MediaPlayer mediaPlayer = null;
int delayMillis;
Handler handler;
Runnable runnable;
private boolean isToggleChecked;
private ToggleButton toggleButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toggleButton = findViewById(R.id.button);
handler = new Handler();
runnable = new Runnable() {
#Override
public void run() {
mediaPlayer.start();
}
};
toggleButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
isToggleChecked = true;
toggleMediaPlayer();
}
else {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer=null;
handler.removeCallbacks(runnable);
isToggleChecked = false;
}
}
});
}
#Override
public void onResume() {
super.onResume();
if (isToggleChecked) {
toggleButton.setChecked(true);
}
else {
toggleButton.setChecked(false);
}
}
private void toggleMediaPlayer(){
if(mediaPlayer != null){
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer=null;
handler.removeCallbacks(runnable);
}else{
mediaPlayer = MediaPlayer.create(this, R.raw.beat);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
delayMillis = 1000;
handler.postDelayed(runnable,delayMillis);
}
});
}
}
}
Im making a simple radio streaming app. Everything works great but having a few buggy issues.
When i press the home screen of my device i want the radio to carry on playing. which it does, But as soon as i go to my app history and re-open the app. It starts a new session. this make for a very Un-Pleasurble piece of music lol.
The app is very simple in the way it works i have a media player and a media controller which is attached to a surfaceView in my xml.
Can some one please tell me the correct way to fix this issue as this is the first time making an app that contains a live stream.
Thanks as always guys
my code for the media player and controller
public class radiostation extends AppCompatActivity implements SurfaceHolder.Callback, MediaPlayer.OnPreparedListener,
MediaController.MediaPlayerControl {
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private MediaPlayer mediaPlayer;
private MediaController mediaController;
private Handler handler = new Handler();
String videoSource =
"my radio station source address";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_radiostation);
surfaceView = (SurfaceView)findViewById(R.id.surface);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(mediaController != null){
mediaController.show();
}
return false;
}
});
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
Toast.makeText(radiostation.this,
"Media Controls active lets mash it up", Toast.LENGTH_LONG).show();
mediaPlayer = new MediaPlayer();
mediaPlayer.setDisplay(surfaceHolder);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnPreparedListener(this);
try {
mediaPlayer.setDataSource(videoSource);
mediaPlayer.prepare();
mediaController = new MediaController(this);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(radiostation.this,
"Radio Station off Air or no internet connection!\n" + e.toString(),
Toast.LENGTH_LONG).show();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder,
int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
Toast.makeText(radiostation.this,
"You are now connected ", Toast.LENGTH_LONG).show();
mediaController.setMediaPlayer(this);
mediaController.setAnchorView(surfaceView);
handler.post(new Runnable() {
public void run() {
mediaController.setEnabled(true);
mediaController.show();
}
});
}
#Override
public void start() {
mediaPlayer.start();
}
#Override
public void pause() {
mediaPlayer.pause();
}
#Override
public int getDuration() {
return mediaPlayer.getDuration();
}
#Override
public int getCurrentPosition() {
return mediaPlayer.getCurrentPosition();
}
#Override
public void seekTo(int pos) {
mediaPlayer.seekTo(pos);
}
#Override
public boolean isPlaying() {
return mediaPlayer.isPlaying();
}
#Override
public int getBufferPercentage() {
return 0;
}
#Override
public boolean canPause() {
return true;
}
#Override
public boolean canSeekBackward() {
return false;
}
#Override
public boolean canSeekForward() {
return false;
}
#Override
public int getAudioSessionId() {
return mediaPlayer.getAudioSessionId();
}
#Override
public void onBackPressed() {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer=null;
finish();
}
I am developing a media player app that has a bound service to an activity.It works fine when i press the home button or the app switcher and then come back to the app from the recent app, but as i press the back button the activity also ends the Music Service. Please guide me the exact steps that can solve these minor issues, so that i can give media controls to the app.My App has 2 main classes
MyActivity
AudioService
My code is given below.
AudioService.java
public class AudioService extends Service implements
MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener,
MediaPlayer.OnCompletionListener{
// -----------------------------------------Attributes--------------------------------------------------------
private ArrayList<File> songs;
private ArrayList<File> audio;
private MediaPlayer player;
private int songPosn;
private String name="";
private final IBinder musicBind = new AudioBinder();
private Uri trackUri;
private int NOTIFY_ID=1;
// -----------------------------------------------------------------------------------------------------------
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
public void onCreate(){
//create the service
//create the service
super.onCreate();
//initialize position
songPosn=0;
//create player
player = new MediaPlayer();
initMusicPlayer();
}
// to initialize the media class
public void initMusicPlayer(){
//set player properties
player.setWakeMode(getApplicationContext(),
PowerManager.PARTIAL_WAKE_LOCK);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setOnPreparedListener(this);
player.setOnCompletionListener(this);
player.setOnErrorListener(this);
}
public void setList(ArrayList<File> theSongs){
songs=theSongs;
}
public void setSong(int songIndex){
songPosn=songIndex;
}
public class AudioBinder extends Binder {
AudioService getService() {
return AudioService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return musicBind;
}
#Override
public boolean onUnbind(Intent intent){
player.stop();
player.release();
return false;
}
#Override
public void onCompletion(MediaPlayer mp) {
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mp.reset();
return false;
}
#Override
public void onPrepared(MediaPlayer mp) {
//start playback
mp.start();
showNotification();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId){
songPosn = intent.getIntExtra("pos",0);
audio=(ArrayList)intent.getParcelableArrayListExtra("songlist");
name = intent.getStringExtra("name");
Log.e("Service","name"+audio.get(0));
Log.e("Service","position "+songPosn);
return START_STICKY;
}
public void playSong(){
//play a song
player.reset();
Log.e("TRACH the URI",""+trackUri);
trackUri =Uri.parse(audio.get(songPosn).toString());
try{
player.setDataSource(getApplicationContext(), trackUri);
}
catch(Exception e){
Log.e("MUSIC SERVICE", "Error setting data source", e);
}
player.prepareAsync();
}
private void showNotification(){
Intent notIntent = new Intent(this, MyActivity.class);
notIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendInt = PendingIntent.getActivity(this, 0,
notIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder builder = new Notification.Builder(this);
builder.setContentIntent(pendInt)
.setTicker(name)
.setOngoing(true)
.setContentTitle("Playing")
.setContentText(name);
Notification not = builder.build();
startForeground(NOTIFY_ID, not);
}
#Override
public void onDestroy()
{
stopForeground(true);
}
}
MyActivity.java
public class MyActivity extends Activity {
// ***************************** Attributes Start ******************************************************
private ArrayList<File> myfiles= new ArrayList<File>();
private ListView listView;
private ArrayAdapter<String> adapter ;
private String name="";
private int position;
private AudioService musicSrv;
private Intent playIntent;
private boolean musicBound=false;
// ***************************** Attributes End ******************************************************
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
String toneslist[] ={"Airtel"
,"sherlock_theme"};
listView = (ListView) findViewById(R.id.listView);
adapter = new ArrayAdapter<String>(getApplication(),R.layout.list_item,R.id.list_textview,toneslist);
listView.setAdapter(adapter);
getMp3();
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
name =adapter.getItem(pos);
position =pos;
Log.e("MAINACTIVITY (clickListener) pos =",""+position+" name = "+name);
musicSrv.setSong(position);
musicSrv.playSong();
}
});
}
#Override
protected void onStart() {
super.onStart();
if(playIntent==null){
Log.e("MAINACTIVITY pos =",""+position+" name = "+name);
playIntent = new Intent(this, AudioService.class).putExtra("pos",position).putExtra("songlist", myfiles).putExtra("name", name);
bindService(playIntent, audioConnection, Context.BIND_AUTO_CREATE);
startService(playIntent);
}
}
private ServiceConnection audioConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
AudioService.AudioBinder binder = (AudioService.AudioBinder)service;
musicSrv = binder.getService();
musicSrv.setList(myfiles);
musicBound = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
musicBound = false;
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.my, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void getMp3(){
String s=(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC)).toString();
// s="content://media/external/audio/media";
GetFiles(s);
}
private void GetFiles(String path) {
File file = new File(path);
File[] allfiles = file.listFiles();
if (allfiles.length == 0) {
} else {
for (int i = 0; i < allfiles.length; i++)
{
Log.e("FFFFFFFFF", allfiles[i].getName().toString());
myfiles.add(allfiles[i]);
}
}
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onDestroy() {
stopService(playIntent);
musicSrv=null;
super.onDestroy();
}
}
Try with this in your Activity:
#Override
public void onDestroy(){
if (!isChangingConfigurations()) stopService(new Intent (this, YourService.class));
super.onDestroy();
}
#Override
public void onBackPressed(){
if (mediaIsPlaying) moveTaskToBack(true);
else super.onBackPressed();
}