Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

When you start the app the sensor must be instantiated once. It is not possible to change the site name or the application name after this call.

 

SpringStreams *spring = [SpringStreams getInstance:@"sitename" a:@"TestApplication"]
Code Block
cpp
languagecpp
java
String site = ...;    // will delivered by the measurement provider
Spring appName = ...; // will delivered by the measurement provider
SpringStreams sensor = new SpringStreams(site, appName, getApplicationContext());
Note

The site name and application name is specified by the operator of the measurement system.

...

The library must be able to read continously the current position on a stream in seconds or  the current position of player. 
 

@protocol Meta <NSObject> @required -(NSString*) getPlayerName; -(NSString*) getPlayerVersion; -(int) getScreenWidth; -(int) getScreenHeight; @end @interface StreamAdapter : NSObject { } - (id) init:(NSObject *)stream; -(NSObject<Meta>*) getMeta; -(int) getPosition; -(int) getDuration; -(int) getWidth; -(int) getHeight; @end
Code Block
languagecpp
linenumberstrue
java
package de.spring.mobile;

/**
 * This adapter must be used to support some players by the library.
 * 
 * @see Meta
 * @see SpringStreams
 * @see SpringStreams#track(StreamAdapter, java.util.Map)
 * 
 * @author <a href="mailto:support@spring.de">spring GmbH &amp; Co.KG</a>
 */
public interface StreamAdapter {

	public interface Meta {
		public String getPlayerName();
		public String getPlayerVersion();
		public int getScreenWidth();
		public int getScreenHeight();
	}
	
	public Meta getMeta();
	
	public int getPosition();
	
	public int getDuration();
	
	public int getWidth();
	
	public int getHeight();	
}

 

 

Beginning of the Measurement

...

Info

In the library an adapter for class MPMoviePlayerController from the MediaPlayer.framework is settled. android.widget.VideoView

The source code for this implementation can be found in Appendix A and in the library.

 

The following code block shows an example for the use of the library.

... MPMoviePlayerController *player = [[[MPMoviePlayerController alloc] initWithContentURL: theURL] autorelease]; ... adapter = [[MediaPlayerAdapter alloc] adapter:player]; NSMutableDictionary * atts = [[NSMutableDictionary alloc] init]; [atts setObject:@"iOS/teststream" forKey:@"stream"]; Stream *stream = [spring track:adapter atts:atts]; [atts release]; ...
Code Block
cpp
languagecpp
java
 
// Create a sensor once in the application
SpringStreams sensor = new SpringStreams(site, appName, getApplicationContext());
...
 
public MyVideoActivity extends Activity {
	
	private static SpringStreams sensor;
	private Stream stream;
 
	public MyVideoActivity(SpringStreams sensor) {
		if(MyVideoActivity.sensor == null) 
			MyVideoActivity.sensor = sensor;
	}
 
	@Override
	protected void onStart() {
		Map<String, Object> atts = new HashMap<String, Object>();
		atts.put("stream", "android/teststream");
		stream = sensor.track(new VideoViewAdapter(this.videoView), atts);
		super.onStart();
	}
	
	@Override
	protected void onStop() {
		stream.stop();
		super.onStop();
	}
 
	...
}
 

First, the player and the object needs to be instantiated, that is able to deliver the current position on a stream in seconds. In the second step the adapters must be produced, which implements this requirement accurately.

...

Info

A stream is measured as long as the application Activity is in the foreground. When the applicationthe Activity goes into the background, the current status is transmitted to the measurement system and the measurement stopsIf the stream should be measured again, when the application will come back to the foreground, the method track must be called again.

...

After the measurement of a stream has been started, this stream is measured by the sensor. The measurement can be stopped by calling the method stop on the stream object. All measurements will be automatically stopped by the library, when the application goes into the background.

Code Block
cpp
languagecppjava
// start streaming measurement
Stream *stream = [spring track:adapter atts:atts]sensor.track(adapter, atts);
...
// stop measurement programmatically
[stream .stop]();


 

Info

If the stream should be measured again, when the applicationthe Activity comes to the foreground or after the method stop has been called, the method track must be called again.

...

Code Block
cpp
cpp
...
[[SpringStreams getInstance] unload];

 

Appendix A

...

Using the SpringStreamsActivity

In the following example, the adapter has been implemented for the media player from the standard API.

...

