Skip to content
This repository has been archived by the owner on Jan 20, 2023. It is now read-only.

support content URIs #60

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ buildscript {
allprojects {
repositories {
jcenter()
mavenCentral()
}
}

Expand All @@ -30,3 +31,8 @@ android {
disable 'InvalidPackage'
}
}

dependencies {
implementation('org.apache.commons:commons-collections4:4.2')
implementation('org.apache.commons:commons-lang3:3.8')
}
18 changes: 15 additions & 3 deletions android/src/main/java/bz/rxla/audioplayer/AudioplayerPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@

import android.content.Context;
import android.os.Build;
import android.app.Activity;
import java.io.InputStream;
import bz.rxla.audioplayer.InputStreamMediaDataSource;
import android.net.Uri;

/**
* Android implementation for AudioPlayerPlugin.
Expand All @@ -26,17 +30,19 @@ public class AudioplayerPlugin implements MethodCallHandler {
private final AudioManager am;
private final Handler handler = new Handler();
private MediaPlayer mediaPlayer;
private Activity activity;

public static void registerWith(Registrar registrar) {
final MethodChannel channel = new MethodChannel(registrar.messenger(), ID);
channel.setMethodCallHandler(new AudioplayerPlugin(registrar, channel));
channel.setMethodCallHandler(new AudioplayerPlugin(registrar, channel, registrar.activity()));
}

private AudioplayerPlugin(Registrar registrar, MethodChannel channel) {
private AudioplayerPlugin(Registrar registrar, MethodChannel channel, Activity activity) {
this.channel = channel;
channel.setMethodCallHandler(this);
Context context = registrar.context().getApplicationContext();
this.am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
this.activity = activity;
}

@Override
Expand Down Expand Up @@ -105,7 +111,13 @@ private void play(String url) {
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

try {
mediaPlayer.setDataSource(url);
if (url.startsWith("content://")) {
InputStream inputStream = activity.getContentResolver().openInputStream(Uri.parse(url));
InputStreamMediaDataSource mediaDataSource = new InputStreamMediaDataSource(inputStream);
mediaPlayer.setDataSource(mediaDataSource);
} else {
mediaPlayer.setDataSource(url);
}
} catch (IOException e) {
Log.w(ID, "Invalid DataSource", e);
channel.invokeMethod("audio.onError", "Invalid Datasource");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package bz.rxla.audioplayer;

import android.media.MediaDataSource;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Collections;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.ArrayUtils;
import static java.lang.Math.toIntExact;

public class InputStreamMediaDataSource extends MediaDataSource {
private InputStream inputStream;
private List<Byte> loadedData;

InputStreamMediaDataSource(InputStream inputStream) {
this.inputStream = inputStream;
loadedData = new ArrayList<Byte>();
}

@Override
public int readAt(long readStartPosition, byte[] outputBuffer, int outputBufferOffset, int bytesToRead) throws IOException {
final long readEndPosition = readStartPosition + bytesToRead;
final int loadedDataEndPosition = loadedData.size() - 1;
final int numberOfNewBytesToRead = toIntExact(Math.max(readEndPosition - loadedDataEndPosition, 0));
if (readEndPosition > loadedDataEndPosition) {
ArrayList<Byte> newlyReadData = readInputStreamToList(inputStream, numberOfNewBytesToRead);
loadedData = ListUtils.union(loadedData, newlyReadData);
}
final List<Byte> readBytesList = loadedData.subList(toIntExact(readStartPosition), toIntExact(readEndPosition));
final Byte[] readObjectBytesArray = readBytesList.toArray(new Byte[readBytesList.size()]);
final byte[] readBytesArray = ArrayUtils.toPrimitive(readObjectBytesArray);
System.arraycopy(readBytesArray, 0, outputBuffer, outputBufferOffset, bytesToRead);
return bytesToRead;
}

private ArrayList<Byte> readInputStreamToList(InputStream inputStream, int numberOfBytesToRead) throws IOException {
byte[] readBytesArray = new byte[numberOfBytesToRead];
int numberOfBytesRead = inputStream.read(readBytesArray); // read the bytes
if (numberOfBytesRead == -1) {
throw new IOException("InputStream failed to provide data.");
} else {
ArrayList<Byte> outputList = new ArrayList<>(Collections.nCopies(numberOfBytesRead, Byte.valueOf((byte)0)));
for (int i = 0; i < numberOfBytesRead; i++) {
outputList.set(i, readBytesArray[i]);
}
return outputList;
}
}

public long getSize() {return -1;}

@Override
public synchronized void close() throws IOException {

}
}