I need to display a PDF document inside the mobile browsers, without asking if the user wants to download it. Using Safari (iOs) I can do it perfectly, but when I try to do the same thing using the Android's (version ICS) native browser (called "Internet") the file is downloaded, and even the download doesn't seem to work.. After the download is done, the file is shown as Download unsuccessful, and I can't open it using a PDF file reader.
The same link download works fine is all others browsers whos not mobile.
I believe the problem is in some of the headers that I need to add to the response.
I'm setting the Content-Type as application/pdf and the Content-Disposition as inline;filename="report.PDF"
Is there anyone who had the same problem?
Anyone who knows a solution? :)
Thanks!
Lucas
The android browser does not have a default built in PDF support so this cannot be easily done with that.
However here are two things you could do.
1) Download and install adobe reader from the play store and then try the following code
First you create a file on the device memory and then you read the pdf data into it.
"theurl" is the url of where the pdf is located
InputStream in = null;
File dst = new File(Environment.getExternalStorageDirectory()+"/myPDF.pdf");
try {
in = theurl.openStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
OutputStream out = null;
try {
out = new FileOutputStream(dst);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
}
// Transfer bytes from in to out
try {
byte[] buf = new byte[100000];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Intent intent = new Intent();
Uri path = Uri.fromFile(dst);
intent.setDataAndType(path, "application/pdf");
startActivity(intent);
This will download the pdf, create it in your device memory and then the intent will open it on through your application using adove reader on your device.
Another option is
2) Go to http://jaspreetchahal.org/android-how-to-open-pdf-file-within-the-browser/ and see how that guy did it
Related
I am writing a log data to the File in android. But I am unable to understand where this file is stored on my android device ( google nexsus 7 ). Where and How should I look for the contents of the file ?
Following is the piece of code I am using to write log data to the file.
public File AppendingLog(String LogData){
try {
File logFile = new File(Environment.getExternalStorageDirectory(),
"yourLog.txt");
if (!logFile.exists()) {
try {
logFile.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile,
true));
buf.append(LogData);
buf.newLine();
buf.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return logFile;
}
android.util.Log.d("myapp", logFile.toString());
On most devices, it will be in /sdcard/. The exact path will be /sdcard/yourLog.txt.
As you are using Environment.getExternalStorageDirectory(), the actual path will differ between devices. Some devices return the external sd card path, but most will return the internal sd card's path, which usually is /sdcard/.
I think answers below are what you need.
You can also download Astro File Manager App which will also give you an idea where your files go on Android System.
I'm having issues using the Cards from the recently released GDK. Basically, Card.addImage() can only take two arguments, a resource id or a URI.
For my use case, I need to open an image that exists as a file not directly as a resource. So for testing purposes I'm including the images in the assets folder. Trying to access them directly from the asset folder fails, so I'm copying them from there to internal storage. Once they're copied, I generate a URI from the file and assign it to the card. The resulting card shows a grey block where the image should be.
String fileName = step.attachment; //of the form, "folder1/images/image1.jpg"
File outFile = new File(getFilesDir()+File.separator+fileName);
FileChannel inputChannel = null;
FileChannel outputChannel = null;
try {
//check to see if the file has already been cached in internal storage before copying
if(!outFile.exists()) {
FileInputStream inputStream = new FileInputStream(getAssets().openFd(fileName).getFileDescriptor());
FileOutputStream outputStream = openFileOutput(fileName, Context.MODE_PRIVATE);
inputChannel = inputStream.getChannel();
outputChannel = outputStream.getChannel();
outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
try {
if(inputChannel!=null)
inputChannel.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(outputChannel!=null)
outputChannel.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
card.addImage(Uri.fromFile(outFile));
It's hard to diagnose because I have no clue what the Card is doing internally.
Instead of writing
new FileInputStream(getAssets().openFd(fileName).getFileDescriptor());
can you try
getAssets().openFd(fileName).createInputStream();
and see if it works?
To answer your original question, the addImage method supports resource: and file: URIs.
This is very strange, but I managed to solve my problem. I replaced the file copy code with the following and it appears to have solved my issues
InputStream in = null;
OutputStream out = null;
try {
in = getAssets().open(step.attachment);
out = new FileOutputStream(outFile);
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch(IOException e) {
Log.e("tag", "Failed to copy asset file: " + step.attachment, e);
}
It's not clear to me why/how I was copying my entire apk, but I'm guessing it's the call to
getAssets().openFd(fileName).getFileDescriptor()
Perhaps it was returning the file descriptor of the apk. It's odd because I've seen some claim that the previous method works.
I am trying to read some files and put them into a new file using the below method in Eclipse.
But I am getting a read-only file system EROFS error in eclipse at run time.
Input file names will be provided as function parameter. Files are present in res\raw folder.
SampleFile.mp3 is an empty audio file placed at the location.
public void myfun(Set s)
{
try {
FileOutputStream fos=new FileOutputStream(".\\res\raw\sampleFile.mp3",true);
FileInputStream fis;
Iterator ptr=s.iterator();
String str;
while(ptr.hasNext()!=null)
{
str=ptr.next().toString();
fis=new FileInputStream(str);
int i;
while((i=fis.read())!=-1)
{
fos.write(i);
}
fis.close();
}
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You are trying to write into the 'res/raw' folder of the current directory, but android does not work like that. Go read the Storage Options section of the Android Development Guide, and choose one that fits your needs (and use case).
Also, you want to concatenate multiple files into an mp3? Are they by any chance... mp3 files themselves that you want to play?
I am trying to download an mp3 file from google TTS API, here is the code
try {
String path ="http://translate.google.com/translate_tts?tl=en&q=hello";
//this is the name of the local file you will create
String targetFileName = "test.mp3";
boolean eof = false;
URL u = new URL(path);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.addRequestProperty("User-Agent", "Mozilla/5.0");
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
FileOutputStream f = new FileOutputStream(new File(Environment.getExternalStorageDirectory()
+ "/download/"+targetFileName));
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ( (len1 = in.read(buffer)) > 0 ) {
f.write(buffer,0, len1);
}
f.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
This works fine, but when I try to make the request for languages like chinese or greek which use special characters
String path ="http://translate.google.com/translate_tts?tl=zh-TW&q=你好";
The mp3 file I get back has no sound but from the size of the file I can tell it has data in it. When I try the same with Arabic
String path ="http://translate.google.com/translate_tts?tl=ar&q=%D8%A7%D9%84%D9%84%D9%87";
I get back an empty mp3 file with 0 bytes.
I have tried using different user agents and nothing seems to work.
Please help.
Thank You
Use the path as a URI rather than a string then change it to an ascii string.
URI uri = new URI("http://translate.google.com/translate_tts?tl=zh-TW&q=你好");
URL u = new URL(uri.toASCIIString());
I have your same problem. But I have solve it yesterday.
I wanna the API say Chinese and save to mp3 file .
The url now is:
path ="http://translate.google.com/translate_tts?tl=zh-TW&q=你好"
you do as follow:
path ="http://translate.google.com/translate_tts?ie=UTF-8&tl=zh-TW&q=".urlencode("你好");
Add a param ie=utf-8 AND encode the Chinese words.
You'll got what you want .
and if the app crashes try this
txtToTranslate = txtToTranslate.replace(" ", "%20");
it replaces the spaces between the words.
In my app there are 3 EditTexts. I want to write the content of this EditTexts to a file, but the filewrite throws a nullpointer exception. Why?
OutputStream f1; is declared globally.
BtnSave = (Button)findViewById(R.id.Button01);
BtnSave.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
intoarray = name + "|" + number + "|" + freq + "\n";
Toast.makeText(Main.this, "" + intoarray, Toast.LENGTH_SHORT).show();
//so far so good
byte buf[] = intoarray.getBytes();
try {
f1 = new FileOutputStream("file2.txt");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
f1.write(buf); //nullpointer exception
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
f1.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Most likely
f1 = new FileOutputStream("file2.txt");
failed and since you caught the exception f1 remained null. In most cases in Android you can only create files either in your application data directory or external storage.
The way you are currently using this won't work, generally you are trying to write to internal storage, which is private to your app and must be contained within your applications directory.
The proper way to create the file stream is
fin = openFileOutput("file2.txt", Context.MODE_PRIVATE); // open for writing
fout = openFileInput("file2.txt", Context.MODE_PRIVATE); // open for reading
Which will locate the file in your storage area for your application, which is typically something like
/data/data/com.yourpackagename/files/...
You can still create directories within your applications area if you need a directory structure of course.
If you need to write to external storage that's a different process, for more information see Android Data Storage
Sorry for all you were trying help me, I asked the wrong question. I wanted to use internal storage (and it is now working). I don't know what the problem is, but the with the code below (that i have used a lot) filewrite is ok:
try {
File root = Environment.getExternalStorageDirectory();
File file = new File(root, "Data.txt");
if (root.canWrite()) {
FileWriter filewriter = new FileWriter(file, true);
BufferedWriter out = new BufferedWriterfilewriter);
out.write(intoarray);
out.close();
}
} catch (IOException e) {
Log.e("TAG", "Could not write file " + e.getMessage());
}
I would delete the topic if I could. I accept this answer to close the topic.
Thanks, anyway.