MediaMetadataRetriever.setDataSource(Native Method) causes RuntimeException: status = 0xFFFFFFEA - java

I'm building a media player using ReactNative. In order to accomplish such app I had to export a module I built for retrieving music metadata like album, artist, etc as well as file path.
The code above was working perfectly using jdk1.8.0_112, but since I updated to jdk1.8.0_144 It stopped working.
In this example, I'm not checking for not null, not empty, length > 0, etc, But I really do in the original one.
try {
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource("Path to the file"); // /storage/337C-1C15/Music/Edguy/Speedhoven.mp3
} catch (RuntimeException ex) {
// java.lang.RuntimeException: setDataSource failed: status = 0xFFFFFFEA
}
I'm facing two problems. On one hand, I'm not a great Android dev so getting some clues is such hard task. On the other hand, the error does provide a good description.
Just in case some of you had a better way to accomplish what I tried, I left here the whole code:
#ReactMethod
public void getAll(Callback errorCallback, Callback successCallback){
ContentResolver musicResolver = this.getCurrentActivity().getContentResolver();
Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);
if (musicCursor != null && musicCursor.moveToFirst()) {
WritableArray jsonArray = new WritableNativeArray();
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
WritableMap items = new WritableNativeMap();
int titleColumn = musicCursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE);
int idColumn = musicCursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID);
int artistColumn = musicCursor.getColumnIndex(android.provider.MediaStore.Audio.Media.ARTIST);
try {
do {
items = new WritableNativeMap();
byte[] art;
long thisId = musicCursor.getLong(idColumn);
String thisPath = musicCursor.getString(musicCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
String thisTitle = musicCursor.getString(titleColumn);
String thisArtist = musicCursor.getString(artistColumn);
String duration = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.Media.DURATION));
if(thisPath != null && thisPath != "" && thisPath.endsWith(".mp3")) {
mmr.setDataSource(thisPath);
String album = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM);
String artist = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
String title = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
String genre = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE);
String encoded = "";
String encodedImage = "";
art = mmr.getEmbeddedPicture();
if (album == null) {
album = thisArtist;
}
if (artist == null) {
artist = thisArtist;
}
if (title == null) {
title = thisTitle;
}
if (art != null) {
Bitmap songImage = BitmapFactory.decodeByteArray(art, 0, art.length);
if(songImage != null){
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
songImage.compress(Bitmap.CompressFormat.JPEG, 60, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream.toByteArray();
encodedImage = Base64.encodeToString(byteArray, Base64.DEFAULT);
String pathtoImg = "";
byte[] imageByte = Base64.decode(encodedImage, Base64.DEFAULT);
try {
pathtoImg = Environment.getExternalStorageDirectory() + "/" + thisId + ".jpg";
File filePath = new File(pathtoImg);
FileOutputStream fos = new FileOutputStream(filePath, true);
encoded = pathtoImg;
fos.write(imageByte);
fos.flush();
fos.close();
} catch (FileNotFoundException fnfe) {
errorCallback.invoke(fnfe.getMessage());
} catch (IOException ioe) {
errorCallback.invoke(ioe.getMessage());
}
}
}
String str = String.valueOf(thisId);
items.putString("id", str);
items.putString("album", album);
items.putString("artist", artist);
items.putString("title", title);
items.putString("genre", genre);
if (encoded == "") {
items.putString("cover", "");
} else {
items.putString("cover", "file://" + encoded);
}
items.putString("duration", duration);
items.putString("path", thisPath);
jsonArray.pushMap(items);
}
} while (musicCursor.moveToNext());
successCallback.invoke(jsonArray);
mmr.release();
} catch (RuntimeException e) {
errorCallback.invoke(e.toString());
mmr.release();
} catch (Exception e) {
errorCallback.invoke(e.getMessage());
mmr.release();
}
}
}
Of course, I've already taken a look at:
This post
This post
This post

