Speeding up the doinbackground() process - android

I'm splitting an encrypted video into 4 parts using this code
public class SplitVideoFile {
private static String result;
static ArrayList<String>update=new ArrayList<>();
public static String main(File file) {
try {
// File file = new File("C:/Documents/Despicable Me 2 - Trailer (HD) - YouTube.mp4");//File read from Source folder to Split.
if (file.exists()) {
String videoFileName = file.getName().substring(0, file.getName().lastIndexOf(".")); // Name of the videoFile without extension
// String path = Environment.getDataDirectory().getAbsolutePath().toString() + "/storage/emulated/0/Videointegrity";
String path = "/storage/emulated/0/Videointegrity";
// File myDir = new File(getFile, "folder");
//myDir.mkdir();
File splitFile = new File(path.concat("/").concat(videoFileName));//Destination folder to save.
if (!splitFile.exists()) {
splitFile.mkdirs();
Log.d("Directory Created -> ", splitFile.getAbsolutePath());
}
int i = 01;// Files count starts from 1
InputStream inputStream = new FileInputStream(file);
String videoFile = splitFile.getAbsolutePath() +"/"+ String.format("%02d", i) +"_"+ file.getName();// Location to save the files which are Split from the original file.
OutputStream outputStream = new FileOutputStream(videoFile);
Log.d("File Created Location: ", videoFile);
update.add("File Created Location: ".concat(videoFile));
int totalPartsToSplit =4 ;// Total files to split.
int splitSize = inputStream.available() / totalPartsToSplit;
int streamSize = 0;
int read = 0;
while ((read = inputStream.read()) != -1) {
if (splitSize == streamSize) {
if (i != totalPartsToSplit) {
i++;
String fileCount = String.format("%02d", i); // output will be 1 is 01, 2 is 02
videoFile = splitFile.getAbsolutePath() +"/"+ fileCount +"_"+ file.getName();
outputStream = new FileOutputStream(videoFile);
Log.d("File Created Location: ", videoFile);
streamSize = 0;
}
}
outputStream.write(read);
streamSize++;
}
inputStream.close();
outputStream.close();
Log.d("Total files Split ->", String.valueOf(totalPartsToSplit));
result="success";
} else {
System.err.println(file.getAbsolutePath() +" File Not Found.");
result="failed";
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public ArrayList<String> getUpdate()
{
return update;
}
And in my activity file i call this using async task's doinbackground method like below
protected String doInBackground(Void...arg0) {
Log.d(TAG + " DoINBackGround", "On doInBackground...");
File encvideo=new File(epath.getText().toString());
SplitVideoFile split=new SplitVideoFile();
String result=split.main(encvideo);
publishProgress(1);
return result;
}
Even though it splits the video, it takes too much of time to do the process.
How can I speed them up. As I'm showing a progress bar in preexecute method it looks like the user sees the progress bar for a long time, which I don't want.

Related

How to update UI with download progress when download is a runnable being executed in a ThreadpoolExecutor?

I am implementing a download manager in native android where a thread pool executor is used to implement parallel downloads. A runnable is where the actual download happens, which is being executed on the pool threads. How can I send the download progress from the runnable to the UI? In order to send broadcasts, I need to pass context into the runnable. Is that the appropriate way?
How can I handle pause/resume/cancel of download gracefully?
Right now the moment user taps the pause/cancel button the value is updated in the DB and while the Thread.CurrentThread().IsInterrupted condition in the runnable becomes valid I check the status in database and decide whether I need to delete the partially downloaded file (if its cancel).
Also, will it be possible to know when the download completes so that I can remove the future object from the list?
public class Downloadable : Java.Lang.Object, IRunnable
{
private readonly string _destination;
private readonly int _productId;
public Downloadable(int productId)
{
_productId = productId;
_destination = Utils.StoragePath() + productId + ".zip";
}
public void Run()
{
int count;
try
{
Response response = CloudService.GetCloud().GetDownLoadURL(_productId.ToString(), true).Result;
if (string.Equals(response.status, "error", StringComparison.OrdinalIgnoreCase) || string.Equals(response.status, "internalError", StringComparison.OrdinalIgnoreCase))
{
//send error
}
else
{
DownloadPath downloadPath = JsonConvert.DeserializeObject<DownloadPath>(response.data);
string offlineUrl = downloadPath.contentUrl.Offline;
if (string.IsNullOrWhiteSpace(offlineUrl))
{
//send error
}
else
{
File directory = new File(Utils.StoragePath());
if (!directory.Exists())
directory.Mkdirs();
URL url = new URL(offlineUrl);
HttpURLConnection connection = (HttpURLConnection)url.OpenConnection();
long total = 0;
File file = new File(_destination);
file.CreateNewFile();
if (file.Exists() && file.Length() > 0)
{
total = file.Length();
connection.SetRequestProperty("Range", "Bytes=" + total + "-");
}
connection.Connect();
int lenghtOfFile = connection.ContentLength;
BufferedInputStream bufferedInputStream = new BufferedInputStream(url.OpenStream());
FileOutputStream fileOutputStream = new FileOutputStream(_destination, true);
byte[] buffer = new byte[1024];
count = 0;
while ((count = bufferedInputStream.Read(buffer, 0, 1024)) != -1)
{
if (Thread.CurrentThread().IsInterrupted)
{
if (DBService.GetDB().GetStatus(_productId) == (int)IpcCommon.Enumerations.Status.DOWNLOAD)
file.Delete();
break;
}
total += count;
System.Console.WriteLine("__PROGRESS__ " + (int)((total * 100) / lenghtOfFile));
System.Console.WriteLine("__PROGRESS__ ID " + _productId);
//publishProgress("" + (int)((total * 100) / lenghtOfFile));
fileOutputStream.Write(buffer, 0, count);
}
fileOutputStream.Close();
bufferedInputStream.Close();
}
}
}
catch (System.Exception exception)
{
IpcCommon.App.Logger.Log("Downloadable - File Download", new System.Collections.Generic.Dictionary<string, string> { { "Error", exception.Message } });
}
}
}
Dictionary<int, IFuture> _runningTaskList = new Dictionary<int, IFuture>();
int noOfCores = Runtime.GetRuntime().AvailableProcessors();
LinkedBlockingQueue _taskQueue = new LinkedBlockingQueue();
_threadPoolExecutor = new ThreadPoolExecutor(noOfCores, noOfCores * 2, 1, TimeUnit.Minutes, _taskQueue);
IFuture future = _threadPoolExecutor.Submit(new Downloadable(productId));
_runningTaskList.Add(productId, future);

ThreadpoolExecutor data getting mixed up

I am using android's thread pool executor framework (initialized as below).
BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<>();
ExecutorService executorService = new ThreadPoolExecutor(totalCores, totalCores * 3, 10, TimeUnit.SECONDS, taskQueue);
Now, consider the following function onFrameProcessed -
public void onFrameProcessed(RenderedImage renderedImage) {
String timeNow = new SimpleDateFormat("d-M-Y_HH_mm_ss_SSS").format(new Date()).toString();
CustomRunnable3 customRunnable3 = new CustomRunnable3(renderedImage, timeNow);
executorService.execute(customRunnable3);
}
Definition of CustomRunnable3 is as follows:
class CustomRunnable3 implements Runnable {
RenderedImage renderedImageLocal;
String basePath, timeNowCopy;
int hashCode;
CustomRunnable3(RenderedImage renderedImage, String timeNow) {
renderedImageLocal = renderedImage;
this.basePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
this.timeNowCopy = timeNow;
hashCode = renderedImageLocal.hashCode();
}
#Override
public void run() {
if (renderedImageLocal.imageType() == RenderedImage.ImageType.ThermalRadiometricKelvinImage) {
int[] thermalData = renderedImageLocal.thermalPixelValues();
String dataPath = basePath + "/" + this.timeNowCopy + ".csv";
try {
PrintWriter printWriter = new PrintWriter(dataPath);
int dataLen = thermalData.length;
for (int i = 0; i < dataLen; i++) {
printWriter.println(thermalData[i]);
}
printWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
String imgPath = basePath + "/" + this.timeNowCopy + ".jpg";
try {
if (hashCode != renderedImageLocal.hashCode()) {
Log.e("Checking", "Hash code changed..");
}
renderedImageLocal.getFrame().save(new File(imgPath), frameProcessor);
if (hashCode != renderedImageLocal.hashCode()) {
Log.e("Checking", "Hash code changed after writing..");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Usage Scenario : onFrameReceived is being called multiple times per second(like 4-5 times). In each call to onFrameReceived, I am saving two files from renderedImage object (1 csv file, 1 jpg file). Both of these files must be related to each other because both are created from one parent and have same name(except the extension).
Problem : But that is not happening and somehow I am ending up with jpg file content from 1 renderedImage and csv content from another renderedImage object.
What are the possible reasons for this problem, please share your opinion.

need to plot graph from internal storage file

I am storing my data which is coming from hardware device (i.e console), 1st i am creating the file in my device as follows -->>
final String folderName = LOGGING_ROOT_FOLDER;
File folder = new File(folderName);
if (!folder.isDirectory()) {
boolean ret = folder.mkdirs();
if (ret != true) {
return null; // return empty string if fail.
}
}
final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss_SSS", Locale.US);
final String fileName = folderName + File.separator + firstName + "-" + patientId + "-" + procedureId + "-"
+ sdf.format(new Date(System.currentTimeMillis())) + ".log";
File f = new File(fileName);
if (!f.exists()) {
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
customLogFile = new BufferedWriter(new FileWriter(f, true));
} catch (IOException e) {
e.printStackTrace();
}
After creating the file i am storing the data in my device as .log with flag (below i have given the code )-->>
if (customLogFile != null) {
StringBuilder sb = new StringBuilder(500);
final String d = mFormatter.format(new Date(System.currentTimeMillis()));
if (pdMeanValue != -1) {
sb.append(pdMeanValue);
}
sb.append("|");
if (aoMean != -1) {
sb.append(aoMean);
}
sb.append("|");
if (aoMap != -1) {
sb.append(aoMap);
}
sb.append("|");
if (ffrValue != -1) {
sb.append(ffrValue);
}
sb.append("|");
if (ffrLowestValue != -1) {
sb.append(ffrLowestValue);
}
sb.append("|");
sb.append(d);
if (mIsRecording) {
sb.append("|1"); // this is the flag
}
if (!canLogFile(sb.toString().getBytes().length)) {
return false;
}
customLogFile.write(sb.toString());
customLogFile.newLine();
So i am getting the data from console continuously and plotting the graph, but now after this i want to fetch the stored file data and wants to plot again in graph but segment wise like one interval of time to another interval (i.e like if flag is 1,then that data i want to fetch from the device and plot the graph, by taking pdMeanValue, aoMean value which will be there in side file as string format). (stored data structure is like [20|30|45|10|12|time will place here|flag])
Please help me to plot the graph by taking the value where the flag is 1.

How to read a CSV file?

I am creating an application where i do some real-time image analysis and store them into a csv file. The csv has 2 columns time and y-value of each frame.
I want to read this file and store the values from 2 columns into to double array. I want this because i want to perform an fast Fourier transformation on the data.
public class MainActivity extends AppCompatActivity implements CameraView.PreviewReadyCallback {
private static Camera camera = null;
private CameraView image = null;
private LineChart bp_graph;
private int img_Y_Avg, img_U_Avg, img_V_Avg;
private long end = 0, begin = 0;
double valueY, valueU, valueV;
Handler handler;
private int readingRemaining = 1200;
private static long time1, time2, timeDifference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
bp_graph = (LineChart)findViewById(R.id.graph);
graph_features();
//open camera
try {
camera = Camera.open();
handler = new Handler();
final Runnable runnable = new Runnable() {
#Override
public void run() {
camera.stopPreview();
camera.release();
}
};
handler.postDelayed(runnable, 30000);
} catch (Exception e) {
Log.d("ERROR", "Failed to get camera: " + e.getMessage());
}
if (camera != null) {
image = new CameraView(this, camera);
FrameLayout camera_view = (FrameLayout) findViewById(R.id.camera_view);
camera_view.addView(image);
image.setOnPreviewReady(this);
}
}
#Override
protected void onResume(){
super.onResume();
}
#Override
protected void onPause() {
super.onPause();
}
#Override
public void onPreviewFrame(long startTime, int ySum, int uSum, int vSum, long endTime) {
begin = startTime;
img_Y_Avg = ySum;
img_U_Avg = uSum;
img_V_Avg = vSum;
end = endTime;
showResults(begin, img_Y_Avg, img_U_Avg, img_V_Avg, end);
}
private void showResults(long startTime, int ySum, int uSum, int vSum, long endTime){
//set value of Y on the text view
TextView valueOfY = (TextView)findViewById(R.id.valueY);
//valueY = img_Y_Avg;
valueOfY.setText(String.valueOf(img_Y_Avg));
//start time in milliseconds
long StartDurationInMs = TimeUnit.MILLISECONDS.convert(begin, TimeUnit.MILLISECONDS);
ArrayList<Long> startOfTime = new ArrayList<>();
startOfTime.add(StartDurationInMs);
//store value to array list
ArrayList<Integer> yAverage = new ArrayList<>();
yAverage.add(img_Y_Avg);
//convert to readable format
String readableDate = new SimpleDateFormat("MMM dd,yyyy, HH:mm:ss.SSS").format(EndDurationInMs);
Log.d("Date ", readableDate);
Log.d("time ", String.valueOf(String.valueOf(yAverage.size())));
//store when all array are generated
Log.d("time ", String.valueOf(StartDurationInMs));
ArrayList<Long> getValues = new ArrayList<>();
for(int i = 0; i < yAverage.size(); i++) {
getValues.add(startOfTime.get(i));
getValues.add((long)(yAverage.get(i)));
}
//store the yAverage and start time to csv file
storeCsv(yAverage, getValues);
Log.d("MyEntryData", String.valueOf(getValues));
}
public void storeCsv(ArrayList<Integer>yAverage, ArrayList<Long>getValues){
String filename = "temporary.csv";
//File directoryDownload = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/bpReader";
//File logDir = new File (directoryDownload, "bpReader"); //Creates a new folder in DOWNLOAD directory
File logDir = new File(path);
logDir.mkdirs();
File file = new File(logDir, filename);
FileOutputStream outputStream = null;
try {
file.createNewFile();
outputStream = new FileOutputStream(file, true);
//outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
for (int i = 0; i < yAverage.size(); i += 2) {
outputStream.write((getValues.get(i) + ",").getBytes());
outputStream.write((getValues.get(i + 1) + "\n").getBytes());
//outputStream.write((getValues.get(i + 2) + ",").getBytes());
//outputStream.write((getValues.get(i + 3) + "\n").getBytes());
}
outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void readCsv(){
}
}
This is my MainActivity. What I am doing here is getting the data from CameraView class for each frame with the help of an interface that I created. After that im storing the values into a CSV file called temporary.csv.
Issues
I want to read this csv and store the first column(the time) into one double array and the second column(yAverage) into another double array.
I also want to delete the file once i have all the data stored into the into the double array.
How can I do that?
I would suggest youto use an open source library like OpenCSV to get the datafrom the CSV file. When you have the library implemented it's only a matter of iterating through the x and y columns and assign them to an array. With OpenCSV it would look like that. But i would also suggest you an more object orientec approach if the x and y with the same index coords are related to each other.
String csvFile = "/Users/mkyong/csv/country3.csv";
int length = 100; //If you dont know how many entries the csv file has i would suggest to use ArrayList
double[] xCoords = new double[length];
double[] yCoords = new double[length];
CSVReader reader = null;
try {
reader = new CSVReader(new FileReader(csvFile));
String[] line;
int i = 0;
while ((line = reader.readNext()) != null) {
xCoords[i] = Double.parseDouble(line[0]);
yCoords[i] = Double.parseDouble(line[1]);
}
} catch (IOException e) {
e.printStackTrace();
}
From the answer given by Lucas, I got the direction to my solution
public void readCsv(){
//set the path to the file
String getPath = Environment.getExternalStorageDirectory() + "/bpReader";
String csvFile = "temporary.csv";
String path = getPath+ "/" + csvFile;
//File file = new File(path, csvFile);
int length = 500;
double[] xCoords = new double[length];
double[] yCoords = new double[length];
CSVReader reader = null;
try {
File myFile = new File (path);
reader = new CSVReader(new FileReader(myFile));
String[] line;
int i = 0;
while ((line = reader.readNext()) != null) {
xCoords[i] = Double.parseDouble(line[0]) ;
yCoords[i] = Double.parseDouble(line[1]);
Log.d("read:: ", "Time: "+String.valueOf(xCoords[i])+" Y: "+String.valueOf(yCoords[i]));
}
myFile.delete();
} catch (IOException e) {
e.printStackTrace();
}
}
And then i had to add
// https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.6'
to my gradle,, which can be found at MVN repository

How to rename file in android? [duplicate]

This question already has answers here:
Java - removing first character of a string
(14 answers)
Closed 6 years ago.
I can apply a prefix dot (".") to all the files having .gif extension successfully. For instance, rename "my_file.gif" to ".my_file.gif"). However, I want to remove this prefix dot again using code (AKA reverse it). I have tried, but it won't work. (simply does not remove the dot) below is my code and my approach -
this is the code for adding a dot prefix(which works fine)-
// getting SDcard root path
File dir = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath());
walkdir(dir);
}
//detect files having these extensions and rename them
public static final String[] TARGET_EXTENSIONS = { "gif"};
public void walkdir(File dir) {
File listFile[] = dir.listFiles();
if (listFile != null) {
for (int i = 0; i < listFile.length; i++) {
if (listFile[i].isDirectory()) {
walkdir(listFile[i]);
} else {
String fPath = listFile[i].getPath();
for (String ext : TARGET_EXTENSIONS) {
if (fPath.endsWith(ext)) {
putDotBeforeFileName(listFile[i]);
}
}
}
}
}
}
private String putDotBeforeFileName(File file) {
String fileName = file.getName();
String fullPath = file.getAbsolutePath();
int indexOfFileNameStart = fullPath.lastIndexOf(fileName);
StringBuilder sb = new StringBuilder(fullPath);
sb.insert(indexOfFileNameStart, ".");
String myRequiredFileName = sb.toString();
file.renameTo(new File(myRequiredFileName));
return myRequiredFileName;
}
}
and this is my approach for removing the dot prefix which doesn't work (no force closes)-
private String putDotBeforeFileName(File file) {
String fileName = file.getName();
String fullPath = file.getAbsolutePath();
int indexOfDot = fullPath.indexOf(".");
String myRequiredFileName = "";
if (indexOfDot == 0 && fileName.length() > 1) {
myRequiredFileName = file.getParent() + "/" + fileName.substring(1);
}
try {
Runtime.getRuntime().exec(
"mv " + file.getAbsolutePath() + " " + myRequiredFileName);
} catch (IOException e) {
e.printStackTrace();
}
return myRequiredFileName;
}
Try this code
private String removeDotBeforeFileName(File file) {
String fileName = file.getName();
String fullPath = file.getAbsolutePath();
String myRequiredFileName = "";
if (fileName.length() > 1 && fullPath.charAt(0)=='.') {
myRequiredFileName = file.getParent() + "/" + fileName.substring(1);
file.renameTo(new File(myRequiredFileName));
}
return myRequiredFileName;
}

Categories

Resources