ArrayList<String> list1 = splitFileList;
for (int i = 0; i < list1.size(); i++) {
tempFileName = splitFileList.get(i);
String splitFileCheckinDirectory = splitVideofilepath + Constant.SPLIT_VIDEO + "/" + list1.get(i) + Constant.FILE_EXTENSION;
File myfile = new File(splitFileCheckinDirectory);
if (!myfile.exists()) {
new TrimmVideo(getExternalFilesDir(null) + "/" + getFileNameFromFilePath(mFilePath), mStartTImelist.get(i), mEndTimelist.get(i) - mStartTImelist.get(i)).execute();
}
}
below is my Asynktask which i am trying execute inside for loop
private class TrimmVideo extends AsyncTask<Void, Void, Void> {
private final String mediaPath;
private final double endTime;
private final int length;
private double startTime;
private ProgressDialog progressDialog;
private TrimmVideo(String mediaPath, int startTime, int length) {
this.mediaPath = mediaPath;
this.startTime = startTime;
this.length = length;
this.endTime = this.startTime + this.length;
}
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(VideoPlayActvity.this,
"Trimming videos", "Please wait...", true);
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
trimVideo();
return null;
}
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
dbHandler.updateFlag(fileModel == null ? tempFileName : fileModel.getfilename());
btn_save_video.setVisibility(View.INVISIBLE);
super.onPostExecute(result);
}
private void trimVideo() {
try {
File file = new File(mediaPath);
FileInputStream fis = new FileInputStream(file);
FileChannel in = fis.getChannel();
Movie movie = MovieCreator.build(in);
List<Track> tracks = movie.getTracks();
movie.setTracks(new LinkedList<Track>());
boolean timeCorrected = false;
// Here we try to find a track that has sync samples. Since we can only start decoding
// at such a sample we SHOULD make sure that the start of the new fragment is exactly
// such a frame
for (Track track : tracks) {
if (track.getSyncSamples() != null && track.getSyncSamples().length > 0) {
if (timeCorrected) {
// This exception here could be a false positive in case we have multiple tracks
// with sync samples at exactly the same positions. E.g. a single movie containing
// multiple qualities of the same video (Microsoft Smooth Streaming file)
//throw new RuntimeException("The startTime has already been corrected by another track with SyncSample. Not Supported.");
} else {
startTime = correctTimeToNextSyncSample(track, startTime);
timeCorrected = true;
}
}
}
for (Track track : tracks) {
long currentSample = 0;
double currentTime = 0;
long startSample = -1;
long endSample = -1;
for (int i = 0; i < track.getDecodingTimeEntries().size(); i++) {
TimeToSampleBox.Entry entry = track.getDecodingTimeEntries().get(i);
for (int j = 0; j < entry.getCount(); j++) {
// entry.getDelta() is the amount of time the current sample covers.
if (currentTime <= startTime) {
// current sample is still before the new starttime
startSample = currentSample;
} else if (currentTime <= endTime) {
// current sample is after the new start time and still before the new endtime
endSample = currentSample;
} else {
// current sample is after the end of the cropped video
break;
}
currentTime += (double) entry.getDelta() / (double) track.getTrackMetaData().getTimescale();
currentSample++;
}
}
movie.addTrack(new CroppedTrack(track, startSample, endSample));
}
IsoFile out = new DefaultMp4Builder().build(movie);
File storagePath = new File(getExternalFilesDir(null) + "/" + Constant.SPLIT_VIDEO + "/");
storagePath.mkdirs();
File myMovie = new File(storagePath, fileModel == null ? "/" + tempFileName + Constant.FILE_EXTENSION : fileModel.getfilename() + Constant.FILE_EXTENSION);
FileOutputStream fos = new FileOutputStream(myMovie);
FileChannel fc = fos.getChannel();
out.getBox(fc);
dbHandler.updateFlag(fileModel == null ? tempFileName : fileModel.getfilename());
fc.close();
fos.close();
fis.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private double correctTimeToNextSyncSample(Track track, double cutHere) {
double[] timeOfSyncSamples = new double[track.getSyncSamples().length];
long currentSample = 0;
double currentTime = 0;
for (int i = 0; i < track.getDecodingTimeEntries().size(); i++) {
TimeToSampleBox.Entry entry = track.getDecodingTimeEntries().get(i);
for (int j = 0; j < entry.getCount(); j++) {
if (Arrays.binarySearch(track.getSyncSamples(), currentSample + 1) >= 0) {
// samples always start with 1 but we start with zero therefore +1
timeOfSyncSamples[Arrays.binarySearch(track.getSyncSamples(), currentSample + 1)] = currentTime;
}
currentTime += (double) entry.getDelta() / (double) track.getTrackMetaData().getTimescale();
currentSample++;
}
}
for (double timeOfSyncSample : timeOfSyncSamples) {
if (timeOfSyncSample > cutHere) {
return timeOfSyncSample;
}
}
return timeOfSyncSamples[timeOfSyncSamples.length - 1];
}
}
splitFileList list Contain 2 Size data a,b i want to execute synchronously one by one i.e loop start from 0 then it should complete asynk task for 0 then if loop will go one then it should complete please suggest me how to execute asynk task one by one in for loop .
You can't run synchronously by AsyncTask You must use thread some thing like this:
Thread t = new Thread(
new Runnable() {
public void run() {
try {
ArrayList<String> list1 = splitFileList;
for (int i = 0; i < list1.size(); i++) {
tempFileName = splitFileList.get(i);
String splitFileCheckinDirectory = splitVideofilepath + Constant.SPLIT_VIDEO + "/" + list1.get(i) + Constant.FILE_EXTENSION;
File myfile = new File(splitFileCheckinDirectory);
if (!myfile.exists()) {
trimVideo(getExternalFilesDir(null) + "/" + getFileNameFromFilePath(mFilePath), mStartTImelist.get(i), mEndTimelist.get(i) - mStartTImelist.get(i)); //here you can run synchronously work
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
t.start();
try {
t.join();
.....
} catch (Exception e) {
e.printStackTrace();
}
private void trimVideo(String mediaPath, int startTime, int length) {
try {
File file = new File(mediaPath);
FileInputStream fis = new FileInputStream(file);
FileChannel in = fis.getChannel();
Movie movie = MovieCreator.build(in);
List<Track> tracks = movie.getTracks();
movie.setTracks(new LinkedList<Track>());
boolean timeCorrected = false;
// Here we try to find a track that has sync samples. Since we can only start decoding
// at such a sample we SHOULD make sure that the start of the new fragment is exactly
// such a frame
for (Track track : tracks) {
if (track.getSyncSamples() != null && track.getSyncSamples().length > 0) {
if (timeCorrected) {
// This exception here could be a false positive in case we have multiple tracks
// with sync samples at exactly the same positions. E.g. a single movie containing
// multiple qualities of the same video (Microsoft Smooth Streaming file)
//throw new RuntimeException("The startTime has already been corrected by another track with SyncSample. Not Supported.");
} else {
startTime = correctTimeToNextSyncSample(track, startTime);
timeCorrected = true;
}
}
}
for (Track track : tracks) {
long currentSample = 0;
double currentTime = 0;
long startSample = -1;
long endSample = -1;
for (int i = 0; i < track.getDecodingTimeEntries().size(); i++) {
TimeToSampleBox.Entry entry = track.getDecodingTimeEntries().get(i);
for (int j = 0; j < entry.getCount(); j++) {
// entry.getDelta() is the amount of time the current sample covers.
if (currentTime <= startTime) {
// current sample is still before the new starttime
startSample = currentSample;
} else if (currentTime <= endTime) {
// current sample is after the new start time and still before the new endtime
endSample = currentSample;
} else {
// current sample is after the end of the cropped video
break;
}
currentTime += (double) entry.getDelta() / (double) track.getTrackMetaData().getTimescale();
currentSample++;
}
}
movie.addTrack(new CroppedTrack(track, startSample, endSample));
}
IsoFile out = new DefaultMp4Builder().build(movie);
File storagePath = new File(getExternalFilesDir(null) + "/" + Constant.SPLIT_VIDEO + "/");
storagePath.mkdirs();
File myMovie = new File(storagePath, fileModel == null ? "/" + tempFileName + Constant.FILE_EXTENSION : fileModel.getfilename() + Constant.FILE_EXTENSION);
FileOutputStream fos = new FileOutputStream(myMovie);
FileChannel fc = fos.getChannel();
out.getBox(fc);
dbHandler.updateFlag(fileModel == null ? tempFileName : fileModel.getfilename());
fc.close();
fos.close();
fis.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private double correctTimeToNextSyncSample(Track track, double cutHere) {
double[] timeOfSyncSamples = new double[track.getSyncSamples().length];
long currentSample = 0;
double currentTime = 0;
for (int i = 0; i < track.getDecodingTimeEntries().size(); i++) {
TimeToSampleBox.Entry entry = track.getDecodingTimeEntries().get(i);
for (int j = 0; j < entry.getCount(); j++) {
if (Arrays.binarySearch(track.getSyncSamples(), currentSample + 1) >= 0) {
// samples always start with 1 but we start with zero therefore +1
timeOfSyncSamples[Arrays.binarySearch(track.getSyncSamples(), currentSample + 1)] = currentTime;
}
currentTime += (double) entry.getDelta() / (double) track.getTrackMetaData().getTimescale();
currentSample++;
}
}
for (double timeOfSyncSample : timeOfSyncSamples) {
if (timeOfSyncSample > cutHere) {
return timeOfSyncSample;
}
}
return timeOfSyncSamples[timeOfSyncSamples.length - 1];
}
If you can't implement #Hazem answer you can go with another approach.
For this you need to maintain counter for each of your data and forget about for loop.
First you need to call asynctask for first position of your list.Something like this:
if(list1.size() > 0) {
fileCounter=0;
tempFileName = splitFileList.get(fileCounter);
String splitFileCheckinDirectory = splitVideofilepath + Constant.SPLIT_VIDEO + "/" + tempFileName + Constant.FILE_EXTENSION;
File myfile = new File(splitFileCheckinDirectory);
if (!myfile.exists()) {
new TrimmVideo(getExternalFilesDir(null) + "/" + getFileNameFromFilePath(mFilePath), mStartTImelist.get(i), mEndTimelist.get(i) - mStartTImelist.get(i)).execute();
}
}
Then in onPostExecute of your asyncTask
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
dbHandler.updateFlag(fileModel == null ? tempFileName : fileModel.getfilename());
btn_save_video.setVisibility(View.INVISIBLE);
super.onPostExecute(result);
// Update your counter here
fileCounter++;
// Check if your incremented counter doesn't exceed your list size
if(fileCounter < list1.size()) {
// Then call your asynctask again with updated counter data
empFileName = splitFileList.get(fileCounter);
String splitFileCheckinDirectory = splitVideofilepath + Constant.SPLIT_VIDEO + "/" + tempFileName + Constant.FILE_EXTENSION;
File myfile = new File(splitFileCheckinDirectory);
if (!myfile.exists()) {
new TrimmVideo(getExternalFilesDir(null) + "/" + getFileNameFromFilePath(mFilePath), mStartTImelist.get(i), mEndTimelist.get(i) - mStartTImelist.get(i)).execute();
}
}
}
Hope this will help you.
When I transfer the bytes greater than 16384 bytes when the data will be lost,
I have tried libusb, but libusb I did not find the right development documentation for reference, I wonder if there is no better way to solve this problem?
Here is the code that I print through the bulktransfer, when the transmitted data is less than 16384, it is working!
//convert pic to ZPL
public class ZPLConveter {
private int blackLimit = 380;
private int total = -1;
private int widthBytes = -1;
private boolean compressHex = false;
private static Map<Integer, String> mapCode = new HashMap<Integer, String>();
{
mapCode.put(1, "G");
mapCode.put(2, "H");
mapCode.put(3, "I");
mapCode.put(4, "J");
mapCode.put(5, "K");
mapCode.put(6, "L");
mapCode.put(7, "M");
mapCode.put(8, "N");
mapCode.put(9, "O");
mapCode.put(10, "P");
mapCode.put(11, "Q");
mapCode.put(12, "R");
mapCode.put(13, "S");
mapCode.put(14, "T");
mapCode.put(15, "U");
mapCode.put(16, "V");
mapCode.put(17, "W");
mapCode.put(18, "X");
mapCode.put(19, "Y");
mapCode.put(20, "g");
mapCode.put(40, "h");
mapCode.put(60, "i");
mapCode.put(80, "j");
mapCode.put(100, "k");
mapCode.put(120, "l");
mapCode.put(140, "m");
mapCode.put(160, "n");
mapCode.put(180, "o");
mapCode.put(200, "p");
mapCode.put(220, "q");
mapCode.put(240, "r");
mapCode.put(260, "s");
mapCode.put(280, "t");
mapCode.put(300, "u");
mapCode.put(320, "v");
mapCode.put(340, "w");
mapCode.put(360, "x");
mapCode.put(380, "y");
mapCode.put(400, "z");
}
public String convertFromImg(Bitmap bitmap) {
String cuerpo = createBody(bitmap);
if(compressHex) {
cuerpo = encodeHexAscii(cuerpo);
}
return headDoc() + cuerpo + footDoc();
}
private String createBody(Bitmap originalImg) {
StringBuffer sb = new StringBuffer();
int width = originalImg.getWidth();
int height = originalImg.getHeight();
int rgb,red,green,blue,index = 0;
char binaryChar[] = {'0','0','0','0','0','0','0','0',};
widthBytes = width / 8;
if(width % 8 > 0) {
widthBytes = (((int)width / 8) + 1);
}else {
widthBytes = width / 8;
}
total = widthBytes * height;
for (int h = 0; h < height; h++) {
for (int w = 0; w < width; w++) {
rgb = originalImg.getPixel(w,h);
red = Color.red(rgb);
green =Color.green(rgb);
blue = Color.blue(rgb);
char auxChar = '1';
int totalColor = red + green + blue;
if(totalColor > blackLimit) {
auxChar = '0';
}
binaryChar[index] = auxChar;
index++;
if(index == 8 || w == (width - 1)) {
sb.append(fourByteBinary(new String(binaryChar)));
binaryChar = new char[]{'0','0','0','0','0','0','0','0'};
index = 0;
}
}
sb.append("\n");
}
return sb.toString();
}
private String fourByteBinary(String binary){
int decimal = Integer.parseInt(binary,2);
if(decimal > 15) {
return Integer.toString(decimal,16).toUpperCase();
}else {
return "0" + Integer.toString(decimal,16).toUpperCase();
}
}
private String encodeHexAscii(String code) {
int maxLine = widthBytes * 2;
StringBuffer sbCode = new StringBuffer();
StringBuffer sbLine = new StringBuffer();
String perviousLine = "";
int counter = 1;
char aux = code.charAt(0);
boolean firstChar = false;
for (int i = 0; i < code.length(); i++) {
if(firstChar) {
aux = code.charAt(i);
firstChar = false;
continue;
}
if(code.charAt(i) == '\n') {
if(counter >= maxLine && aux == '0') {
sbLine.append(",");
}else if(counter >= maxLine && aux == 'F'){
sbLine.append("!");
}else if (counter>20){
int multi20 = (counter/20)*20;
int resto20 = (counter%20);
sbLine.append(mapCode.get(multi20));
if(resto20!=0){
sbLine.append(mapCode.get(resto20) + aux);
} else {
sbLine.append(aux);
}
} else {
sbLine.append(mapCode.get(counter) + aux);
if(mapCode.get(counter)==null){
}
}
counter = 1;
firstChar = true;
if(sbLine.toString().equals(perviousLine)){
sbCode.append(":");
} else {
sbCode.append(sbLine.toString());
}
perviousLine = sbLine.toString();
sbLine.setLength(0);
}
if(aux == code.charAt(i)) {
counter++;
}else {
if(counter > 20) {
int multi20 = (counter/20)*20;
int resto20 = (counter%20);
sbLine.append(mapCode.get(multi20));
if(resto20!=0){
sbLine.append(mapCode.get(resto20) + aux);
} else {
sbLine.append(aux);
}
}else {
sbLine.append(mapCode.get(counter) + aux);
}
counter = 1;
aux = code.charAt(i);
}
}
return sbCode.toString();
}
private String headDoc(){
String str = "^XA " +
"^FO0,0^GFA,"+ total + ","+ total + "," + widthBytes +", ";
return str;
}
private String footDoc(){
String str = "^FS"+
"^XZ";
return str;
}
public void setCompressHex(boolean compressHex) {
this.compressHex = compressHex;
}
public void setBlacknessLimitPercentage(int percentage){
blackLimit = (percentage * 768 / 100);
}
}
And this is the code that I use for transferring the image
//Transferring data using bulktransfer
private void printTask(final UsbDeviceConnection conn) {
try {
convertPDFToImg();
ZPLConveter zp = new ZPLConveter();
zp.setCompressHex(false);
zp.setBlacknessLimitPercentage(50);
command = zp.convertFromImg(bit);
} catch (IOException e) {
e.printStackTrace();
}
bytes = command.getBytes(StandardCharsets.US_ASCII);
conn.bulkTransfer(pointBulkOut, bytes, bytes.length, 500);
}
How to save uploaded file to sdcard folder , currently it stores to /data/data/cache folder with filename like "NanoHTTPD-some random number".
I am not able to copy it to any folder location in sdcard.
I would like to save the file to a pre-mentioned folder location in sdcard with the same name as the original file name was uploaded from my html page.
I have tried all sort of codes .But file copy fails all the time.
1)Not able to get correct location of temp file.
2)Not getting original filename that the form was posted with
Here is my implementation .
Please help i am stuck.
public class HttpMultimediaServer extends NanoHTTPD {
private static final String TAG = "HttpMultimediaServer";
private FileInputStream fileInputStream;
public HttpMultimediaServer() {
super(12345);
this.setTempFileManagerFactory(new ExampleManagerFactory());
}
#Override
public Response serve(IHTTPSession session) {
Method method = session.getMethod();
String uri = session.getUri();
Log.e("handle", "url>>" + uri);
if (uri.contains(filesOnly)) {
isfilesOnly = true;
uri = "/";
} else
isfilesOnly = false;
uri = uri.replace("%20", " ");
try {
uri=new String (uri.getBytes ("iso-8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e2) {
e2.printStackTrace();
}
File filePathServer = new File(uri);
if (method==Method.POST) {
try {
Map<String, String> hdrs=session.getHeaders();
Map<String, String> params=session.getParms();
Map<String, String> files = new HashMap<String, String>();
session.parseBody(files);
Set<String> keys = files.keySet();
for(String key: keys){
String name = key;
String loaction = files.get(key);
File tempfile = new File(loaction);
String tempFileName = files.get(loaction).toString();
File fileToMove = new File(tempFileName);
// temp file path returned by NanoHTTPD
String p =Environment.getExternalStorageDirectory().getPath();
String newFile = p + "/LICENSE.txt";
File nf = new File(newFile); // I want to move file here
if (fileToMove.canWrite()) {
boolean success = fileToMove.renameTo(nf);
if (success == true) {
// LOG to console
Log.i("FILE_MOVED_TO", newFile);
} else {
Log.e("FILE_MOVE_ERROR", tempFileName);
}
} else {
Log.e("PERMISSION_ERROR_TEMP_FILE", tempFileName);
}
}
uploadstatus = UPLOAD_SUCESS;
return new Response("UPLOAD_SUCESS");
} catch (Exception e) {
e.printStackTrace();
uploadstatus = UPLOAD_FAIL;
return new Response("UPLOAD_FAIL");
}
}
}
public static void copy(File src, File dst) throws IOException {
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
public static void copyFile(File src, File dst) throws IOException
{
FileChannel inChannel = new FileInputStream(src).getChannel();
FileChannel outChannel = new FileOutputStream(dst).getChannel();
try
{
inChannel.transferTo(0, inChannel.size(), outChannel);
}
finally
{
if (inChannel != null)
inChannel.close();
if (outChannel != null)
outChannel.close();
}
}
private Response getFullResponse(String mimeType,String filePath) throws FileNotFoundException {
// cleanupStreams();
fileInputStream = new FileInputStream(filePath);
return new Response(Response.Status.OK, mimeType, fileInputStream);
}
private Response getPartialResponse(String mimeType, String rangeHeader,String filePath) throws IOException {
File file = new File(filePath);
String rangeValue = rangeHeader.trim().substring("bytes=".length());
long fileLength = file.length();
long start, end;
if (rangeValue.startsWith("-")) {
end = fileLength - 1;
start = fileLength - 1
- Long.parseLong(rangeValue.substring("-".length()));
} else {
String[] range = rangeValue.split("-");
start = Long.parseLong(range[0]);
end = range.length > 1 ? Long.parseLong(range[1])
: fileLength - 1;
}
if (end > fileLength - 1) {
end = fileLength - 1;
}
if (start <= end) {
long contentLength = end - start + 1;
// cleanupStreams();
fileInputStream = new FileInputStream(file);
//noinspection ResultOfMethodCallIgnored
fileInputStream.skip(start);
Response response = new Response(Response.Status.PARTIAL_CONTENT, mimeType, fileInputStream);
response.addHeader("Content-Length", contentLength + "");
response.addHeader("Content-Range", "bytes " + start + "-" + end + "/" + fileLength);
response.addHeader("Content-Type", mimeType);
return response;
} else {
return new Response(Response.Status.RANGE_NOT_SATISFIABLE, "text/html", rangeHeader);
}
}
int UPLOAD_SUCESS = 1;
int UPLOAD_FAIL = -1;
int UPLOAD_NO = 0;
int uploadstatus;
boolean isfilesOnly;
String filesOnly = "?filesOnly=1";
ArrayList<CLocalFile> list;
StringBuilder sb;
public void walkdir(File dir) {
File listFile[] = dir.listFiles();
if (listFile != null) {
for (int i = 0; i < listFile.length; i++) {
// checking if it is a directory
if (listFile[i].isDirectory()) {
if (isfilesOnly)
walkdir(listFile[i]);
else {
CLocalFile f = new CLocalFile();
f.setName(listFile[i].getName());
f.setData(listFile[i].getAbsolutePath());
f.setSize("Folder");
list.add(f);
continue;
}
}
// checking the file extension if it is a file
String fileName = listFile[i].getName();
String extension = "";
int e = fileName.lastIndexOf('.');
if (e > 0) {
extension = fileName.substring(e + 1);
}
if (!isfilesOnly
|| CollabUtility.video_pattern.contains(extension
.toLowerCase(Locale.ENGLISH))
|| CollabUtility.document_pattern.contains(extension
.toLowerCase(Locale.ENGLISH))
|| CollabUtility.audio_pattern.contains(extension
.toLowerCase(Locale.ENGLISH))) {
CLocalFile f = new CLocalFile();
f.setName(fileName);
String mb = "Bytes";
double size = listFile[i].length();
if (size > 1024) {
size = size / 1024;
mb = "KB";
}
if (size > 1024) {
size = size / 1024;
mb = "MB";
}
if (size > 1024) {
size = size / 1024;
mb = "GB";
}
size = Math.floor(size * 100 + 0.5) / 100;
f.setSize(size + " " + mb);
f.setData(listFile[i].getAbsolutePath());
list.add(f);
}
}
}
}
void listofMedia(File file) {
list = new ArrayList<CLocalFile>();
walkdir(file);
// now create the html page
String style = "<style>" + "html {background-color:#eeeeee;} "
+ "body { background-color:#FFFFFF; "
+ "font-family:Tahoma,Arial,Helvetica,sans-serif; "
+ "font-size:18x; " + "border:3px " + "groove #006600; "
+ "padding:15px; } " + "</style>";
String script = "<script language='javascript'>"
+ "function clickit(state) {"
+ "if(state==true){document.getElementById('filesonly').checked="
+ "! document.getElementById('filesonly').checked}"
+ "if ( document.getElementById('filesonly').checked == false ){"
+ "var l=window.location.href;" + "l=l.replace('" + filesOnly
+ "', '');" + "window.location=l;" + "}"
+ "else{var l=window.location.href;"
+ "window.location=String.concat(l,'" + filesOnly + "')" + "}"
+ "}</script>";
Log.d("check", script);
sb = new StringBuilder();
sb.append("<html>");
sb.append("<head>");
sb.append("<title>Files from device</title>");
sb.append(style);
// sb.append("<script language='javascript'>"
// + "function clickit() {"
// + "if ( document.getElementById('filesonly').checked == false ){"
// + "var l=window.location.href;" + "l=l.replace('" + filesOnly
// + "', '');" + "window.location=l;" + "}"
// + "else{var l=window.location.href;"
// + "window.location=String.concat(l,'" + filesOnly + "')" + "}"
// + "}</script>");
sb.append(script);
sb.append("</head>");
sb.append("<body alink=\"blue\" vlink=\"blue\">");
Log.d("check", sb.toString());
// if(true)
// return;
// form upload
sb.append("<h3>File Upload:</h3>");
sb.append("Select a file to upload: <br/>");
sb.append("<form action=\"\" method=\"post\" enctype=\"multipart/form-data\">");
sb.append("<input type=\"file\" name=\"uploadfile\" size=\"50\" />");
sb.append("<input type=\"submit\" value=\"Upload File\" />");
sb.append("</form>");
if (uploadstatus == UPLOAD_FAIL)
sb.append("<h3><font color='red'>The upload was failed</font></h3>");
else if (uploadstatus == UPLOAD_SUCESS)
sb.append("<h3><font color='red'>The upload was successfull</font></h3>");
// if files are there or not
if (list != null && list.size() != 0) {
sb.append("<h3>The following files are hosted live from ");
if (!isfilesOnly)
sb.append("<font color='blue'>" + file.getName()
+ "</font> folder of ");
sb.append("the device</h3>");
} else {
sb.append("<h3>Couldn't find any file from <font color='blue'>"
+ file.getName() + "</font> folder of the device</h3>");
}
// checkbox
if (isfilesOnly)
sb.append("<input type=\"checkbox\" onchange='clickit(false);' checked='true' id=\"filesonly\" />"
+ "<asd onclick='clickit(true);' style=\"cursor:default;\">"
+ "Show only relevant Files (Audio, Video and Documents)</asd>");
else
sb.append("<input type=\"checkbox\" onchange='clickit(false);' id=\"filesonly\" />"
+ "<asd onclick='clickit(true);' style=\"cursor:default;\">"
+ "Show only relevant Files (Audio, Video and Documents)</asd>");
// table of files
sb.append("<table cellpadding='5px' align=''>");
// showing path URLs if not only files
if (!isfilesOnly) {
ArrayList<File> href = new ArrayList<File>();
File parent = new File(file.getPath());
while (parent != null) {
href.add(parent);
// pointing to the next parent
parent = parent.getParentFile();
}
sb.append("<tr>");
sb.append("<td colspan=2><b>");
sb.append("<a href='" + file.getParent() + "'>");
sb.append("UP");
sb.append("</a>");
// printing the whole structure
String path = "";
for (int i = href.size() - 2; i >= 0; --i) {
path = href.get(i).getPath();
if (isfilesOnly)
path += filesOnly;
sb.append(" => <a href='" + path + "'>");
sb.append(href.get(i).getName());
sb.append("</a>");
}
sb.append("</b></td>");
sb.append("</tr>");
}
sb.append("<tr>");
sb.append("<td>");
sb.append("<b>File Name</b>");
sb.append("</td>");
sb.append("<td>");
sb.append("<b>Size / Type</b>");
sb.append("</td>");
sb.append("<tr>");
// sorting the list
Collections.sort(list);
// showing the list of files
for (CLocalFile f : list) {
String data = f.getData();
if (isfilesOnly)
data += filesOnly;
sb.append("<tr>");
sb.append("<td>");
sb.append("<a href='" + data + "'>");
sb.append(f.getName());
sb.append("</a>");
sb.append("</td>");
sb.append("<td align=\"right\">");
sb.append(f.getSize());
sb.append("</td>");
sb.append("</tr>");
}
sb.append("</table>");
sb.append("</body>");
sb.append("</html>");
}
private static class ExampleManagerFactory implements TempFileManagerFactory {
#Override
public TempFileManager create() {
return new ExampleManager();
}
}
private static class ExampleManager implements TempFileManager {
private final String tmpdir;
private final List<TempFile> tempFiles;
private ExampleManager() {
tmpdir = System.getProperty("java.io.tmpdir");
// tmpdir = System.getProperty("/sdcard");
tempFiles = new ArrayList<TempFile>();
}
#Override
public TempFile createTempFile() throws Exception {
DefaultTempFile tempFile = new DefaultTempFile(tmpdir);
tempFiles.add(tempFile);
System.out.println("Created tempFile: " + tempFile.getName());
return tempFile;
}
#Override
public void clear() {
if (!tempFiles.isEmpty()) {
System.out.println("Cleaning up:");
}
for (TempFile file : tempFiles) {
try {
System.out.println(" "+file.getName());
file.delete();
} catch (Exception ignored) {}
}
tempFiles.clear();
}
}
}
If you are using NanoHTTPD r.2.1.0, please try these codes:
#Override
public Response serve(IHTTPSession session) {
Map<String, String> headers = session.getHeaders();
Map<String, String> parms = session.getParms();
Method method = session.getMethod();
String uri = session.getUri();
Map<String, String> files = new HashMap<>();
if (Method.POST.equals(method) || Method.PUT.equals(method)) {
try {
session.parseBody(files);
} catch (IOException ioe) {
return getResponse("Internal Error IO Exception: " + ioe.getMessage());
} catch (ResponseException re) {
return new Response(re.getStatus(), MIME_PLAINTEXT, re.getMessage());
}
}
if ("/uploadfile".equalsIgnoreCase(uri)) {
String filename = parms.get("filename");
String tmpFilePath = files.get("filename");
if (null == filename || null == tmpFilePath) {
// Response for invalid parameters
}
File dst = new File(mCurrentDir, filename);
if (dst.exists()) {
// Response for confirm to overwrite
}
File src = new File(tmpFilePath);
try {
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);
byte[] buf = new byte[65536];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (IOException ioe) {
// Response for failed
}
// Response for success
}
// Others...
}
In order to upload multiple files in a single input file like:
<input type="file" name="filename" multiple>
I modify decodeMultipartData() method in NanoHTTPD.java from:
private void decodeMultipartData(String boundary, ByteBuffer fbuf, BufferedReader in, Map<String, String> parms,
Map<String, String> files) throws ResponseException {
try {
int[] bpositions = getBoundaryPositions(fbuf, boundary.getBytes());
int boundarycount = 1;
String mpline = in.readLine();
while (mpline != null) {
if (!mpline.contains(boundary)) {
throw new ResponseException(Response.Status.BAD_REQUEST, "BAD REQUEST: Content type is multipart/form-data but next chunk does not start with boundary. Usage: GET /example/file.html");
}
boundarycount++;
Map<String, String> item = new HashMap<String, String>();
mpline = in.readLine();
while (mpline != null && mpline.trim().length() > 0) {
int p = mpline.indexOf(':');
if (p != -1) {
item.put(mpline.substring(0, p).trim().toLowerCase(Locale.US), mpline.substring(p + 1).trim());
}
mpline = in.readLine();
}
if (mpline != null) {
String contentDisposition = item.get("content-disposition");
if (contentDisposition == null) {
throw new ResponseException(Response.Status.BAD_REQUEST, "BAD REQUEST: Content type is multipart/form-data but no content-disposition info found. Usage: GET /example/file.html");
}
StringTokenizer st = new StringTokenizer(contentDisposition, ";");
Map<String, String> disposition = new HashMap<String, String>();
while (st.hasMoreTokens()) {
String token = st.nextToken().trim();
int p = token.indexOf('=');
if (p != -1) {
disposition.put(token.substring(0, p).trim().toLowerCase(Locale.US), token.substring(p + 1).trim());
}
}
String pname = disposition.get("name");
pname = pname.substring(1, pname.length() - 1);
String value = "";
if (item.get("content-type") == null) {
while (mpline != null && !mpline.contains(boundary)) {
mpline = in.readLine();
if (mpline != null) {
int d = mpline.indexOf(boundary);
if (d == -1) {
value += mpline;
} else {
value += mpline.substring(0, d - 2);
}
}
}
} else {
if (boundarycount > bpositions.length) {
throw new ResponseException(Response.Status.INTERNAL_ERROR, "Error processing request");
}
int offset = stripMultipartHeaders(fbuf, bpositions[boundarycount - 2]);
String path = saveTmpFile(fbuf, offset, bpositions[boundarycount - 1] - offset - 4);
files.put(pname, path);
value = disposition.get("filename");
value = value.substring(1, value.length() - 1);
do {
mpline = in.readLine();
} while (mpline != null && !mpline.contains(boundary));
}
parms.put(pname, value);
}
}
} catch (IOException ioe) {
throw new ResponseException(Response.Status.INTERNAL_ERROR, "SERVER INTERNAL ERROR: IOException: " + ioe.getMessage(), ioe);
}
}
tobe:
private void decodeMultipartData(String boundary, ByteBuffer fbuf, BufferedReader in, Map<String, String> parms,
Map<String, String> files) throws ResponseException {
try {
String pname_0 = "";
String pname_1 = "";
int pcount = 1;
int[] bpositions = getBoundaryPositions(fbuf, boundary.getBytes());
int boundarycount = 1;
String mpline = in.readLine();
while (mpline != null) {
if (!mpline.contains(boundary)) {
throw new ResponseException(Response.Status.BAD_REQUEST, "BAD REQUEST: Content type is multipart/form-data but next chunk does not start with boundary. Usage: GET /example/file.html");
}
boundarycount++;
Map<String, String> item = new HashMap<String, String>();
mpline = in.readLine();
while (mpline != null && mpline.trim().length() > 0) {
int p = mpline.indexOf(':');
if (p != -1) {
item.put(mpline.substring(0, p).trim().toLowerCase(Locale.US), mpline.substring(p + 1).trim());
}
mpline = in.readLine();
}
if (mpline != null) {
String contentDisposition = item.get("content-disposition");
if (contentDisposition == null) {
throw new ResponseException(Response.Status.BAD_REQUEST, "BAD REQUEST: Content type is multipart/form-data but no content-disposition info found. Usage: GET /example/file.html");
}
StringTokenizer st = new StringTokenizer(contentDisposition, ";");
Map<String, String> disposition = new HashMap<String, String>();
while (st.hasMoreTokens()) {
String token = st.nextToken().trim();
int p = token.indexOf('=');
if (p != -1) {
disposition.put(token.substring(0, p).trim().toLowerCase(Locale.US), token.substring(p + 1).trim());
}
}
String pname = disposition.get("name");
pname = pname.substring(1, pname.length() - 1);
if (pname.contentEquals(pname_0)) {
pname_1 = pname + String.valueOf(pcount);
pcount++;
} else {
pname_0 = pname;
pname_1 = pname;
}
String value = "";
if (item.get("content-type") == null) {
while (mpline != null && !mpline.contains(boundary)) {
mpline = in.readLine();
if (mpline != null) {
int d = mpline.indexOf(boundary);
if (d == -1) {
value += mpline;
} else {
value += mpline.substring(0, d - 2);
}
}
}
} else {
if (boundarycount > bpositions.length) {
throw new ResponseException(Response.Status.INTERNAL_ERROR, "Error processing request");
}
int offset = stripMultipartHeaders(fbuf, bpositions[boundarycount - 2]);
String path = saveTmpFile(fbuf, offset, bpositions[boundarycount - 1] - offset - 4);
files.put(pname_1, path);
value = disposition.get("filename");
value = value.substring(1, value.length() - 1);
do {
mpline = in.readLine();
} while (mpline != null && !mpline.contains(boundary));
}
parms.put(pname_1, value);
}
}
} catch (IOException ioe) {
throw new ResponseException(Response.Status.INTERNAL_ERROR, "SERVER INTERNAL ERROR: IOException: " + ioe.getMessage(), ioe);
}
}
Hope this help and sorry for my bad English..:-)
Here's my working code:
public Response serve(IHTTPSession session) {
Map<String, String> headers = session.getHeaders();
Map<String, String> parms = session.getParms();
Method method = session.getMethod();
String uri = session.getUri();
Map<String, String> files = new HashMap<>();
if (Method.POST.equals(method) || Method.PUT.equals(method)) {
try {
session.parseBody(files);
} catch (IOException ioe) {
return getResponse("Internal Error IO Exception: " + ioe.getMessage());
} catch (ResponseException re) {
return new Response(re.getStatus(), MIME_PLAINTEXT, re.getMessage());
}
}
uri = uri.trim().replace(File.separatorChar, '/');
if (uri.indexOf('?') >= 0) {
uri = uri.substring(0, uri.indexOf('?'));
}
// Other implementation goes here...
if ("/uploadfiles".equalsIgnoreCase(uri)) {
String filename, tmpFilePath;
File src, dst;
for (Map.Entry entry : parms.entrySet()) {
if (entry.getKey().toString().substring(0, 8).equalsIgnoreCase("filename")) {
filename = entry.getValue().toString();
tmpFilePath = files.get(entry.getKey().toString());
dst = new File(mCurrentDir, filename);
if (dst.exists()) {
return getResponse("Internal Error: File already exist");
}
src = new File(tmpFilePath);
if (! copyFile(src, dst)) {
return getResponse("Internal Error: Uploading failed");
}
}
}
return getResponse("Success");
}
return getResponse("Error 404: File not found");
}
private boolean deleteFile(File target) {
if (target.isDirectory()) {
for (File child : target.listFiles()) {
if (! deleteFile(child)) {
return false;
}
}
}
return target.delete();
}
private boolean copyFile(File source, File target) {
if (source.isDirectory()) {
if (! target.exists()) {
if (! target.mkdir()) {
return false;
}
}
String[] children = source.list();
for (int i = 0; i < source.listFiles().length; i++) {
if (! copyFile(new File(source, children[i]), new File(target, children[i]))) {
return false;
}
}
} else {
try {
InputStream in = new FileInputStream(source);
OutputStream out = new FileOutputStream(target);
byte[] buf = new byte[65536];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (IOException ioe) {
return false;
}
}
return true;
}
private Response getResponse(String message) {
return createResponse(Response.Status.OK, MIME_PLAINTEXT, message);
}
// Announce that the file server accepts partial content requests
private Response createResponse(Response.Status status, String mimeType, String message) {
Response res = new Response(status, mimeType, message);
res.addHeader("Accept-Ranges", "bytes");
return res;
}
To allow multiple file upload:
<input type="file" name="filename" multiple>
The same issue existed in the 2.2.1 branch. Following the same logic, I fixed the same function with a few lines of code change.
Add a counter pcount at the beginning of the function:
private void decodeMultipartFormData(String boundary, String encoding, ByteBuffer fbuf, Map<String, String> parms, Map<String, String> files) throws ResponseException {
int pcount = 1;
try {
Then use the counter to update the keyname if filename is not empty:
while (matcher.find()) {
String key = matcher.group(1);
if ("name".equalsIgnoreCase(key)) {
part_name = matcher.group(2);
} else if ("filename".equalsIgnoreCase(key)) {
file_name = matcher.group(2);
// add these two line to support multiple
// files uploaded using the same field Id
if (!file_name.isEmpty()) {
if (pcount > 0)
part_name = part_name + String.valueOf(pcount++);
else
pcount++;
}
}
}
Maybe late, but just for latecommers just like me.
Explained before, the client use okhttp upload a file just like the follow code:
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
//sourceFile is a File as you know
.addFormDataPart("image_file_1", "logo-square1.png", RequestBody.create(MediaType.parse("image/png"), sourceFile))
.build();
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
Response response = client.newCall(request).execute();
The follow code is what you want
#Override
public Response serve(IHTTPSession session) {
Method method = session.getMethod();
// ▼ 1、parse post body ▼
Map<String, String> files = new HashMap<>();
if (Method.POST.equals(method) || Method.PUT.equals(method)) {
try {
session.parseBody(files);
} catch (IOException ioe) {
return getResponse("Internal Error IO Exception: " + ioe.getMessage());
} catch (ResponseException re) {
return newFixedLengthResponse(re.getStatus(), MIME_PLAINTEXT, re.getMessage());
}
}
//after the body parsed, by default nanoHTTPD will save the file to cache and put it into params( "image_file_1" as key and the value is "logo-square1.png");
//files key is just like "image_file_1", and the value is nanoHTTPD's template file path in cache
// ▲ 1、parse post body ▲
// ▼ 2、copy file to target path xiaoyee ▼
Map<String, String> params = session.getParms();
for (Map.Entry<String, String> entry : params.entrySet()) {
final String paramsKey = entry.getKey();
if (paramsKey.contains("image_file_1")) {
final String tmpFilePath = files.get(paramsKey);
final String fileName = paramsKey;
final File tmpFile = new File(tmpFilePath);
final File targetFile = new File(mCurrentDir + fileName);
LogUtil.log("copy file now, source file path: %s,target file path:%s", tmpFile.getAbsoluteFile(), targetFile.getAbsoluteFile());
//a copy file method just what you like
copyFile(tmpFile, targetFile);
//maybe you should put the follow code out
return getResponse("Success");
}
}
// ▲ 2、copy file to target path xiaoyee ▲
return getResponse("Error 404: File not found");
}
I am using Sebastian Annies example for the mp4parser where I append 3 videos. The result should be one video that plays all the three videos simultaneously. However, I get one video that plays the last video three times. Here is my code...
// int i = number of videos....
try {
String[] f = new String[i];
for (int count = 0; count < i; count++) {
f[count] = "/sdcard/vid" + i + ".mp4";
}
Movie[] inMovies = new Movie[i];
for (int count = 0; count < i; count++) {
inMovies[count] = MovieCreator.build(f[count]);
}
List<Track> videoTracks = new LinkedList<Track>();
List<Track> audioTracks = new LinkedList<Track>();
for (Movie m : inMovies) {
for (Track t : m.getTracks()) {
if (t.getHandler().equals("soun")) {
audioTracks.add(t);
}
if (t.getHandler().equals("vide")) {
videoTracks.add(t);
}
}
}
Movie result = new Movie();
if (audioTracks.size() > 0) {
result.addTrack(new AppendTrack(audioTracks.toArray(new Track[audioTracks.size()])));
}
if (videoTracks.size() > 0) {
result.addTrack(new AppendTrack(videoTracks.toArray(new Track[videoTracks.size()])));
}
Container out = new DefaultMp4Builder().build(result);
FileChannel fc = new RandomAccessFile(String.format
("/sdcard/output.mp4"),
"rw").getChannel();
out.writeContainer(fc);
fc.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
VideoView v = (VideoView) findViewById(R.id.videoView1);
// v.setVideoPath("/sdcard/aaa" + i + ".mp4");
v.setVideoPath("/sdcard/output.mp4");
v.setMediaController(new MediaController(this));
v.start();
I dont know why it isn't doing what it's supposed to do. Please help me. Thanks
Your problem is that you're filling the input file-names with the same file:
for (int count = 0; count < i; count++) {
f[count] = "/sdcard/vid" + i + ".mp4";
}
Should be
for (int count = 0; count < i; count++) {
f[count] = "/sdcard/vid" + count + ".mp4";
}
You might be better off, for readability, to make i the loop variable, and have count be the number of files.