mirror of
https://github.com/purplecabbage/phonegap-plugins.git
synced 2026-04-24 03:00:11 -04:00
36
Android/RemoteSound/README.md
Normal file
36
Android/RemoteSound/README.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# RemoteSound plugin for Phonegap (Android) #
|
||||
By Olivier Brand
|
||||
|
||||
## Adding the Plugin to your project ##
|
||||
1. To install the plugin, move `Resources.js` to your project's www folder and include a reference to it
|
||||
in your html files.
|
||||
|
||||
<script src="RemoteSound.js"></script>
|
||||
|
||||
2. Create a folder called 'com/phonegap/plugin/remotesound' within your project's src folder.
|
||||
3. And copy the java file into that new folder.
|
||||
|
||||
<pre>
|
||||
mkdir -p <your_project>/src/com/phonegap/plugin/remotesound
|
||||
cp ./ResourcesPlugin.java <your_project>/src/com/phonegap/plugin/remotesound
|
||||
</pre>
|
||||
|
||||
4. Add a plugin line to `res/xml/plugins.xml`
|
||||
|
||||
<plugin name="RemoteSound" value="com.phonegap.plugin.remotesound.RemoteSoundPlugin" />
|
||||
|
||||
## Using the plugin ##
|
||||
|
||||
<pre>
|
||||
|
||||
<!-- Play a sound -->
|
||||
window.plugins.remotesound.playRemoteSound({
|
||||
'soundURL': 'http://myserver/sounds/mysound.wav'
|
||||
});
|
||||
|
||||
<!-- Load remote sounds -->
|
||||
window.plugins.remotesound.playRemoteSound({
|
||||
'soundURLs': ['http://myserver/sounds/mysound.wav', 'http://myserver/sounds/mysound2.wav']
|
||||
});
|
||||
|
||||
</pre>
|
||||
48
Android/RemoteSound/RemoteSound.js
Normal file
48
Android/RemoteSound/RemoteSound.js
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* RemoteSound
|
||||
* Implements the javascript access to the phonegap plugin for playing and loading remote sounds
|
||||
* @author Olivier Brand
|
||||
*/
|
||||
|
||||
/**
|
||||
* @return the deviceInfo class instance
|
||||
*/
|
||||
var RemoteSound = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Play a sound. Parameter is a URI called "soundName"
|
||||
*
|
||||
* @param successCallback
|
||||
* The callback which will be called when directory listing is
|
||||
* successful
|
||||
* @param failureCallback
|
||||
* The callback which will be called when directory listing encouters
|
||||
* an error
|
||||
*/
|
||||
RemoteSound.prototype.playRemoteSound = function(params, successCallback,
|
||||
failureCallback) {
|
||||
return cordova.exec(successCallback, failureCallback, 'RemoteSound',
|
||||
'playRemoteSound', [ params ], true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Load and cache remote sounds. Parameter is a JSON Array of URLs pointing to sound assets
|
||||
*
|
||||
* @param successCallback
|
||||
* The callback which will be called when directory listing is
|
||||
* successful
|
||||
* @param failureCallback
|
||||
* The callback which will be called when directory listing encouters
|
||||
* an error
|
||||
*/
|
||||
RemoteSound.prototype.loadRemoteSounds = function(params, successCallback,
|
||||
failureCallback) {
|
||||
return cordova.exec(successCallback, failureCallback, 'RemoteSound',
|
||||
'loadRemoteSounds', [ params ], true);
|
||||
};
|
||||
|
||||
|
||||
cordova.addConstructor(function() {
|
||||
cordova.addPlugin('remotesound', new RemoteSound());
|
||||
});
|
||||
250
Android/RemoteSound/RemoteSoundPlugin.java
Normal file
250
Android/RemoteSound/RemoteSoundPlugin.java
Normal file
@@ -0,0 +1,250 @@
|
||||
package com.phonegap.plugin.remotesound;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import org.apache.cordova.api.Plugin;
|
||||
import org.apache.cordova.api.PluginResult;
|
||||
import org.apache.cordova.api.PluginResult.Status;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.MediaPlayer;
|
||||
import android.media.MediaPlayer.OnCompletionListener;
|
||||
import android.media.MediaPlayer.OnPreparedListener;
|
||||
|
||||
/**
|
||||
* The Class RemoteSoundPlugin allows to perform 2 separate actions: 1- play a
|
||||
* remote sound given a URL 2- load and cache sounds given some URLs
|
||||
*
|
||||
* A usage where load/cache sounds is valuable is when lots of sounds, possibly
|
||||
* large, needs to be pre-loaded Play sound is first checking that no other
|
||||
* sound with the same name has been cached. If not, it remotely downloads it
|
||||
* and cache it on the file system
|
||||
*/
|
||||
public class RemoteSoundPlugin extends Plugin implements OnPreparedListener, OnCompletionListener {
|
||||
|
||||
private MediaPlayer mp = null;
|
||||
private static final int BUFFER_SIZE = 1024 * 2;
|
||||
|
||||
@Override
|
||||
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
||||
PluginResult result = null;
|
||||
|
||||
if (action.equals("playRemoteSound")) {
|
||||
|
||||
JSONObject obj = null;
|
||||
try {
|
||||
obj = args.getJSONObject(0);
|
||||
String soundURL = obj.has("soundURL") ? obj.getString("soundURL") : null;
|
||||
|
||||
if (soundURL != null) {
|
||||
this.playSound(soundURL);
|
||||
}
|
||||
} catch (JSONException jsonEx) {
|
||||
|
||||
result = new PluginResult(Status.JSON_EXCEPTION);
|
||||
}
|
||||
}
|
||||
|
||||
if (action.equals("loadRemoteSounds")) {
|
||||
|
||||
JSONArray resourceNames = null;
|
||||
JSONObject obj = null;
|
||||
|
||||
try {
|
||||
obj = args.getJSONObject(0);
|
||||
resourceNames = obj.has("soundURLs") ? obj.getJSONArray("soundURLs") : null;
|
||||
|
||||
if (resourceNames != null && resourceNames.length() > 0) {
|
||||
Set<URL> resources = new HashSet<URL>(resourceNames.length());
|
||||
for (int nbElem = 0; nbElem < resourceNames.length(); nbElem++) {
|
||||
try {
|
||||
resources.add(new URL(resourceNames.getString(nbElem)));
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (!resources.isEmpty()) {
|
||||
downloadResources(ctx.getContext(), resources);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (JSONException jsonEx) {
|
||||
|
||||
result = new PluginResult(Status.JSON_EXCEPTION);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* android.media.MediaPlayer.OnPreparedListener#onPrepared(android.media
|
||||
* .MediaPlayer)
|
||||
*/
|
||||
public void onPrepared(MediaPlayer mediaplayer) {
|
||||
if (mp != null) {
|
||||
mp.start();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* android.media.MediaPlayer.OnCompletionListener#onCompletion(android.media
|
||||
* .MediaPlayer)
|
||||
*/
|
||||
public void onCompletion(MediaPlayer mediaplayer) {
|
||||
Timer endSound = new Timer();
|
||||
endSound.schedule(new TimerTask() {
|
||||
public void run() {
|
||||
if (mp != null) {
|
||||
mp.stop();
|
||||
mp.release();
|
||||
mp = null;
|
||||
}
|
||||
}
|
||||
}, 200);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Play sound, either locally (from assets) or remotely via URL.
|
||||
*
|
||||
* @param soundUri
|
||||
* the sound uri
|
||||
*/
|
||||
private void playSound(String soundUri) {
|
||||
|
||||
try {
|
||||
|
||||
mp = new MediaPlayer();
|
||||
|
||||
mp.setOnPreparedListener(this);
|
||||
mp.setOnCompletionListener(this);
|
||||
|
||||
FileInputStream fis = null;
|
||||
String soundName = soundUri.substring(soundUri.lastIndexOf('/') + 1);
|
||||
try {
|
||||
|
||||
fis = ctx.getApplicationContext().openFileInput(soundName);
|
||||
} catch (FileNotFoundException fne) {
|
||||
|
||||
downloadRemoteMedia(ctx.getApplicationContext(), soundUri, soundName);
|
||||
fis = ctx.getApplicationContext().openFileInput(soundName);
|
||||
}
|
||||
|
||||
mp.setDataSource(fis.getFD());
|
||||
|
||||
mp.setVolume(1.0f, 1.0f);
|
||||
mp.prepare();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Download the url stream to a temporary location and then call the
|
||||
*
|
||||
*
|
||||
* @param context
|
||||
* the context
|
||||
* @param mediaUrl
|
||||
* the media url
|
||||
* @param mediaFileName
|
||||
* the media file name
|
||||
* @return the file
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
private void downloadRemoteMedia(Context context, String mediaUrl, String mediaFileName)
|
||||
throws IOException {
|
||||
// File downloadingMediaFile = null;
|
||||
HttpURLConnection cn = null;
|
||||
FileOutputStream out = null;
|
||||
InputStream stream = null;
|
||||
|
||||
try {
|
||||
cn = (HttpURLConnection) new URL(mediaUrl).openConnection();
|
||||
stream = new BufferedInputStream(cn.getInputStream(), BUFFER_SIZE);
|
||||
|
||||
// PRIVATE STORAGE. Automatically replace existing files
|
||||
out = context.openFileOutput(mediaFileName, Context.MODE_PRIVATE);
|
||||
|
||||
byte buf[] = new byte[BUFFER_SIZE];
|
||||
int len1 = 0;
|
||||
|
||||
while ((len1 = stream.read(buf)) > 0) {
|
||||
out.write(buf, 0, len1);
|
||||
}
|
||||
|
||||
out.close();
|
||||
stream.close();
|
||||
} finally {
|
||||
if (cn != null) {
|
||||
cn.disconnect();
|
||||
}
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
try {
|
||||
stream.close();
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Download given resources.
|
||||
*
|
||||
* @param context
|
||||
* the context
|
||||
* @param resources
|
||||
* the resources
|
||||
* @return the number of loaded resources
|
||||
*/
|
||||
private Integer downloadResources(Context context, Set<URL> resources) {
|
||||
int nbLoaded = 0;
|
||||
|
||||
for (Iterator<URL> iterator = resources.iterator(); iterator.hasNext();) {
|
||||
|
||||
URL url = iterator.next();
|
||||
try {
|
||||
downloadRemoteMedia(context, url.toString(),
|
||||
url.getPath().substring(url.getPath().lastIndexOf('/') + 1));
|
||||
nbLoaded++;
|
||||
} catch (IOException ioex) {
|
||||
ioex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return nbLoaded;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,12 +23,12 @@ var Resources = function() {
|
||||
*/
|
||||
Resources.prototype.getStringResources = function(params, successCallback,
|
||||
failureCallback) {
|
||||
return PhoneGap.exec(successCallback, failureCallback, 'Resources',
|
||||
return cordova.exec(successCallback, failureCallback, 'Resources',
|
||||
'getStringResources', [ params ], false);
|
||||
};
|
||||
|
||||
|
||||
|
||||
PhoneGap.addConstructor(function() {
|
||||
PhoneGap.addPlugin('resources', new Resources());
|
||||
cordova.addConstructor(function() {
|
||||
cordova.addPlugin('resources', new Resources());
|
||||
});
|
||||
Reference in New Issue
Block a user