For loop wait for completion of called method - java

I have a code which is checking a defined type of audio file in folder and calling converter to change its format. Now when first file is passed, converter is called and as file is in process of being conversion, for loop called converter again for second file. In this i felt earlier/later process is terminated and hence i m getting only file converted as output. Code is here. How can i manage to get all files convereted.
public void convertAudio(View v) {
final File pathanme = new File(Environment.getExternalStorageDirectory() + "/sdcard/test");
File files[] = pathanme.listFiles();
for (File f : files) {
if (f.getName().endsWith(".mp4")) {
String filename = f.getName().toLowerCase().toString();
System.out.println(filename);
File wavFile = new File(pathanme, filename);
IConvertCallback callback = new IConvertCallback() {
#Override
public void onSuccess(File convertedFile) {
Toast.makeText(NewMainActivity.this, "SUCCESS: " + convertedFile.getPath(), Toast.LENGTH_LONG).show();
}
#Override
public void onFailure(Exception error) {
Toast.makeText(NewMainActivity.this, "ERROR: " + error.getMessage(), Toast.LENGTH_LONG).show();
}
};
Toast.makeText(this, "Converting audio file..." + filename, Toast.LENGTH_SHORT).show();
AndroidAudioConverter.with(this)
.setFile(wavFile)
.setFormat(AudioFormat.MP3)
.setCallback(callback)
.convert();
}
}
If u see there is success message against conversion and i never got this under for loop whereas if i pass only one file, i got success message. pls advice.

You could add a class instance variable for an index and increment it as necessary, calling the convert() method recursively as necessary. It'd look something like this (Java is a little rusty, you may have to clean up syntax):
public class MyClass {
private int fileIndex = 0;
private File[] files;
public void convertAudio(View v) {
final File pathanme = new File(Environment.getExternalStorageDirectory() + "/sdcard/test");
this.files = pathanme.listFiles();
fileIndex = 0;
convertFile(files[fileIndex]);
}
private void convertFile(File f) {
if (f.getName().endsWith(".mp4")) {
String filename = f.getName().toLowerCase().toString();
System.out.println(filename);
File wavFile = new File(pathanme, filename);
IConvertCallback callback = new IConvertCallback() {
#Override
public void onSuccess(File convertedFile) {
Toast.makeText(NewMainActivity.this, "SUCCESS: " + convertedFile.getPath(), Toast.LENGTH_LONG).show();
fileIndex++;
if (this.files.size > fileIndex) {
convertFile(this.files[fileIndex];
} else {
// we're done converting
}
}
#Override
public void onFailure(Exception error) {
Toast.makeText(NewMainActivity.this, "ERROR: " + error.getMessage(), Toast.LENGTH_LONG).show();
// cancel out or keep going, whatever
}
};
Toast.makeText(this, "Converting audio file..." + filename, Toast.LENGTH_SHORT).show();
AndroidAudioConverter.with(this)
.setFile(wavFile)
.setFormat(AudioFormat.MP3)
.setCallback(callback)
.convert();
}
}
}

Related

Java - Download and delete file on Google Drive

I have an Android app that at some point, needs to create and delete some text files on Google Drive as well as download / grab the content of those files to display it in an activity.
So I've been trying for some time to find a way to do this using only the file's name but I seem to be having a lot of problem finding some info on how to do it. Moreover, not being a Java dev does not make things easier.
I managed to create a file inside the root folder:
private void createFile()
{
println("CreateFileActivity > createFile");
final Task<DriveFolder> rootFolderTask = getDriveResourceClient().getRootFolder();
final Task<DriveContents> createContentsTask = getDriveResourceClient().createContents();
Tasks.whenAll(rootFolderTask, createContentsTask)
.continueWithTask(task -> {
DriveFolder parent = rootFolderTask.getResult();
DriveContents contents = createContentsTask.getResult();
OutputStream outputStream = contents.getOutputStream();
try (Writer writer = new OutputStreamWriter(outputStream))
{
writer.write("SOME_TEXT_HERE");
}
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("MyFile.txt")
.setMimeType("text/plain")
.setStarred(true)
.build();
return getDriveResourceClient().createFile(parent, changeSet, contents);
})
.addOnSuccessListener(this,
driveFile -> {
System.out.println("File created");
Intent resultActvityIntent = new Intent(getApplicationContext(), ResultActivity.class);
startActivity(resultActvityIntent);
})
.addOnFailureListener(this, e -> {
Toast.makeText(this, "Unable to create file", Toast.LENGTH_SHORT).show();
System.out.println("Unable to create file");
Log.e(TAG, "Unable to create file", e);
Intent resultActvityIntent = new Intent(getApplicationContext(), ResultActivity.class);
startActivity(resultActvityIntent);
});
}
To my surprise however, it creates a new file with the same name every time instead of overwriting it.
Also, I cannot seem to be able to delete the file or download it / grad the content using only the file name.
I found a lot of info on how to delete the file using the file ID and I also found an example provided by Google but it's not really what I need.
#Override
protected void onDriveClientReady()
{
pickTextFile()
.addOnSuccessListener(this,
driveId -> deleteFile(driveId.asDriveFile()))
.addOnFailureListener(this, e -> {
Log.e(TAG, "No file selected", e);
showMessage(getString(R.string.file_not_selected));
finish();
});
}
private void deleteFile(DriveFile file)
{
// [START delete_file]
getDriveResourceClient()
.delete(file)
.addOnSuccessListener(this,
aVoid -> {
showMessage(getString(R.string.file_deleted));
finish();
})
.addOnFailureListener(this, e -> {
Log.e(TAG, "Unable to delete file", e);
showMessage(getString(R.string.delete_failed));
finish();
});
// [END delete_file]
}
Any ideas on how to do this or where to start looking?
Or it's not possible to delete the file directly from within an app?
This is how the Google drive API works. Everything uses the file id. What you should be doing is a file.list sending the q parameters to search for files with the correct name and file type. You will then have the file id to be able to update the file.
Google drive API doesn't prevent you from creating more than one file with the same name.
Following #DalmTo's suggestion, here's my solution for deleting a file on Google Drive. The example below skips trash and deletes the file permanently.
private static final String fileName = "MyAppsTextFile.txt";
private void deleteExistingFile()
{
println("DeleteFileActivity > deleteExistingFile");
Query query = new Query.Builder()
.addFilter(Filters.eq(SearchableField.TITLE, fileName))
.build();
Task<MetadataBuffer> queryTask = getDriveResourceClient().query(query);
queryTask.addOnSuccessListener( this,
new OnSuccessListener<MetadataBuffer>()
{
#Override
public void onSuccess(MetadataBuffer metadataBuffer)
{
System.out.println("Success. File/s found!");
for(Metadata m : metadataBuffer)
{
DriveResource driveResource = m.getDriveId().asDriveResource();
System.out.println("Deleting file " + fileName + " with DriveID m.getDriveId()");
getDriveResourceClient().delete(driveResource);
}
}
})
.addOnFailureListener(this, new OnFailureListener()
{
#Override
public void onFailure(#NonNull Exception e)
{
System.out.println("ERROR: File not found!");
}
});
}
And since the thread title is Download and Delete, here's the code to get the file content from Google drive:
private static final String fileName = "MyAppsTextFile.txt";
private void getFiles()
{
System.out.println("GetGoogleDriveFile > getFiles");
Query query = new Query.Builder()
.addFilter(Filters.eq(SearchableField.TITLE, fileName))
.build();
Task<MetadataBuffer> queryTask = getDriveResourceClient().query(query);
queryTask
.addOnSuccessListener(this,
new OnSuccessListener<MetadataBuffer>()
{
#Override
public void onSuccess(MetadataBuffer metadataBuffer)
{
System.out.println("On SUCCESS");
for( Metadata m : metadataBuffer )
{
DriveFile driveFile = m.getDriveId().asDriveFile();
getFileContents(driveFile);
}
}
})
.addOnFailureListener(this, new OnFailureListener()
{
#Override
public void onFailure(#NonNull Exception e)
{
System.out.println("On FAILURE");
}
});
}
private void getFileContents(DriveFile myFile)
{
System.out.println("GetGoogleDriveFile > getFileContents");
Task<DriveContents> openFileTask =
getDriveResourceClient().openFile(myFile, DriveFile.MODE_READ_ONLY);
openFileTask
.continueWithTask(new Continuation<DriveContents, Task<Void>>()
{
#Override
public Task<Void> then(#NonNull Task<DriveContents> task) throws Exception
{
DriveContents contents = task.getResult();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(contents.getInputStream())))
{
StringBuilder builder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null)
{
builder.append(line).append("\n");
}
userData = builder.toString();
}
System.out.println("We have the file content!");
Task<Void> discardTask = getDriveResourceClient().discardContents(contents);
return discardTask;
}
})
.addOnFailureListener(new OnFailureListener()
{
#Override
public void onFailure(#NonNull Exception e)
{
System.out.println("Unable to read file!");
}
});
}
I'm pretty sure this can be improved but I guess it's a start for anyone looking for a solution.

How to properly save frames from mp4 as png files using ExtractMpegFrames.java?

I am trying to get all frames from an mp4 file using the ExtractMpegFrames.java class found here http://bigflake.com/mediacodec/ExtractMpegFramesTest.java.txt
What I currently do is create a temp file (File.createTempFile) in a directory that stores all the frames, create a FileOutputStream and do
bm.compress(Bitmap.CompressFormat.PNG, 100, fOut)
where fOut is the OutputStream with the file.
Currently, the saved images look like this: https://imgur.com/a/XpsV2
Using the Camera2 Api, I record a video and save it as an mp4. According to VLC, the color space for the video is Planar 4:2:0 YUV Full Scale.
Looking around, it seems that each vendor uses different color spaces
https://stackoverflow.com/a/21266510/7351748. I know ffmpeg can conversions with color spaces, but I cannot use it.
I am not sure where to start to solve this issue of the strange output pngs. I am assuming that this is a color space issue, but I can be completely wrong here.
You can get all Frames of Video Using ffmpeg library here is working code.
add dependancy
compile 'com.writingminds:FFmpegAndroid:0.3.2'
to your gradle
private void loadFFMpegBinary() {
try {
if (ffmpeg == null) {
ffmpeg = FFmpeg.getInstance(this);
}
ffmpeg.loadBinary(new LoadBinaryResponseHandler() {
// #Override
// public void onFailure() {
// showUnsupportedExceptionDialog();
// }
#Override
public void onSuccess() {
Log.d(TAG, "ffmpeg : correct Loaded");
}
});
} catch (FFmpegNotSupportedException e) {
} catch (Exception e) {
Log.d(TAG, "EXception : " + e);
}
}
here is image extratct method
public void extractImagesVideo() {
File moviesDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES
);
String filePrefix = "extract_picture";
String fileExtn = ".jpg";
String yourRealPath = getPath(Pick_Video.this, DataModel.selectedVideoUri);
Log.d("selected url", "" + DataModel.selectedVideoUri);
File src = new File(yourRealPath).getAbsoluteFile();
File appDir=new File(moviesDir,"/"+app_name+"/");
if(!appDir.exists())
appDir.mkdir();
DataModel.appDir=appDir;
File dir = new File(appDir, "testVideo");
int fileNo = 0;
while (dir.exists()) {
fileNo++;
dir = new File(moviesDir+"/"+app_name+"/", "testVideo" + fileNo);
}
dir.mkdir();
DataModel.dir = dir;
resultList = new ArrayList<String>(256);
filePath = dir.getAbsolutePath();
File dest = new File(dir, filePrefix + "%03d" + fileExtn);
Log.d(TAG, "startTrim: src: " + src.toString());
Log.d(TAG, "startTrim: dest: " + dest.getAbsolutePath());
String[] complexCommand = { "-i",""+src.toString(),"-qscale:v", "2","-vf", "fps=fps=20/1",dest.getAbsolutePath()};
//"-qscale:v", "2","-vf", "fps=fps=20/1",//
//works fine with speed and
execFFmpegBinary(complexCommand);
}
call this two method on button click event
Comment If Any query.

Suddenly can't read/write to file

I'm making an android application, which saves data to a file in the settings activity.
I made some custom functions to ease writing my files, they're in a class all my activities inherit from, including the settings activity.
Custom functions:
public void WriteToFile(String filename, String tag, String value) {
try {
FileOutputStream fileOut = openFileOutput(filename + ".txt", MODE_PRIVATE);
OutputStreamWriter writer = new OutputStreamWriter(fileOut);
writer.write(ReadFile(filename + ".txt") + tag + ":" + value + ";");
writer.close();
} catch (Exception e) {
Toast.makeText(this, "ERROR: " + e.toString(), Toast.LENGTH_LONG).show();
Log.e("Error writing: ", e.toString());
}
}
public void WipeFile(String filename) {
try {
FileOutputStream fileOut = openFileOutput(filename + ".txt", MODE_PRIVATE);
OutputStreamWriter writer = new OutputStreamWriter(fileOut);
writer.write("");
writer.close();
} catch (Exception e) {
Toast.makeText(this, "ERROR: " + e.toString(), Toast.LENGTH_LONG).show();
Log.e("Error writing: ", e.toString());
}
}
public String ReadFile(String filename) {
try {
FileInputStream fileIn = openFileInput(filename + ".txt");
InputStreamReader InputRead = new InputStreamReader(fileIn);
char[] inputBuffer = new char[10000];
String content = "", readString;
int charRead;
while ((charRead = InputRead.read(inputBuffer)) > 0) {
readString = String.copyValueOf(inputBuffer, 0, charRead);
content += readString;
}
InputRead.close();
return content;
} catch (Exception e) { WipeFile(filename); return ""; }
}
public String FileValue(String filename, String tag, String defaultValue) {
String[] content = ReadFile(filename + ".txt").split(";");
for (String pair : content) {
if (pair.split(":")[0].equals(tag)) return pair.split(":")[1];
} WriteToFile(filename, tag, defaultValue); return defaultValue;
}
Settings activity:
#Override
#SuppressWarnings("ConstantConditions")
protected void onCreate(Bundle savedInstanceState) {
ToolbarTitle = "Settings";
ActivityID = R.layout.activity_settings;
ToolbarID = R.id.settings_toolbar;
ToolbarIcon = R.mipmap.settings_icon;
ActivityLayout = R.id.settings_layout;
super.onCreate(savedInstanceState);
if (prefs.getInt("LoggedinID", 0) == 0) findViewById(R.id.settings_user).setVisibility(View.GONE);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.settings_lowBattery, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
int spinnerPosition = adapter.getPosition(FileValue("settings", "Alert", "20%"));
Spinner battery = ((Spinner) findViewById(R.id.settings_battery));
battery.setAdapter(adapter);
battery.setSelection(spinnerPosition);
((Switch) findViewById(R.id.settings_notifications)).setChecked(FileValue("settings", "Notifications", "1").equals("1"));
findViewById(R.id.settings_ads).setVisibility((FileValue("settings", "Ads", "1").equals("1") ? View.VISIBLE : View.INVISIBLE));
}
#SuppressWarnings("ConstantConditions")
public void Apply(View view) {
WipeFile("settings");
WriteToFile("settings", "Notifications", (((Switch) findViewById(R.id.settings_notifications)).isChecked() ? "1" : "0"));
WriteToFile("settings", "Alert", ((Spinner) findViewById(R.id.settings_battery)).getSelectedItem().toString());
}
public void Ads(View view) {
Toast.makeText(this, "Just a prank, bro", Toast.LENGTH_SHORT).show();
WriteToFile("settings", "Ads", "0");
}
What's weird is that it all worked when it was messy and not in custom functions, any idea why?
The problem seems to occur in the ReadFile function, where InputRead.read(inputBuffer) returns -1 (No data in file).
I have no idea how to even check where the problem lies, when writing to the file or when reading from it....
Thanks ahead
PROBLEM SOLVED
1. The ReadFile function that was inside the writer.write function couldn't open the file and read it since the writer kept it open for itself.
2. That same ReadFile function was provided with (filename + ".txt"), and added ".txt" to it as well.
It seems like the problem might be in how you are appending to file...
Internally your write function opens the file, then before closing it, your read function opens the same file and closes it. It could be that either the read function is failing when it tries to open the file because it is already open, but not closed. OR it could be that when the read function closes the file it also closes the file for the write function...
So the problem seems to be that you want to append to the file in your write function, but you are implementing it poorly. You do not need to rewrite the contents to file. You just need to find the proper flag to open the file for appending.
You should use a java.util.Properties for your settings. It is like a Map<String, String>.
To load all your settings, use load(Reader reader).
To save all your settings, use save(OutputStream out, String comments).

skip duplicate file using java

Can anyone help me to skip file having extension "read" in my code ?
I have two files in my folder:
123.csv
123.csv.read
After execution every csv file is converted into ".csv.read", but if the same file comes again, that file should be skipped.
Like this file (123.csv.read) has been processed already, so if same new file(123.csv) comes, I want to be skipped that file.
In my code below, after 123.csv file is processed, the folder has only one file 123.csv.read. break is not behaving as I was expecting.
context.Str = ((String)globalMap.get("tFileList_1_CURRENT_FILEPATH"));
String extension = context.Str.substring(context.Str.lastIndexOf(".") + 1);
if (extension.equals("read"))
{
break;
}
else {
System.out.println("Good File to Process");
}
public static void listFile(final String folder, final String ext) {
ExtFilter filter = new ExtFilter(ext);
File dir = new File(folder);
if (dir.isDirectory() == false) {
System.out.println("Directory does not exists : " + FindFileExtension.FILE_DIR);
return;
}
// list out all the file name and filter by the extension
String[] list = dir.list(filter);
if (list.length == 0) {
System.out.println("no files end with : " + ext);
return;
}
for (String file : list) {
String temp = new StringBuffer(FindFileExtension.FILE_DIR).append(File.separator).append(file).toString();
System.out.println("file : " + temp);
// do your stuff here this file is not processed
}
}
public static class ExtFilter implements FilenameFilter {
private String ext;
public ExtFilter(final String ext) {
this.ext = ext;
}
public boolean accept(final File dir, final String name) {
return (name.endsWith(this.ext));
}
}
You can do something like that,it might help you
You can try this:
For example 123.csv file came again, then you check this if exist in read folder
if(!new File(123.csv+".read").exist()) {
// if this file is not exist, then it means that this has not been processed
// process the file
} else {
// do some other staff
}
Edit: Or you can try this
public static void main(String[] args) throws Exception {
File dir = new File("your_path");
File[] processedFiles = dir.listFiles(new FileFilter() {
#Override
public boolean accept(File pathname) {
return pathname.getName().contains("read");
}
});
List<File> files = Arrays.asList(processedFiles);
File[] noneProcessedFiles = dir.listFiles(new FileFilter() {
#Override
public boolean accept(File pathname) {
return !pathname.getName().contains("read");
}
});
for (File file : noneProcessedFiles) {
if (!files.stream().findAny().get().getName().contains(file.getName())) {
// process the file....
System.out.println("Not found ... " + file.getName());
} else {
// do some other staff....
System.out.println("Fount the file");
}
}
}

Send a pdf on an default Email Client - Android Aplication [duplicate]

This question already has an answer here:
Android send mail with PDF file
(1 answer)
Closed 7 years ago.
I need send a PDF file attach on a message, I have a button that calls a function that open a Intent with message, email address and subject filled, but I need that the PDF file has been attached too.
This is my code and I can not find my error, someone can help me please?
public void initializeWebView() {
// Initialize the webview
webView.setResourceClient(new XWalkResourceClient(webView) {
#Override
public boolean shouldOverrideUrlLoading(XWalkView view, String stringUrl) {
if(stringUrl.equals(baseUrl)) {
return false;
}
// mailto links will be handled by the OS.
if (stringUrl.startsWith("mailto:")) {
Uri uri = Uri.parse(stringUrl);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
String fileName = "bouhnik.pdf";
String filePath = (Configuration.getMagazineAssetPath()).toString()+ File.separator + fileName;
Context c = getActivity().getApplicationContext();
File file = null;
FileOutputStream fos = null;
try {
InputStream is = c.getAssets().open(filePath);
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
fos = new FileOutputStream(file);
fos.write(buffer);
fos.close();
} catch (IOException e) {
Log.i("Ferrou",e.toString());
e.printStackTrace();
}
if (!file.exists() || !file.canRead()) {
return false;
}
intent.putExtra(intent.EXTRA_STREAM, file.getPath());
intent.setClassName("com.android.email", "com.android.mail.compose.ComposeActivity");
intent .putExtra(Intent.EXTRA_SUBJECT, "Subject");
WebViewFragment.this.startActivity(Intent.createChooser(intent, "Send email..."));
} else {
try {
URL url = new URL(stringUrl);
// We try to remove the referrer string to avoid passing it to the server in case the URL is an external link.
String referrer = "";
if (url.getQuery() != null) {
Map<String, String> variables = Configuration.splitUrlQueryString(url);
String finalQueryString = "";
for (Map.Entry<String, String> entry : variables.entrySet()) {
if (entry.getKey().equals("referrer")) {
referrer = entry.getValue();
} else {
finalQueryString += entry.getKey() + "=" + entry.getValue() + "&";
}
}
if (!finalQueryString.isEmpty()) {
finalQueryString = "?" + finalQueryString.substring(0, finalQueryString.length() - 1);
}
stringUrl = stringUrl.replace("?" + url.getQuery(), finalQueryString);
}
// Remove referrer from query string
if (!url.getProtocol().equals("file")) {
if (referrer.equals(WebViewFragment.this.getActivity().getString(R.string.url_external_referrer))) {
Uri uri = Uri.parse(stringUrl);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
WebViewFragment.this.startActivity(intent);
} else if (referrer.toLowerCase().equals(WebViewFragment.this.getActivity().getString(R.string.url_baker_referrer))) {
((IssueActivity) WebViewFragment.this.getActivity()).openLinkInModal(stringUrl);
return true;
} else {
return false;
}
} else {
stringUrl = url.getPath().substring(url.getPath().lastIndexOf("/") + 1);
int index = ((IssueActivity) WebViewFragment.this.getActivity()).getJsonBook().getContents().indexOf(stringUrl);
if (index != -1) {
Log.d(this.getClass().toString(), "Index to load: " + index + ", page: " + stringUrl);
((IssueActivity) WebViewFragment.this.getActivity()).getViewPager().setCurrentItem(index);
view.setVisibility(View.GONE);
} else {
// If the file DOES NOT exist, we won't load it.
File htmlFile = new File(url.getPath());
if (htmlFile.exists()) {
return false;
}
}
}
} catch (MalformedURLException | UnsupportedEncodingException ex) {
Log.d(">>>URL_DATA", ex.getMessage());
}
}
return true;
}
});
// Set UI Client (Start stop animations)
webView.setUIClient(new XWalkUIClient(webView) {
#Override
public void onPageLoadStopped(XWalkView view, String url, LoadStatus status) {
if(!url.isEmpty() && status == LoadStatus.FINISHED) {
if(isUserVisible) {
webView.resumeTimers();
}else{
webView.pauseTimers();
}
}
}
});
webView.load(baseUrl, null);
}
Thank's so much for everyone!!
I solve my problem change the type of Intent to:
Intent emailIntent = new Intent(Intent.ACTION_SEND);
Because this is better to email commands, and I define a emailUri where:
emailUri = Uri.fromFile(file.getAbsoluteFile());
because this get a absolute path with a file inside, and when the email client open, it open this file, not a path.
I add a type at my intent but I select the type of my attachment, so I define:
emailIntent.setType("application/pdf");
And finally:
emailIntent.putExtra(Intent.EXTRA_STREAM, uriMail);
startActivity(emailIntent);
It's works now!! Thanks :D
It looks like something is might be going wrong with your file path. Double check it. Then
1 - You need to add the package name of your application with context.getPackageName()
private String path = Environment.getExternalStorageDirectory().getPath() + context.getPackageName() + "books/"+fileName;
2 - Declare the permission inside your AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Categories