2

When you visit a website in Chrome and play a <audio> element, chrome adds a notification with a play/pause btn to the notifications area. Is it possible to do the same with a webview app?

I've managed to get things up and running in Android Studio, but can't figure out the notification thing

Any pointers?

Edit: Here's an example of what I mean: https://developers.google.com/web/updates/2015/07/media-notifications Is that even possible?

user1525
  • 157
  • 7
  • My best assumption for what I have gathered for the same issue is that you should use evaluateJavascript() and inject/get – DrBrad Nov 13 '17 at 14:44

1 Answers1

3

Here's an example that I made, this is allot for StackOverflow but there's no documentation for this. https://gist.github.com/DrBrad/7574712c6140ccc468212afa04d9e458

Put this in the WebChromeClient.java

@Override
public void onProgressChanged(final WebView view, int newProgress){
    super.onProgressChanged(view, newProgress);
    if(newProgress == 100){

        String code = "var videoElement;" +
                "for(var i = 0; i < document.getElementsByTagName('video').length; i++){" +
                "    var vid = document.getElementsByTagName('video')[0];" +
                "    vid.onplay = function(){" +
                "        videoElement = vid;" +
                "        JSOUT.videoAction('true');" +
                "    };" +
                "    vid.onpause = function(){" +
                "        videoElement = vid;" +
                "        JSOUT.videoAction('false');" +
                "    };" +
                "}";
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
            wv.evaluateJavascript(code, null);
        }else{
            wv.loadUrl("javascript:"+code);
        }
    }
}

Put this in the JSInterface.java

public class JSInterface {

    public static boolean playing;

    @JavascriptInterface
    public void videoAction(String type){
        Log.e("Info", type);

        playing = Boolean.parseBoolean(type);

        if(playing){
            NotificationManager mNotificationManager = (NotificationManager) activity.getSystemService(Context.NOTIFICATION_SERVICE);
            Notification.Builder builder = new Notification.Builder(activity);
            Notification notification = builder.getNotification();
            notification.icon = R.drawable.icon;

            RemoteViews contentView = new RemoteViews(activity.getPackageName(), R.layout.custom_notification);
            notification.contentView = contentView;
            notification.flags |= Notification.FLAG_ONGOING_EVENT;

            contentView.setTextViewText(R.id.title, "Browser");
            contentView.setTextViewText(R.id.desc, "This is a description. - PLAYING");
            contentView.setImageViewResource(R.id.pausePlay, R.drawable.pause);

            PendingIntent pendingSwitchIntent = PendingIntent.getBroadcast(activity, 0, new Intent(activity, NotificationPausePlay.class), 0);
            contentView.setOnClickPendingIntent(R.id.pausePlay, pendingSwitchIntent);

            mNotificationManager.notify(99, notification);


        }else{
            NotificationManager mNotificationManager = (NotificationManager) activity.getSystemService(Context.NOTIFICATION_SERVICE);
            Notification.Builder builder = new Notification.Builder(activity);
            Notification notification = builder.getNotification();
            notification.icon = R.drawable.icon;

            RemoteViews contentView = new RemoteViews(activity.getPackageName(), R.layout.custom_notification);
            notification.contentView = contentView;
            notification.flags |= Notification.FLAG_ONGOING_EVENT;

            contentView.setTextViewText(R.id.title, "Browser");
            contentView.setTextViewText(R.id.desc, "This is a description. - PAUSED");
            contentView.setImageViewResource(R.id.pausePlay, R.drawable.play);

            PendingIntent pendingSwitchIntent = PendingIntent.getBroadcast(activity, 0, new Intent(activity, NotificationPausePlay.class), 0);
            contentView.setOnClickPendingIntent(R.id.pausePlay, pendingSwitchIntent);

            mNotificationManager.notify(99, notification);
        }
    }
}

Put this in NotificationPausePlay.java

public class NotificationPausePlay extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent){
        Log.e("Here", "I am here");

        if(playing){
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
                wv.evaluateJavascript("videoElement.pause();", null);
            }else{
                wv.loadUrl("javascript:videoElement.pause();");
            }

            NotificationManager mNotificationManager = (NotificationManager) activity.getSystemService(Context.NOTIFICATION_SERVICE);
            Notification.Builder builder = new Notification.Builder(activity);
            Notification notification = builder.getNotification();
            notification.icon = R.drawable.icon;

            RemoteViews contentView = new RemoteViews(activity.getPackageName(), R.layout.custom_notification);
            notification.contentView = contentView;
            notification.flags |= Notification.FLAG_ONGOING_EVENT;

