I'm using a simple activity (from this library) with ZXing to scan a barcode.
Everything works fine, but the transition between the MainActivity and the ScannerActivity doesn't work well. Halfway through it gets interrupted. When going back from the ScannerActivity to the MainActivity the transition works like desired. Only while loading the barcodescanner it doesn't look really good.
Do you have any idea how to fix this?
MainActivity:
private void invokeScanner() {
try {
Intent intent = new Intent(this, ScannerActivity.class);
stealFocus(et_loadInput);
startActivityForResult(intent,0);
this.overridePendingTransition(R.anim.detail_anim_up, R.anim.detail_anim_down);
} catch (Exception e){
Log.e(TAG, "couldn't open scanner");
e.printStackTrace();
openAlertDialog(Const.MSG_PROCESSING_ERROR);
}
}
ScannerActivity:
public class ScannerActivity extends AbstractTitleBarActivity implements ZXingScannerView.ResultHandler{
private ZXingScannerView mScannerView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mScannerView = new ZXingScannerView(this);
setContentView(mScannerView);
this.tv_backTitle.setText(getString(R.string.TITLE_SEARCH_VIEW));
this.tv_heading.setText("");
TextView titleClose = (TextView) findViewById(R.id.btn_close);
titleClose.setVisibility(View.VISIBLE);
titleClose.setOnClickListener(titleCloseListener);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
#Override
public void onResume() {
super.onResume();
mScannerView.setResultHandler(this); // Register ourselves as a handler for scan results.
mScannerView.startCamera(); // Start camera on resume
}
#Override
public void onPause() {
super.onPause();
mScannerView.stopCamera(); // Stop camera on pause
}
#Override
protected boolean isBackBtnVisible() {
return false;
}
#Override
protected boolean isLogoVisible() {
return false;
}
#Override
public void handleResult(Result rawResult) {
Log.v(TAG, rawResult.getText()); // Prints scan results
Log.v(TAG, rawResult.getBarcodeFormat().toString()); // Prints the scan format (qrcode, pdf417 etc.)
MainActivity.scanVal = rawResult.toString();
MainActivity.loadVal = MainActivity.scanVal;
finish();
overridePendingTransition(R.anim.detail_anim_back_down,R.anim.detail_anim_back_up);
}
// listener for close button
protected TextView.OnClickListener titleCloseListener = new TextView.OnClickListener() {
public void onClick(View v) {
finish();
overridePendingTransition(
R.anim.detail_anim_back_down, R.anim.detail_anim_back_up);
}
};
}
I actually solved my own problem :D with this answer.
I just put the ZXingScannerView into a fragment and added a surface view with 0px height as a sibling. Now the animation works fine and the barcode scanner loads without refreshing the complete activity.
Related
Currently working on an app in Android Studio to play music from a live audio source. I got the play and pause button to work for certain url's such as this, which may only work either because it's http. However, when doing it with this link, which is live audio from a college radio station, it doesn't play anything (the static when the station is not on can't be heard in the app).
My code is below:
public class RadioSelection extends AppCompatActivity {
ImageView fm;
ImageView digital;
MediaPlayer mediaPlayer;
ImageView playPause;
String stream = "http://wmuc.umd.edu:8000/wmuc-hq";
boolean prepared = false;
boolean started = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_radio_selection);
mediaPlayer=new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
new PlayerTask().execute(stream);
playPause = findViewById(R.id.play_pause);
fm = findViewById(R.id.fm);
digital = findViewById(R.id.digital);
playPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (started) {
started = false;
mediaPlayer.pause();
Toast.makeText(RadioSelection.this, "Paused", Toast.LENGTH_SHORT).show();
} else {
started = true;
mediaPlayer.start();
Toast.makeText(RadioSelection.this, "Playing", Toast.LENGTH_SHORT).show();
}
}
});
fm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
digital.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
private class PlayerTask extends AsyncTask<String, Void, Boolean> {
#Override
protected Boolean doInBackground(String... strings) {
try {
mediaPlayer.setDataSource(strings[0]);
mediaPlayer.prepare();
prepared = true;
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("It's prepared!");
return prepared;
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
}
}
#Override
protected void onPause() {
super.onPause();
if (started) {
mediaPlayer.pause();
}
}
#Override
protected void onResume() {
super.onResume();
if (started) {
mediaPlayer.start();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (prepared) {
mediaPlayer.release();
}
}
}
I feel like it has to do with the protocol but I'm not sure, and I don't really know of a way to test if it actually successfully connected to the audio source. I'd really appreciate any help.
How to play android radio with screen off background playable option. My App working fine without backgournd playing option. But I want to give background playing option in my app that is when user closes the app, the radio should keep on playing, untill user stops it.
I am also disable screen off option in xml file with android:keepScreenOn="true" option but I want to remove this option and keep mobile screen off and play my app in background.
This is my code
Button BPlay;
String stream = "http://stream.zeno.fm/hmzuvfwn9k0uv";
MediaPlayer mediaPlayer;
boolean prepared = false;
boolean started = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_radio);
BPlay = (Button) findViewById(R.id.b_play);
BPlay.setEnabled(false);
BPlay.setText("Loading.....");
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
new PlayerTask().execute(stream);
BPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (started){
started = false;
mediaPlayer.pause();
BPlay.setText("PLAY");
} else {
started = true;
mediaPlayer.start();
BPlay.setText("PAUSE");
}
}
});
}
class PlayerTask extends AsyncTask<String, Void, Boolean> {
#Override
protected Boolean doInBackground(String... strings) {
try {
mediaPlayer.setDataSource(strings [0]);
mediaPlayer.prepare();
prepared = true;
} catch (IOException e) {
e.printStackTrace();
}
return prepared;
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
BPlay.setEnabled(true);
BPlay.setText("PLAY");
}
}
#Override
protected void onPause() {
super.onPause();
if (started){
mediaPlayer.pause();
}
}
#Override
protected void onResume() {
super.onResume();
if (started){
mediaPlayer.start();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (prepared){
mediaPlayer.release();
}
}
}
In order to have you media playing while the app is in the background, you'll need a MediaSession background Service running in parallel.
TLTR, here's a basic tutorial from Google on how to do that.
this is my base activity that extends class activity. I make my other activities extend this base class:
public abstract class Base extends Activity {
private BroadcastReceiver netStateReceiver;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutResourceId());
}
protected abstract int getLayoutResourceId();
#Override
protected void onPause() {
if (netStateReceiver != null) {
unregisterReceiver(netStateReceiver);
netStateReceiver = null;
}
super.onPause();
}
#Override
protected void onResume() {
if (netStateReceiver == null) {
netStateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(final Context context, Intent intent) {
final Dialog offline = new Dialog(context, android.R.style.Theme_Light);
//A change occurred in connection state. Check whether user has been become online or offline:
if (!CheckNet()) {
//User became offline (show offline dialog):
offline.setContentView(R.layout.activity_offline);
offline.setTitle("offline");
offline.getWindow().setBackgroundDrawableResource(R.color.transparent);
offline.show();
final Button retry = (Button) offline.findViewById(R.id.button6);
retry.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (CheckNet()) {
offline.dismiss();
}
}
});
}
else {
//User became online (dismiss offline dialog):
if (offline.isShowing()) {
offline.dismiss();
}
}
}
};
registerReceiver(netStateReceiver, new IntentFilter(Values.CONNECTIVITY_RECEIVER_ACTION));
}
super.onResume();
}
private boolean CheckNet() {
final ConnectivityManager conMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkInfo activeNetwork = conMgr.getActiveNetworkInfo();
return (activeNetwork != null && activeNetwork.isConnectedOrConnecting());
}
}
As you see in code I have registered a receiver for checking connectivity status.
I want when user becomes offline a dialog be shown to user and notify him that he is offline and should become online to continue. This part works good.
I also want when that dialog is showing and in the moment user becomes online this dialog be dismissed, but this part doesn't work and dialog stays on the display.
What's the problem, how can I dismiss the dialog?
You create a new dialog on every broadcast instead of using the dialog you already created before.
Make the dialog variable a member variable of the activity class, then it should work.
private Dialog offline;
#Override
protected void onResume() {
if (netStateReceiver == null) {
netStateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(final Context context, Intent intent) {
if (!CheckNet()) {
if(offline==null || !offline.isShowing()){
offline = new Dialog(context, android.R.style.Theme_Light);
}
...
} else {
//User became online (dismiss offline dialog):
if (offline!=null && offline.isShowing()) {
offline.dismiss();
}
}
Make it global access to your dialog object reference :
final Dialog offline = new Dialog(context, android.R.style.Theme_Light);
Then you will able to close your dialog.
You are creating a new dialog everytime you receive a broadcast, so the dialog you dismissed is a whole different dialog than the one used to show "you are currently offline".
Try putting your "offline" dialog in the activity instead of within the onReceive callback.
A simple example would be:
public abstract class Base extends Activity {
private BroadcastReceiver netStateReceiver;
final Dialog offline;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutResourceId());
// You create the dialog here instead within the onReceive callback
offline = new Dialog(this, android.R.style.Theme_Light);
offline.setContentView(R.layout.activity_offline);
offline.setTitle("offline");
offline.getWindow().setBackgroundDrawableResource(R.color.transparent);
}
#Override
protected void onResume() {
if (netStateReceiver == null) {
netStateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(final Context context, Intent intent) {
if (!CheckNet()) {
// Your dialog already exists, just show it immediately
offline.show();
final Button retry = (Button) offline.findViewById(R.id.button6);
retry.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (CheckNet()) {
offline.dismiss();
}
}
});
}
else {
//User became online (dismiss offline dialog):
if (offline.isShowing()) {
offline.dismiss();
}
}
}
};
registerReceiver(netStateReceiver, new IntentFilter(Values.CONNECTIVITY_RECEIVER_ACTION));
}
super.onResume();
}
}
I built app to play audio from internet, I use service to play audio in background, the question is how to show loding dialog while media player is in preparing posision in service(background) hire my Code.
Activity
package com.uqifm.onlineradio;
.......
public class MainActivity extends AppCompatActivity {
Button b_play;
Boolean started = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b_play = (Button) findViewById(R.id.b_play);
b_play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(started){
started = false;
stopService(new Intent(MainActivity.this,MyService.class));
b_play.setText("PLAY");
}else{
started = true;
startService(new Intent(MainActivity.this,MyService.class));
b_play.setText("STOP");
}
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
stopService(new Intent(MainActivity.this,MyService.class));
}
}
Service
package com.uqifm.onlineradio;
....................
public class MyService extends Service {
MediaPlayer mediaPlayer;
String stream = "http://xxxxx:36365";
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.setDataSource(stream);
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mediaPlayer.start();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
mediaPlayer.release();
}
}
Register broadcasts, Start a ProgressDialog before you start the service. Then wait for the broadcast. After the broadcast, hide the dialog. see example in this thread. Send data from Service back to my activity
Put a ProgressDialog in xml and set the visibility according to your requirement. Use interface for communicating with service.
You can use Broadcast or try EventBus which is much more easier. You can post an event from the service using EventBus and receive the the broadcast in MainActivity and update the progress dialogue.
Please follow the link.
Maybe something like this:
fun playAudio(audioUrl: String){
showProgressBar()
var mediaPlayer: MediaPlayer? = MediaPlayer().apply {
setAudioStreamType(AudioManager.STREAM_MUSIC)
setDataSource(audioUrl)
prepareAsync() // might take long! (for buffering, etc)
}
mediaPlayer?.setOnPreparedListener {
hideProgressBar()
it.start()
}
mediaPlayer?.setOnCompletionListener {
mediaPlayer.release()
}
}
I have designed a splash screen with a button. The Java code is as below. The layout of the splash contains some texts with animation and button named skipped splash screen. When the user presses the button, the splash screen has to stop immediately and open the next activity. But when I open the splash screen and press skip button, the next activity opens but after the duration for which splash screen has to run gets over, again the activity opens. How to stop the splash screen when a user presses the skip button?
public class Qz1 extends Activity {
TextView a;
TextView b;
TextView c;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_qz1);
a =(TextView)findViewById(R.id.roundOnea22);
a.startAnimation(AnimationUtils.loadAnimation(Qz1.this, R.anim.anim_slide_in_left));
b =(TextView)findViewById(R.id.roundOneb);
b.startAnimation(AnimationUtils.loadAnimation(Qz1.this, R.anim.anim_slide_in_right));
c =(TextView)findViewById(R.id.roundme);
c.startAnimation(AnimationUtils.loadAnimation(Qz1.this, R.anim.anim_slide_in_left));
Thread thread = new Thread(){
#Override
public void run() {
// TODO Auto-generated method stub
try{
sleep(3200);
startActivity(new Intent(getApplicationContext(), Qone.class));
} catch (InterruptedException e){
e.printStackTrace();
}
}
};
thread.start();
}
public void round1(View v){
Intent i = new Intent(Qz1.this, Qone.class);
startActivity(i);
}
}
Let's suppose you want to keep your first activity in the background, but you do not want the thread to re-open the second activity as soon as it has finished sleeping.
In order to achieve that, you can make your "thread" a global variable of a custom Thread class. You can define this as an inner class of your activity:
MyThread thread;
and the class definition:
private class MyThread extends Thread
{
public boolean bRun = true;
#Override
public void run()
{
try
{
sleep(3200);
if (bRun)
{
startActivity(new Intent(getApplicationContext(), Activity2.class));
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
In onCreate(), you write
thread = new MyThread();
thread.start();
Then you can change your "onClick" method like this:
public void round1(View v){
if (thread != null && thread.isAlive())
{
thread.bRun = false;
}
Intent i = new Intent(Qz1.this, Qone.class);
startActivity(i);
}
This will keep the thread from starting the second activity, if it has been started by clicking the button.
Shouldn't be using sleep(2000)
use an animationlistener (http://developer.android.com/reference/android/view/animation/Animation.AnimationListener.html)
when onAnimationEnd is triggered call startActivity.
I think best practice here would be to use a Handler.
You can do it like this:
public class Test extends AppCompatActivity{
private Handler handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Settign the splashscreen with the button i suppose
setContentView(R.id.splashcreen);
}
#Override
protected void onStart() {
super.onStart();
handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
startNextActivity();
}
}, 2000);
}
public void startNextActivity(){
startActivity(new Intent(getApplicationContext(), Qone.class));
}
public void skipSplashScreen(){
if (handler != null)
handler.removeCallbacksAndMessages(null);
startNextActivity();
}
#Override
protected void onStop() {
super.onStop();
// clear handler on stop
if (handler != null)
handler.removeCallbacksAndMessages(null);
}
}
CAll skipSplashScreen() when user press the button and the handler will stop so the timer stops and you go to next activity manually by calling method startNextActivity().
It's best practice to use Async Tasks for wait/sleep scenarios, such as for splash screens, but requirements can differ.
Anyway this is my way to call a splash screen:
Create the AsyncTask first.
private class SplashTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
finish();
Intent intent = new Intent(SplashActivity.this,
MainActivity.class);
startActivity(intent);
}
}
}
Then call this where ever you want: on button click, on start, or on create:
new SplashTask().execute();
try this in the splash activity
Button button = (Button)findViewById(R.id.buttonLayout);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(this,TargetActivity.class));
finish();
}
});