1

I have an Player activity and Floating Player (service), after click on back button the Player Activity is close and the Floating Player is goes into action, when I click on the Floating Player I want to back to the Player Activity but with no run again the onCreate method.

I read a lot of solution in StackOver Flow, especially use the FLAG_ACTIVITY_CLEAR_TOP and FLAG_ACTIVITY_SINGLE_TOP flags, or add android:launchMode="singleTask" / android:launchMode="singleInstance" to the Player Activity in the Manifest, but none of them not really work.

I would be happy if there is a real solution that make a single task to my Player Activity, and not reopen it from onCreate method.

Player Activity:

public class MainActivity extends AppCompatActivity {

    private WebView webView;

    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        webView = findViewById(R.id.webView);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.loadUrl("https://www.youtube.com/embed/bWsIJ7UVxQs");
        Toast.makeText(this, "onCreate is running!", Toast.LENGTH_SHORT).show();

    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        startService(new Intent(MainActivity.this, WindowPlayer.class));
    }
}

Floating player (service):

public class WindowPlayer extends Service {

    private WindowManager windowManager;
    private View contFloatingPlayer;
    private WindowManager.LayoutParams contPlayerParams;
    private WebView webView;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    @SuppressLint("ClickableViewAccessibility")
    @Override
    public void onCreate() {
        super.onCreate();
        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        initFloatingPlayer();

        webView.loadUrl("https://www.youtube.com/embed/bWsIJ7UVxQs");

        webView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                contFloatingPlayer.setVisibility(View.GONE);
                webView.destroy();
                return false;
            }
        });

        webView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction() & MotionEvent.ACTION_MASK) {
                    case MotionEvent.ACTION_UP:
                        Intent backToStablePlayer = new Intent(getApplicationContext(), MainActivity.class);
                        backToStablePlayer.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                                Intent.FLAG_ACTIVITY_CLEAR_TOP |
                                Intent.FLAG_ACTIVITY_SINGLE_TOP);
                        startActivity(backToStablePlayer);
                }
                return false;
            }
        });
    }

    @SuppressLint({"ClickableViewAccessibility", "SetJavaScriptEnabled", "AddJavascriptInterface"})
    private void initFloatingPlayer() {
        int LAYOUT_FLAG;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        } else {
            LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
        }

        contPlayerParams = new WindowManager.LayoutParams(
                532,
                300,
                LAYOUT_FLAG,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT);

        contPlayerParams.gravity = Gravity.TOP | Gravity.LEFT | Gravity.START;
        contPlayerParams.x = 0;
        contPlayerParams.y = 100;

        contFloatingPlayer = LayoutInflater.from(this).inflate(R.layout.activity_main, null, false);

        windowManager.addView(contFloatingPlayer, contPlayerParams);

        webView = contFloatingPlayer.findViewById(R.id.webView);

        webView.getSettings().setJavaScriptEnabled(true);

    }

Note: I added Intent.FLAG_ACTIVITY_NEW_TASK to the intent because it's intent from service, else it's crash.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Hila
  • 33
  • 2
  • when an activity is destroyed then you can't bring it back and not go through onCreate. Why is it a problem? What are you trying to avoid? – Nikos Hidalgo Oct 02 '19 at 10:19

2 Answers2

1

I guess the problem is that when you click "back", the Activity's finish() method is called, the Activity is destroyed and so the next time you launch it it will go to onCreate(). You can try this in MainActivity.class:

@Override
public void onBackPressed() {
    //super.onBackPressed();  // don't call the super
    goToHomeScreen();
    startService(new Intent(MainActivity.this, WindowPlayer.class));
}


public void goToHomeScreen() {
    Intent startMain = new Intent(Intent.ACTION_MAIN);
    startMain.addCategory(Intent.CATEGORY_HOME);
    startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(startMain);
}

This way when you go back to your app, the Activity is not destroyed and it will not go to onCreate().

Yoav Gibri
  • 158
  • 5
  • Very nice Yoav! In my real app i need to back to MainActivity.Class, and not to Home, how can i adjust it? – Hila Oct 02 '19 at 11:04
  • @Hila Isn't the player activity called MainActivity? Anyway, in your player activity, instead of goToHome() method you can launch your MainActivity like in Danial's answer. – Yoav Gibri Oct 02 '19 at 11:16
  • In my question i added an example code.. in my real app there is A.class, B.class and C.class, how can i go back to B.class from C.class on your way in the answer – Hila Oct 02 '19 at 12:44
  • Only one solution working like a charm. App is minimized on back (as user expects but on resume finally it is not restarted). Thanks. Many other on stackoverflow like https://stackoverflow.com/a/23220151/3826175 and do not work. My modification with webview... `public void onBackPressed() { if (webView.canGoBack()) { webView.goBack(); } else { Intent startMain = new Intent(Intent.ACTION_MAIN); startMain.addCategory(Intent.CATEGORY_HOME); startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(startMain); } }` – mikep May 10 '22 at 06:10
0

Try this

 Intent intent = new Intent(A.this, B.class);
                    // to restore activity if there already running
                    intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);  
                    startActivity(intent);

And In manifest of add for B activity

android:launchMode="singleInstance"
Danial clarc
  • 724
  • 1
  • 7
  • 25
  • I tried it, not working, it's still run the onCreate method. the point is exactly what Yoav said, the onBack method is destroy the activity... – Hila Oct 02 '19 at 12:34