            contentView.setTextViewText(R.id.title, "Browser");
            contentView.setTextViewText(R.id.desc, "This is a description. - PAUSED");
            contentView.setImageViewResource(R.id.pausePlay, R.drawable.play);

            PendingIntent pendingSwitchIntent = PendingIntent.getBroadcast(activity, 0, new Intent(activity, NotificationPausePlay.class), 0);
            contentView.setOnClickPendingIntent(R.id.pausePlay, pendingSwitchIntent);

            mNotificationManager.notify(99, notification);

            playing = false;
        }else{
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
                wv.evaluateJavascript("videoElement.play();", null);
            }else{
                wv.loadUrl("javascript:videoElement.play();");
            }

            NotificationManager mNotificationManager = (NotificationManager) activity.getSystemService(Context.NOTIFICATION_SERVICE);
            Notification.Builder builder = new Notification.Builder(activity);
            Notification notification = builder.getNotification();
            notification.icon = R.drawable.icon;

            RemoteViews contentView = new RemoteViews(activity.getPackageName(), R.layout.custom_notification);
            notification.contentView = contentView;
            notification.flags |= Notification.FLAG_ONGOING_EVENT;

            contentView.setTextViewText(R.id.title, "Browser");
            contentView.setTextViewText(R.id.desc, "This is a description. - PLAYING");
            contentView.setImageViewResource(R.id.pausePlay, R.drawable.play);


            PendingIntent pendingSwitchIntent = PendingIntent.getBroadcast(activity, 0, new Intent(activity, NotificationPausePlay.class), 0);
            contentView.setOnClickPendingIntent(R.id.pausePlay, pendingSwitchIntent);

            mNotificationManager.notify(99, notification);

            playing = true;
        }
    }
}

Put this in the custom_notification.xml

<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:background="#e6e6e6">

<ImageView
    android:layout_width="45dp"
    android:layout_height="45dp"
    android:id="@+id/icon"
    android:src="@drawable/icon"
    android:layout_centerVertical="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_marginRight="10dp" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/title"
    android:textSize="16dp"
    android:textStyle="bold"
    android:textColor="#000000"
    android:singleLine="true"
    android:layout_alignParentTop="true"
    android:layout_toRightOf="@+id/icon"
    android:layout_toEndOf="@+id/icon"
    android:layout_toLeftOf="@+id/pausePlay"
    android:layout_toStartOf="@+id/pausePlay" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/desc"
    android:textSize="16dp"
    android:textColor="#5f5f5f"
    android:singleLine="true"
    android:layout_below="@+id/title"
    android:layout_toRightOf="@+id/icon"
    android:layout_toEndOf="@+id/icon"
    android:layout_toLeftOf="@+id/pausePlay"
    android:layout_toStartOf="@+id/pausePlay"/>

<ImageButton
    android:layout_width="40dp"
    android:layout_height="40dp"
    android:id="@+id/pausePlay"
    android:scaleType="fitXY"
    android:background="#e6e6e6"
    android:layout_centerVertical="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true" />

</RelativeLayout>

add this to the webview

wv.setWebChromeClient(new webChromeClient());    
wv.addJavascriptInterface(new JSInterface(), "JSOUT");

add this to the manifest under </activity>

<receiver android:name=".NotificationPausePlay" />
DrBrad
  • 305
  • 2
  • 13
  • 1
    The code in gist has been updated. **Tested and it works flawless** even though it require refactoring for performance. If you come into this post you might also be interested in play in the background [as shown here](https://stackoverflow.com/questions/52028940/how-can-i-make-webview-keep-a-video-or-audio-playing-in-the-background) – Remy May 21 '19 at 11:10
  • Thank you :) I have a better workaround for background play if you want me to send you too a gist for that as well. – DrBrad May 22 '19 at 23:13
  • That's would be nice :-) Also you can update your answer here with the better solution. – Remy May 23 '19 at 08:10
  • Hello, @DrBrad, thanks for this. but where can i access the "activity" and "wv" in NotificationPausePlay.java? also the "playing" variable is not initialized. – Marc Quebrar Tan Oct 27 '20 at 09:11
  • Yes for the things which are not initialized and I used companion object for that.Check this https://github.com/rohangho/DemoDownloadPage/tree/Mp3Broadcast – rohan ghosh Oct 28 '20 at 15:48
  • @rohanghosh it doesn't work on this url https://html5tutorial.info/html5-audio.php. when I click play on that website, and pause it via notification control, it does not pause the audio. – Marc Quebrar Tan Oct 29 '20 at 02:49
  • you can also try this site: https://html.com/tags/audio/ – Marc Quebrar Tan Oct 29 '20 at 03:06