Libstreaming: How to navigate from SurfaceView screen(Sending Video+Audio Streams to wowza) to HTML Page in Android Phonegap - angularjs

I am creating one phonegap application using Libstreaming for Video and Audio streaming. I have login and Home screen. On Home screen, there is a button "Start Streaming", on click of this button It launches the camera to start streaming which sends audio and video streams to WOWZA media server. The camera preview has one surface view on which video is getting played.
The camera preview has one Back button over SurfaceView to back on Home screen. My issue is that, On click of back button Camera preview should be destroyed and It should redirect to Home screen (Navigation from Android SurfaceView to HTML page).
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/surface_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:background="#android:color/black" >
<!-- Below surface view is used to to send rtsp audio+video stream to wowza server -->
<net.majorkernelpanic.streaming.gl.SurfaceView
android:id="#+id/surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center" />
<!-- button to halt the camera preview and go back on to the main screen -->
<Button
android:id="#+id/btnGoBack"
android:layout_width="60dp"
android:layout_height="40dp"
android:visibility="visible"
android:text="Back"
android:layout_alignTop="#+id/surface_view"
android:layout_alignParentLeft="true"
android:textSize="14dp"
/></RelativeLayout>

I have done it myself. It looks big but quite simple. All you need to do is, define a click method of back button (which is on the SurfaceView) in your activity class (Not MainActivity as follows-
public class LiveStreamingActivity extends Activity implements RtspClient.Callback, Session.Callback, SurfaceHolder.Callback {
private static SurfaceView mSurfaceView;
private Button btnGoBack;
private SurfaceHolder mHolder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
if (!LibsChecker.checkVitamioLibs(this))
return;
mSurfaceView = (SurfaceView) findViewById(R.id.surface_view);
btnGoBack = (Button) findViewById(R.id.btnGoBack);
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
/* click listener of back button */
btnGoBack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
try {
MainActivity.isFirstTime = true;
/* on click of back button finish the current activity
* which will destroy the surfaceview and will go back on MainActivity
* by referring the Android Activity lifecycle, OnResume() method of MainActivity
* would be called where you can call javascript function directly.
*/
finish();// callback lifecycle: "onPause", "onStop", and at last "onDestroy"
} catch (Exception e) {
e.printStackTrace();
}
}
});
}}
MainActivity.java:
You have to declare a field ("isFirstTime = false") to put a logic for calling javascript function in OnResume() method. (For better understanding please refer Android activity lifecycle).
public class MainActivity extends CordovaActivity {
public static boolean isFirstTime = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadUrl(launchUrl);
}
#Override public void onResume(){
super.onResume();
System.out.println("onResume main activity");
if(isFirstTime){System.out.println("Inside onResume");
loadUrl("javascript:launchProfile()");
}
}
#Override public void onPause(){
super.onPause();
System.out.println("onPause main activity");
isFirstTime = false;
}}
Javascript Function:
I am using AngularJS. So I have to get the $location object to inject the path of profilePage.
function launchProfile(){
var e = document.getElementById('loginScreen');/*'loginScreen' is login form id */
var $injector = angular.element(e).injector();
var $location = $injector.get('$location');
$location.path("/profilePage");}
app.js (Angularjs routing):
vcApp = angular.module('VCMobApp', ['ngRoute']);vcApp.config(['$routeProvider', function ($routeProvider){
$routeProvider.when('/', {templateUrl: 'screens/login.html', controller: 'loginPageCntrl' });
$routeProvider.when('/profilePage', {templateUrl: 'screens/profilePage.html', controller: 'profilePageCntrl'});
$routeProvider.otherwise({ redirectTo: '/' });}]);
In case you are not using AngularJS, then directly you can call your html page using window.location.href='../profilePage.html' inside launchProfile() function itself (skip angularjs code then).

Related

Messages between HtmlPage and AndroidApp using GeckoView

Unfortunetly, I using a platform where WebView is not available, so, I can't make use of the simplicity of JavascriptInterface to interact from my webpage with my app.
Is there a complete (straight forward) example out there explaining how to Interact a page with my Android app using Geckoview?
I tried steps on this page (and others):
https://firefox-source-docs.mozilla.org/mobile/android/geckoview/consumer/web-extensions.html
Frankly speaking, I never saw a page hiding so many details like that.
Html page as simple as this, hosted (lets say) in "http://example.com/x.html":
<html>
<script>
function appToPage(s)
{
log('received:' + s);
}
function pageToApp(s)
{
// do something to send s to app
log('sent:' + s);
}
function log(s)
{
var x = document.getElementById('x');
x.innerHTML += '<br>' + s;
}
var i = 0;
</script>
<body>
<input type=button onclick="pageToApp('helloFromPage' + (i++))" value="SEND">
<div id="x"></div>
</body>
</html>
<script>
log('started');
</script>
Android side:
public class MainActivity extends AppCompatActivity
{
protected void onCreate(Bundle savedInstanceState)
{
...
//all the stuff needed for GeckoView and extensions
geckoSession.loadUri("http://example.com/x.html");
...
}
// when some user press some button in the browser
public void onSendButtonClick()
{
// do somenthing to call appToPage("helloFromApp");
}
// this should be called when a message arrives
public void onMessageFromPage(String s) // or whatever object as parameter (JSON, for example)
{
Log.d("msgFromPage", s)
}
...
}
I'm also using Geckoview from a month ago. To interact with your Website content you have to use a web extension.
There are two methods:
messaging
port messaging
I'm sharing an example link: https://searchfox.org/mozilla-central/source/mobile/android/examples

Clicking button in Vaadin application has no effect with Selenium WebDriver