library is a  SpringStreamsActivity included, that can be used to largely automate the measurement. The source code of this class can be found in Appendix B and in the library.

 

Code Block
java
java
public class VideoPlayer extends SpringStreamsActivity {

	VideoView videoView;

	/**
	 * 
	 */
	public VideoPlayer() {
		super("test", "Streaming Test App");
	}
	
	
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		videoView = ...; 
	}

	@Override
	protected void onStart() {
		Map<String, Object> atts = new HashMap<String, Object>();
		atts.put("stream", "android/teststream");
		super.track(new VideoViewAdapter(this.videoView), atts);
		super.onStart();
	}
}

Appendix A

Anchor
Anhang A
Anhang A

In the following example, the adapter has been implemented for the VideoView from the standard API.

Code Block
languagejava
/**
 * Implementation of an adapter for the {@link VideoView} in standard 
 * android api.
 * 
 * @author <a href="mailto:support@spring.de">spring GmbH &amp; Co.KG</a>
 */
public class VideoViewAdapter implements StreamAdapter {

		
	private VideoView videoView;
	
	public VideoViewAdapter(VideoView videoView) {
		if(videoView == null) 
			throw new NullPointerException("videoView may not be null");
		this.videoView = videoView;
	}

	@Override
	public Meta getMeta() {
		return new Meta() {
			public String getPlayerName() {
				return "android.widget.VideoView";
			}
			public String getPlayerVersion() {
				return Build.VERSION.RELEASE;
			}
			public int getScreenHeight() {
				return (((WindowManager)videoView.getContext().getSystemService(Context.WINDOW_SERVICE))
                                       .getDefaultDisplay()).getHeight();
			}
			public int getScreenWidth() {
				return (((WindowManager)videoView.getContext().getSystemService(Context.WINDOW_SERVICE))
					.getDefaultDisplay()).getWidth();
			}
		};
	}
	
	@Override
	public int getPosition() {
		return (int)Math.round(videoView.getCurrentPosition()/1000.0);
	}

	@Override
	public int getDuration() {
		return (int)Math.round(videoView.getDuration()/1000.0);
	}

	@Override
	public int getWidth() {
		return videoView.getWidth();
	}

	@Override
	public int getHeight() {
		return videoView.getHeight();
	}
}
 


Appendix B

Anchor
Anhang B
Anhang B

The source code of class SpringStreamsActivity

Code Block
java
java
package de.spring.mobile;

import java.util.Map;
import android.app.Activity;
import android.os.Bundle;

/**
 * 
 * @author  <a href="mailto:support@spring.de">spring GmbH &amp; Co.KG</a>
 */
public abstract class SpringStreamsActivity extends Activity {
	private static SpringStreams sensor;
	private static int instances = 0;
	private Stream stream;
	
	
	public SpringStreamsActivity(String site, String appName) {
		this(site, appName, 10);
	}
	
	public SpringStreamsActivity(String site, String appName, int timeout) {
		if(site == null) throw new NullPointerException("parameter site may not be null");
		if(appName == null) throw new NullPointerException("parameter appName may not be null");
		
		if(sensor == null) {
			sensor = new SpringStreams(site, appName, getApplicationContext());
			sensor.setTimeout(timeout);
		}
	}
	public Stream getStream() {
		return stream;
	}
	public void setSensorDebug(boolean debug) {
		sensor.setDebug(debug);
	}
	
	public boolean isSensorDebug() {
		return sensor.isDebug();
	}
	
	public void setTracking(boolean tracking) {
		sensor.setTracking(tracking);
	}
	
	public boolean isTracking() {
		return sensor.isTracking();
	}	
	
	public void track(StreamAdapter adapter, Map<String, Object> atts) {
		if(this.stream != null) {
			stream.stop();
			stream = null;
		}
		stream = sensor.track(adapter, atts);
	}
	/**
	 * @see android.app.Activity#onCreate(android.os.Bundle)
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		instances++;
		super.onCreate(savedInstanceState);
	}
	
	
	/**
	 * @see android.app.Activity#onStop()
	 */
	@Override
	protected void onStop() {
		if(stream != null) {
			stream.stop();
			stream = null;
		}
		super.onStop();
	}
	
	/**
	 * @see android.app.Activity#onDestroy()
	 */
	@Override
	protected void onDestroy() {
		instances--;
		if(instances <= 0) {
			sensor.unload();
			sensor = null;
			stream = null;
		}
		super.onDestroy();
	}
}