After debugging and researching a lot I found the problem.
It seems that mmr.setDataSource("path") returns a RuntimeException when something is wrong with the file. This is particularly important since even when the file exists its metadata cannot be retrieved.
The solution was to use the MediaMetadataRetriever into a try/catch like this:
while(cursor.moveNext()){
try {
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource("Path to the file"); // /storage/337C 1C15/Music/Edguy/Speedhoven.mp3
} catch (RuntimeException ex) {
// something went wrong with the file, ignore it and continue
}
}

Related

How to return a view after download a file

My English Hope you can understand me.
Hello guys, im developing a web program using Apache Velocity, but i meet a problem, i cannot return view after output a file by OutPutStream, following is my code:
#Get("test")
public String getPdfInfoByTestId(Invocation invocation, #Param("testIds") String testIds) throws Exception {
HttpServletResponse response = invocation.getResponse();
if (testIds.length() == 0) {
invocation.addModel("status", PdfStatusEnum.NOT_FOUND.getType());
return "admin_pdf_info";
}
String[] idArray = testIds.split(",");
List<Long> idList = string2LongList(testIds);
List<ContestOneTest> contestOneTestList = contestOneTestService.getByIdList(idList);
if (contestOneTestList.size() == 0) {
invocation.addModel("status", PdfStatusEnum.NOT_FOUND.getType());
//response.sendRedirect("index");
return "admin_pdf_info";
}
List<PdfInfo> pdfInfos = new ArrayList<>(contestOneTestList.size() + 1);
//填充表格需要的数据
for (ContestOneTest contestOneTest : contestOneTestList) {
PdfInfo pdfInfo = new PdfInfo();
CtsTestUser ctsTestUser = ctsTestUserService.getUserById(contestOneTest.getActorId());
pdfInfo.setActorName(ctsTestUser.getName());
pdfInfo.setTestId(contestOneTest.getId());
pdfInfo.setPaperName(contestOneTest.getPaperName());
pdfInfo.setPaperId(contestOneTest.getPaperId());
if (contestOneTest.getStatus() == OneTestStatusEnum.FINISHED.getValue() && StringUtils.isNotBlank(contestOneTest.getPdfUrl())) {
pdfInfo.setGenStatus("已处理");
pdfInfo.setRank("无需排队");
pdfInfo.setPdfUrl(contestOneTest.getPdfUrl());
} else {
pdfInfo.setGenStatus("未处理");
Long rank = JedisAdapter.zRank(RedisKeyUtil.getNewContestPdfGenQueue(),
contestOneTest.getId() + "");
pdfInfo.setRank(String.valueOf(rank));
pdfInfo.setPdfUrl("暂无");
}
}
XSSFWorkbook workbook;
String fileName = new StringBuilder().append(contestOneTestList.size())
.append("位考试的PDF生成进度").toString();
try {
//生成表格并作为下载文件输出
workbook = ExcelUtils.buildWorkbook(pdfInfos);
invocation.addModel("status", PdfStatusEnum.HAS_GENERATED);
invocation.addModel("resultCount", contestOneTestList.size());
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
response.setHeader("Content-Type",
"application/vnd.ms-excel");
OutputStream out = response.getOutputStream();
workbook.write(out);
} catch (Exception e) {
e.printStackTrace();
invocation.addModel("status", PdfStatusEnum.ExcelGenFailed.getType());
}
return "admin_pdf_info";
}
Is there any way to solve my problem?
Very grateful for all answers or suggesstions!

Realm findfirst() is returning null

