Android Java Get path from URI for an mp4 - java

I'm trying to get a load a mp4 file from the android file browser. However the path from the following code does not work. It throws an exception
Uri currFileURI = data.getData();
String path=currFileURI.getPath();
MediaExtractor extractor = new MediaExtractor();
try {
extractor.setDataSource(path);
} catch( IOException e) {
e.printStackTrace();
return;
}
Data I have:
data = {Intent#9869} "Intent { dat=content://com.android.providers.downloads.documents/document/44 flg=0x1 }"
currFileURI = {Uri$HierarchicalUri#9870} "content://com.android.providers.downloads.documents/document/44"
path = "/document/44"
I see this code in stackoverflow:
How to get the Full file path from URI
This looks like an overkill
I can see the method takes in a file path.
https://developer.android.com/reference/android/media/MediaExtractor#setDataSource(java.lang.String)
So it looks the path from the android file browser is different from what the method wants. I also see that the path from the file browser is different than the file name. Anybody have an insight into what the path should look like?

So it looks the path from the android file browser is different from what the method wants
It is not a filesystem path, because a Uri is not a file.
I can see the method takes in a file path
There are many forms of setDataSource() on MediaExtractor, including one that takes a Uri. Try using that method with your Uri.

Related

Cannot find protocol 'resource' in URL constructor

I've implemented a class to read from RSS 2.0 and Atom 1.0 feeds. I want to write some unit tests in order to verify functionality. Here is the feed reader section of my code:
private String readFeed(final String url) throws IOException
{
final StringBuilder builder = new StringBuilder();
final URL feedUrl = new URL(url);
final BufferedReader in = new BufferedReader(
new InputStreamReader(feedUrl.openStream()));
String input;
while ((input = in.readLine()) != null)
{
builder.append(input);
}
in.close();
return builder.toString();
}
After some research, I figured the best way to test would be to have a sample feed as an XML file in my project resources directory.
I've created a example file "resources/rss2-0.xml"
I'm sending in the following value to the readFeed function, "resource:///rss2-0.xml",
and I keep receiving java.net.MalformedURLException: unknown protocol: resource
This is my first time using a URL pathway to load from a resource. From what I can tell, resource seems like it should be a valid protocol. Anyone have any ideas what I may be doing wrong or other ways to go about this?
If you want to deal with path using your local file system, the Path class is best suited for this task.
An object that may be used to locate a file in a file system. It will
typically represent a system dependent file path.
You can use it like so :
Path path = FileSystems.getDefault().getPath("/resources/rss2-0.xml");
BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);
If your really want to deal with URL, the protocol you're looking for is simply "file". So it would be file:///rss2-0.xml instead of resource:///rss2-0.xml and even file:/resources/rss2-0.xml to be exact.
Note that in your case, you will indeed have to deal with URLs sooner or later, but when working on local tests, using the Path class will save you troubles. If you want another alternative, try the URI class. Since an URI is an identifier (see difference between URI and URL) it can identify either an URL or a Path an may serve as a bridge between your production code which will ultimately deal with URLs and your test code where the Path class could be best put in use.
For example :
public interface FeedReader {
String readFeed(final URI uri);
}
And 2 implementations, one for testing locally :
public class LocalFeedReader implements FeedReader {
#Override
public String readFeed(final URI uri) {
// URI -> Path
// then dealing with Path to target local rss2-0.xml file
}
}
And one for production code :
public class WebFeedReader implements FeedReader {
#Override
public String readFeed(final URI uri) {
// URI -> URL
// then dealing with URL to target real resources
}
}
The java docs say that only http, https, file, and jar are "guaranteed" to exist on the search path for protocol handlers. Others only "may" be supported.
http://docs.oracle.com/javase/8/docs/api/java/net/URL.html#URL-java.lang.String-java.lang.String-int-java.lang.String-
It looks like if you want a custom handler that isn't supported in your java distribution, you'll have to create one.
http://mjremijan.blogspot.com/2012/02/create-your-own-java-url-handlers.html

URI scheme is not "file" plug in error

I am getting the error
URI scheme is not “file”
after I run the plugin that I am trying to create. The error is thrown from the following method :
protected File getFile(String fileName) throws URISyntaxException {
System.out.println(fileName);
URI binUri = EpsilonStandaloneExample.class.getResource(fileName).toURI();
URI uri = null;
System.out.println(uri);
if (binUri.toString().indexOf("bin") > -1) {
uri = new URI(binUri.toString().replaceAll("bin", "src"));
}
else {
uri = binUri;
}
System.out.println(uri);
return new File(uri);
}
When I run my class as a java application everything is working and i am getting the right path which is:
file:/E:/epsilon-eclipse/workspace/Test2/src/org/eclipse/epsilon/examples/standalone/egl/oxfordDriver.egl
Now that i am implementing a plugin and run this code the URI returned is:
bundleresource://652.fwk1463565218/org/eclipse/epsilon/examples/standalone/egl/oxfordDriver.egl
This URI is not correct and thats why the error is thrown.
Any suggestions of how to solve this problem?
I assume you want to load a file which is part of the resources in your plugin. This is not possible using a file path, as all resources in a plugin are resolved using a bundle relative URL (and the bundle itself might be deployed as jar file, so there even isn't a normal file). Have a look at reading resources from a plugin.
Also make sure that you add those files to your build.properties (see section "Binary build"). It is not enough to have the files lying around in the plugin project.

Java URL: Unknown Protocol "C"

I know there are similar questions to this one on SO (like this one), however, after reading through the list of "Questions with similar titles", I still feel strongly that this is unique.
I am working with the iText library to generate PDFs from inside a Swing application. iText's Jpeg class requires a URL in its constructor to locate an image/jpg that you want to add to the PDF file.
When I set this URL to the absolute file path of my JPG file, I get a MalformedURLException claiming unknown protocol: c ("c" being the C:\ drive on my local disk).
Is there any hack/circumvention to this, or do I have to host this JPG somewhere and have the URL find it over the net? Here is the code that is failing:
try {
String imageUrl = "C:\Users\MyUser\image.jpg";
Jpeg image = new Jpeg(new URL(imageUrl));
} catch(Exception exc) {
System.out.println(exc.getMessage());
}
Please note: The URL does properly escape the string (thus "\" are converted to "\ \", etc.).
Thanks in advance!
You need to turn the path to the image.jpg file into a file:// URL, like this:
String imageUrl = "file:///C:/Users/MyUser/image.jpg";
Otherwise it interprets the C as the URL protocol.
Try with
String imageUrl = "file:///C:/Users/MyUser/image.jpg";
Try this
try {
String imageUrl = "file:///C:/Users/MyUser/image.jpg";
Jpeg image = new Jpeg(new URL(imageUrl));
} catch(Exception exc) {
System.out.println(exc.getMessage());
}
In my case the issue was that I was having "%" in my file name. Once I changed it, the file was loaded successfully. So I guess special characters are not allowed in file names, at least in windows.
Searching the file with its directory and adding in the image to assign to the ImageView
File file = new File("F:/a.jpg");
Image image = new Image(arquivo.toURI().toString()); //here is magic happens
imageView.setImage(image);

Java URL problem

A webpage contains a link to an executable (i.e. If we click on the link, the browser will download the file on your local machine).
Is there any way to achieve the same functionality with Java?
Thank you
Yes there is.
Here a simple example:
You can have a JSF(Java Server Faces) page, with a supporting backing bean that contains a method annotated with #PostConstruct This means that any action(for example downloading), will occur when the page is created.
There is already a question very similar already, have a look at: Invoke JSF managed bean action on page load
You can use Java's, URL class to download a file, but it requires a little work. You will need to do the following:
Create the URL object point at the file
Call openStream() to get an InputStream
Open the file you want to write to (a FileOutputStream)
Read from the InputStream and write to the file, until there is no more data left to read
Close the input and output streams
It doesn't really matter what type of file you are downloading (the fact that it's an executable file is irrelevant) since the process is the same for any type of file.
Update: It sounds like what you actually want is to plug the URL of a webpage into the Java app, and have the Java app find the link in the page and then download that link. If that is the case, the wording of your question is very unclear, but here are the basic steps I would use:
First, use steps 1 and 2 above to get an InputStream for the page
Use something like TagSoup or jsoup to parse the HTML
Find the <a> element that you want and extract its href attribute to get the URL of the file you need to download (if it's a relative URL instead of absolute, you will need to resolve that URL against the URL of the original page)
Use the steps above to download that URL
Here's a slight shortcut, based on jsoup (which I've never used before, I'm just writing this from snippets stolen from their webpage). I've left out a lot of error checking, but hey, I usually charge for this:
Document doc = Jsoup.connect(pageUrl).get();
Element aElement = doc.getElementsByTag("a").first() // Obviously you may need to refine this
String newUrl = aElement.attr("abs:href"); // This is a piece of jsoup magic that ensures that the destination URL is absolute
// assert newUrl != null
URL fileUrl = new URL(newUrl);
String destPath = fileUrl.getPath();
int lastSlash = destPath.lastIndexOf('/');
if (lastSlash != -1) {
destPath = destPath.substring(lastSlash);
}
// Assert that this is really a valid filename
// Now just download fileUrl and save it to destPath
The proper way to determine what the destination filename should be (unless you hardcode it) is actually to look for the Content-Disposition header, and look for the bit after filename=. In that case, you can't use openStream() on the URL, you will need to use openConnection() instead, to get a URLConnection. Then you can use getInputStream() to get your InputStream and getRequestProperty("Content-Disposition") to get the header to figure out your filename. In case that header is missing or malformed, you should then fall-back to using the method above to determine the destination filename.
You can do this using apache commons IO FileUtils
http://commons.apache.org/io/apidocs/org/apache/commons/io/FileUtils.html#copyURLToFile(java.net.URL, java.io.File)
Edit:
I was able to successfully download a zip file from source forge site (it is not empty), It did some thing like this
import java.io.File;
import java.net.URL;
import org.apache.commons.io.FileUtils;
public class Test
{
public static void main(String args[])
{
try {
URL url = new URL("http://sourceforge.net/projects/gallery/files/gallery3/3.0.2/gallery-3.0.2.zip/download");
FileUtils.copyURLToFile(url, new File("test.zip"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I was able successfully download tomcat.exe too
URL url = new URL("http://archive.apache.org/dist/tomcat/tomcat-6/v6.0.16/bin/apache-tomcat-6.0.16.exe");

Locating a file in a network disk in a Servlet

I create ImageServlet to refer to videos out of my web application scope.
The location of all of my videos are on a intranet location that could be reached from any computer in the intranet:
String path = "\\myip\storage\ogg\VX-276.ogg"
In my application, when I write it as URL - it can't display it!
If I try to open it with chrome it automatically changes it to file://myip/storage/ogg/VX-276.ogg and the file is being displayed.
I tried to do so: file:////odelyay_test64/storage/ogg/
as well but Java converts the string to: file:\myip\storage\ogg\VX-276.ogg which does not exist!
What is the correct way to refer to it?
EDITED
I create a small test:
String path = "file://myip/storage/ogg/VX-276.ogg";
File file = new File(path);
if (file.exists())
System.out.println("exists");
else {
System.out.println("missing" + file.getPath());
}
and I get:
missing file:\myip\storage\ogg\VX-276.ogg
As you can see the slashes are being switched
As per your previous question, you're referencing the resource in a HTML <video> tag. All URLs in the HTML source code must be http:// URLs (or at least be relative to a http:// URL). Most browsers namely refuse to load resources from file:// URLs when the HTML page is itself been requested by http://. You just need to let the URL point to the servlet. If the servlet's doGet() method get hit, then the URL is fine and you should not change it.
Your concrete problem is in the way how you open and read the desired file in the servlet. You need to ensure that the path in File file = new File(path) points to a valid location before you open a FileInputStream on it.
String path = "file://myip/storage/ogg/VX-276.ogg";
File file = new File(path);
// ...
If the servlet code is well written that it doesn't suppress/swallow exceptions and you have read the server logs, then you should have seen an IOException such as FileNotFoundException along with a self-explaining message in the server logs whenever reading the file fails. Go read the server logs.
Update as per the comments, it turns out that you're using Windows and thus file:// on a network disk isn't going to work for Java without mapping it on a drive letter. You need to map //myip on a drive letter first, for example X:.
String path = "X:/storage/ogg/VX-276.ogg";
File file = new File(path);
// ...
in the end I used VFS library of apache and my code looks like this:
public static void main(String[] args) {
FileSystemManager fsManager = null;
String path = "\\\\myip\\storage\\ogg\\VX-276.ogg";
try {
fsManager = VFS.getManager();
FileObject basePath;
basePath = fsManager.resolveFile("file:" + path);
if (basePath.exists())
System.out.println("exists");
else {
System.out.println("missing" + basePath.getURL());
}
} catch (FileSystemException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
In this way, I don't need to create a driver for each user of the system and it allows me not to depend on operation system!

Categories