I'd like to interact with a Vaadin application (Vaadin 8) using WebDriver. The login form is wrapped using the PageObject pattern.
#Test
public void login() {
driver.get("http://localhost:8080/intern/login");
LoginPage loginPage = new LoginPage(driver);
loginPage.enterUserCredentials("test", "test");
loginPage.submit();
}
The submit() method finds the login button and triggers a .click().
#FindBy(id = "loginButton")
private WebElement loginButton;
public void submit() {
this.loginButton.click();
}
When using the "real" application the click triggers several requests and responses to/from the server until the next page after the login page is loaded.
In the above WebDriver example however nothing happens after the click although I instructed the driver to do an implicit wait.
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

Using the camera in CrossMobile

I am using CrossMobile to create an app and I want to use the camera to capture and save photos from my app. I will also need to access the photos taken from the app to show them in a list. How can I present the camera view on a button press?
First of all you might need the CoreImage Plugin, or else some specific permissions will not be available.
Under iOS you also need to add the NSCameraUsageDescription key in the Info.plist by hand, (or else the application will crash due to Apple's limitation).
Let's assume that you have a UIButton with name cameraButton and an UIImageView with name imgV, both initialized in the loadView section of your code.
Then the core would be similar to:
public void loadView() {
// ....
cameraButton.addTarget((sender, event) -> {
if (!UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera))
new UIAlertView(null, "Unable to access camera", null, "Accept").show();
else {
UIImagePickerController picker = new UIImagePickerController();
picker.setSourceType(UIImagePickerControllerSourceType.Camera);
picker.setDelegate(new UIImagePickerControllerDelegate() {
#Override
public void didFinishPickingMediaWithInfo(UIImagePickerController picker, Map<String, Object> info) {
picker.dismissModalViewControllerAnimated(true);
UIImage img = (UIImage) info.get(UIImagePickerController.OriginalImage);
imgV.setImage(img);
}
#Override
public void didCancel(UIImagePickerController picker) {
picker.dismissModalViewControllerAnimated(true);
}
});
presentModalViewController(picker, true);
}
}, UIControlEvents.TouchUpInside);
// ....
}

Soundcloud mobile auth with Google+ returns a blank page?

I'm having issues with trying to sign in via Google on the SoundCloud authorize page (www.soundcloud.com/connect). When a user tries to auth with that, they see a blank page and they are not redirected back to the app. It works fine for the Facebook sign in and regular user/pass sign in.
If you are using WebView the problem is it doesn't support popup windows, and they are required by the auth flow. Got it to work by implementing popup support along the lines of https://stackoverflow.com/a/8022295.
private void setUpWebView() {
webView = new WebView(getContext());
webView.setWebChromeClient(new MyChromeClient());
final WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setSupportMultipleWindows(true);
webView.loadUrl(url);
}
...
final class MyChromeClient extends WebChromeClient {
// Add new webview in same window
#Override
public boolean onCreateWindow(WebView view, boolean dialog,
boolean userGesture, Message resultMsg) {
WebView childView = new WebView(getContext());
childView.getSettings().setJavaScriptEnabled(true);
childView.setWebChromeClient(this);
childView.setLayoutParams(FILL);
mContent.addView(childView);
WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
transport.setWebView(childView);
resultMsg.sendToTarget();
return true;
}
// remove new added webview whenever onCloseWindow gets called for new webview.
#Override
public void onCloseWindow(WebView window) {
mContent.removeViewAt(mContent.getChildCount() - 1);
}
}

Flex Mobile Event Listener not firing

I'm having trouble getting an event listener to work in a mobile app (Built in Flash Builder 4.5, Flex SDK 4.5.1)
I have an event class called BMS_Event.as which looks like this:
package model
{
import flash.events.Event;
public class BMS_Event extends Event
{
public static var COMPLETE_EVENT:String = "BMSData_Complete";
public static var FAULT:String = "BMSDatafault";
public var data:*;
public function BMS_Event(type:String, data:*=null, bubbles:Boolean=false, cancelable:Boolean=false)
{
this.data = data;
super(type, bubbles, cancelable);
}
}
}
A class to dispatch the event:
package model
{
import flash.events.Event;
import flash.events.EventDispatcher;
import model.BMS_Event;
public class BMSDataParser extends EventDispatcher
{
public function BMSDataParser()
{
trace("BMSDataParser function");
var BMSDataCompleteEvent:BMS_Event = new BMS_Event(BMS_Event.COMPLETE_EVENT);
dispatchEvent(BMSDataCompleteEvent);
}
}
}
And in my Mobile App view, two functions to call the eventparser, and then an eventlistener which listens for the complete event:
import model.BMSDataParser;
import model.BMS_Event;
protected function getData():void
{
var parser:BMSDataParser = new BMSDataParser();
parser.addEventListener(BMS_Event.COMPLETE_EVENT, bmstest);
}
private function bmstest(e:BMS_Event):void
{
trace("bmstest function");
}
The problem I'm having is that the event listener isn't firing, everything works fine up until that point. It does work in a web application, but for whatever reason not a mobile app.
I'm new to mobile app development - is this a limitation of AIR mobile Apps?
Any help/suggestions greatly appreciated.
Thanks
Maybe make var parser:BMSDataParser a private class variable, and in the creationComplete or initialized events of the class add parser.addEventListener(BMS_Event.COMPLETE_EVENT, bmstest);
One more thing: if your using ViewNavigatorApplication with Views, the views are not created until they are pushed onto the view stack e.g. navigator.pushView(PayNowView);, so any listeners will not be activated unless they are displayed first

Resources