realm newbie here and facing a problem in my project. So what I want to achieve is that, in my app when I click a photo I am saving a realm object inside my database as well as caching the image locally to be used later. Here is the code for both:
#Override
public void onPhotoSelected(PXImage photo) {
PXComposition composition = null;
PXPhoto photoParent = null;
for (PXComposition pxComposition : mSession.getCompositions()) {
if (pxComposition.getItems() == null || pxComposition.getItems().size() < 1)
continue;
for (PXPhoto item : pxComposition.getItems()) {
if (item.getImage().getOriginalPath().equals(photo.getOriginalPath())) {
composition = pxComposition;
photoParent = item;
break;
}
}
}
if (composition == null && photo.isSelected()) {
mRealm.beginTransaction();
String uuid = mSession.addPhoto(photo).getUuid();
mRealm.commitTransaction(); // IMPORTANT to commit transaction. ContentDownloadTask requires PXImage to be written in Realm.
ThreadUtils.getDefaultExecutorService().submit(new ContentDownloadTask(this, photo.getOriginalPath(), uuid));
} else if (composition != null && !photo.isSelected()) {
mRealm.beginTransaction();
if (photoParent.getImage().isDownloaded()) // FIXME What if not copied yet ???
FileUtils.deleteFile(photoParent.getImage().getApplicationPath());
mSession.removePhoto(photoParent);
mRealm.commitTransaction();
}
onCheckChanged(photo);
App.log().v("SESSION", mSession.toString());
}
This is where click events on the photo are handled. After the selection click I am calling ThreadUtils.getDefaultExecutorService().submit(new ContentDownloadTask(this, photo.getOriginalPath(), uuid)); to cache the image locally. Here is the code for the ContentDownloadTask:
public class ContentDownloadTask implements Callable<Void> {
private String id;
private String path;
private Context context;
private Realm mRealm;
public static final String TAG = "ContentDownloadTask";
private static final String DIR_EXTERNAL_NAME = "Local";
private static final String FILE_EXTENSION = ".jpg";
public ContentDownloadTask(Context context, String path, String id) {
this.path = path;
this.id = id;
this.context = context;
}
#Override
public Void call() throws Exception {
try {
Log.d(TAG, "Copying From " + path);
//create output directory if it doesn't exist
final File file = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
if (file == null) {
throw new IllegalStateException("Failed to get external storage files directory");
} else if (file.exists()) {
if (!file.isDirectory()) {
throw new IllegalStateException(file.getAbsolutePath() +
" already exists and is not a directory");
}
} else {
if (!file.mkdirs()) {
throw new IllegalStateException("Unable to create directory: " +
file.getAbsolutePath());
}
}
File to = new File(file, DIR_EXTERNAL_NAME);
if (to.exists()) {
if (!to.isDirectory()) {
throw new IllegalStateException(file.getAbsolutePath() +
" already exists and is not a directory");
}
} else if (!to.mkdirs()) {
throw new IllegalStateException("Unable to create directory: " +
file.getAbsolutePath());
}
to = new File(to, fileName(this.id));
if (!to.exists())
to.createNewFile();
InputStream in = null;
if (PackageUtils.isContentUri(path)) {
Uri uri = PackageUtils.toUri(path);
in = context.getContentResolver().openInputStream(uri);
} else {
File from = new File(this.path);
in = new FileInputStream(from);
}
OutputStream out = new FileOutputStream(to);
// 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();
mRealm = Realm.getDefaultInstance();
PXImage image = mRealm.where(PXImage.class).equalTo("uuid", this.id).findFirst();
if (image == null) {
to.delete();
throw new Exception("Photo Not Found ID: " + this.id);
}
mRealm.beginTransaction();
image.setApplicationPath(to.getPath());
mRealm.commitTransaction();
mRealm.close();
Log.d(TAG, "Complete Copied From " + path + " To " + to.getAbsolutePath());
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
return null;
}
Now the null is returned at this statement: PXImage image = mRealm.where(PXImage.class).equalTo("uuid", this.id).findFirst();. Basically here I need to save the application path of the image that I cached locally inside the realm object. But it's returning null. Also this not happening every time I click the photos. This only happens sometimes and the error is not reproducible. Any kind of help will be appreciated. I have already checked the following duplicate questions:
first
second
third
fourth
public PXPhoto addPhoto(PXImage image) {
PXComposition composition = null;
PXPhoto photo = null;
boolean isLandscape = false;
int photosPerItem = getProduct().getSelectedPhotosPerItem();
switch (getProduct().getRootShortCode()) {
case Product.CategoryType.SQUARES:
case Product.CategoryType.CLASSIC:
case Product.CategoryType.WALLOGRAPHS:
case Product.CategoryType.SIGNATURES:
case Product.CategoryType.MOSAIC:
setLayoutType(image.isLandscape() ? C.LayoutType.LANDSCAPE.ordinal() : C.LayoutType.PORTRAIT.ordinal());
composition = PXComposition.initializeNewComposition(this);
photo = PXPhoto.initializePhoto(image);
break;
case Product.CategoryType.PANORAMA:
composition = PXComposition.initializeNewComposition(this);
photo = PXPhoto.initializePhoto(image);
break;
case Product.CategoryType.STRIPS:
case Product.CategoryType.POSTERS:
if (getCompositions() == null || getCompositions().size() == 0
|| (getProduct().getRootShortCode().equals(Product.CategoryType.STRIPS) &&
getCompositions().last().getItems().size() % photosPerItem == 0))
composition = PXComposition.initializeNewComposition(this);
else
composition = getCompositions().last();
photo = PXPhoto.initializePhoto(image);
break;
}
composition.addItem(photo);
composition.updateComposition();
if (!composition.isManaged()) {
Realm realm = Realm.getDefaultInstance();
composition = realm.copyToRealmOrUpdate(composition);
realm.close();
photo.setComposition(composition);
addComposition(composition);
} else
photo.setComposition(composition);
return photo;
}
EDIT:
uuid generation:
public PXPhoto() {
this.uuid = UUID.randomUUID().toString();
this.autoEnhance = false;
this.zoom = 1;
}

encode special character java

I'm trying to fix a bug in the code I wrote which convert a srt file to dxfp.xml. it works fine but when there is a special character such as an ampersand it throws an java.lang.NumberFormatException error. I tried to use the StringEscapeUtils function from apache commons to solve it. Can someone explain to me what it is I am missing here? thanks in advance!
public class SRT_TO_DFXP_Converter {
File input_file;
File output_file;
ArrayList<CaptionLine> node_list;
public SRT_TO_DFXP_Converter(File input_file, File output_file) {
this.input_file = input_file;
this.output_file = output_file;
this.node_list = new ArrayList<CaptionLine>();
}
class CaptionLine {
int line_num;
String begin_time;
String end_time;
ArrayList<String> content;
public CaptionLine(int line_num, String begin_time, String end_time,
ArrayList<String> content) {
this.line_num = line_num;
this.end_time = end_time;
this.begin_time = begin_time;
this.content = content;
}
public String toString() {
return (line_num + ": " + begin_time + " --> " + end_time + "\n" + content);
}
}
private void readSRT() {
BufferedReader bis = null;
FileReader fis = null;
String line = null;
CaptionLine node;
Integer line_num;
String[] time_split;
String begin_time;
String end_time;
try {
fis = new FileReader(input_file);
bis = new BufferedReader(fis);
do {
line = bis.readLine();
line_num = Integer.valueOf(line);
line = bis.readLine();
time_split = line.split(" --> ");
begin_time = time_split[0];
begin_time = begin_time.replace(',', '.');
end_time = time_split[1];
end_time.replace(',', '.');
ArrayList<String> content = new ArrayList<String>();
while (((line = bis.readLine()) != null)
&& (!(line.trim().equals("")))) {
content.add(StringEscapeUtils.escapeJava(line));
//if (StringUtils.isEmpty(line)) break;
}
node = new CaptionLine(line_num, begin_time, end_time, content);
node_list.add(node);
} while (line != null);
} catch (Exception e) {
System.out.println(e);
}
finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private String convertToXML() {
StringBuffer dfxp = new StringBuffer();
dfxp.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<tt xml:lang=\"en\" xmlns=\"http://www.w3.org/2006/04/ttaf1\" xmlns:tts=\"http://www.w3.org/2006/04/ttaf1#styling\">\n\t<head>\n\t\t<styling>\n\t\t\t<style id=\"1\" tts:backgroundColor=\"black\" tts:fontFamily=\"Arial\" tts:fontSize=\"14\" tts:color=\"white\" tts:textAlign=\"center\" tts:fontStyle=\"Plain\" />\n\t\t</styling>\n\t</head>\n\t<body>\n\t<div xml:lang=\"en\" style=\"default\">\n\t\t<div xml:lang=\"en\">\n");
for (int i = 0; i < node_list.size(); i++) {
dfxp.append("\t\t\t<p begin=\"" + node_list.get(i).begin_time + "\" ")
.append("end=\"" + node_list.get(i).end_time
+ "\" style=\"1\">");
for (int k = 0; k < node_list.get(i).content.size(); k++) {
dfxp.append("" + node_list.get(i).content.get(k));
}
dfxp.append("</p>\n");
}
dfxp.append("\t\t</div>\n\t</body>\n</tt>\n");
return dfxp.toString();
}
private void writeXML(String dfxp) {
BufferedWriter out = null;
try {
out = new BufferedWriter(new FileWriter(output_file));
out.write(dfxp);
out.close();
} catch (IOException e) {
System.out.println("Error Writing To File:"+ input_file +'\n');
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
if ((args.length < 2) || (args[1].equals("-h"))) {
System.out.println("\n<--- SRT to DFXP Converter Usage --->");
System.out
.println("Conversion: java -jar SRT_TO_DFXP.jar <input_file> <output_file> [-d]");
System.out
.println("Conversion REQUIRES a input file and output file");
System.out.println("[-d] Will Display XML Generated In Console");
System.out.println("Help: java -jar SRT_TO_DFXP.jar -h");
} else if (!(new File(args[0]).exists())) {
System.out.println("Error: Input SubScript File Does Not Exist\n");
} else {
SRT_TO_DFXP_Converter converter = new SRT_TO_DFXP_Converter(
new File(args[0]), new File(args[1]));
converter.readSRT();
String dfxp = converter.convertToXML();
if ((args.length == 3) && (args[2].equals("-d")))
System.out.println("\n" + dfxp + "\n");
converter.writeXML(dfxp);
System.out.println("Conversion Complete");
}
}
here's part of the srt file that it is throwing an error when exported and run as a jar file.
1
00:20:43,133 --> 00:20:50,599
literature and paper by Liversmith & Newman, and I think the point is well made that a host of factors

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" />

the value of Title property is not getting updated for jpg file using apache sanselan?

i want to update the metadata (like tag,comments etc.....) of .jpg & .tif files using JAVA
can any one help me ....
note :i have tried with the below code but when i chek the property of file using windows explorer the value of title is not updated
public static void changeExifMetadata(File jpegImageFile, File dst)
throws IOException, ImageReadException, ImageWriteException {
OutputStream os = null;
try
{
TiffOutputSet outputSet = null;
IImageMetadata metadata = Sanselan.getMetadata(jpegImageFile);
JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
if (null != jpegMetadata)
{
TiffImageMetadata exif = jpegMetadata.getExif();
if (null != exif)
{
outputSet = exif.getOutputSet();
}else {}
}
if (null == outputSet)
outputSet = new TiffOutputSet();
{
final TiffOutputDirectory exifDir = outputSet .getOrCreateExifDirectory();
byte[] rawBytes = "KasperAuthor".getBytes("UTF-16LE");
byte[] nullTerminatedBytes = new byte[rawBytes.length + 2];
exifDir.removeField(ExifTagConstants.EXIF_TAG_XPTITLE);
TiffOutputField authorField = new TiffOutputField(ExifTagConstants.EXIF_TAG_XPTITLE, ExifTagConstants.EXIF_TAG_XPTITLE.dataTypes[0], nullTerminatedBytes.length, nullTerminatedBytes);
exifDir.add(authorField);
}
} finally
{
if (os != null)
try
{
os.close();
} catch (IOException e)
{
}
}
}
thanks in advance ....

Categories