I have converted docx to html and able to display it in webview with images. However, when I try saving the html extracted from webview to internal storage the images are not visible and are rather leaving a blank space in the saved html file.
The code for doing this as follows:
view = (WebView) findViewById(R.id.webpage);
final long startTime = System.currentTimeMillis();
final long endTime;
try {
final LoadFromZipNG loader = new LoadFromZipNG();
WordprocessingMLPackage wordMLPackage = (WordprocessingMLPackage)loader.get(new FileInputStream(new File(Environment.getExternalStorageDirectory()+"/"+getIntent().getStringExtra("textReportFileName"))));
String IMAGE_DIR_NAME = "images";
String baseURL = this.getDir(IMAGE_DIR_NAME, Context.MODE_WORLD_READABLE).toURL().toString();
System.out.println(baseURL); // file:/data/data/com.example.HelloAndroid/app_images/
// Uncomment this to write image files to file system
ConversionImageHandler conversionImageHandler = new AndroidFileConversionImageHandler( IMAGE_DIR_NAME, // <-- don't use a path separator here
baseURL, false, this);
Toast.makeText(getApplicationContext(),baseURL,Toast.LENGTH_SHORT).show();
HtmlExporterNonXSLT withoutXSLT = new HtmlExporterNonXSLT(wordMLPackage, conversionImageHandler);
html = XmlUtils.w3CDomNodeToString(withoutXSLT.export());
File filex = new File(Environment.getExternalStorageDirectory()+"/temp/"+getIntent().getStringExtra("textReportFileName").replace("docx","html"));
if(filex.exists()) {
Toast.makeText(getApplicationContext(),"File exists",Toast.LENGTH_SHORT).show();
InputStream iss = new FileInputStream(filex);
int size = iss.available();
byte[] buffer = new byte[size];
iss.read(buffer);
iss.close();
html = new String(buffer);
//html = html.substring(html.indexOf("0\" rows=\"9\">") + 16);
}
else{
}
} catch (Exception e) {
e.printStackTrace();
finish();
} finally {
endTime = System.currentTimeMillis();
}
The highlighted toast message gives the output : file:/data/data/com.tek.teksmartlab/app_images/
Also the final html file has the image tags with the src = "file:/data/data/com.tek.teksmartlab/app_images/image1.jpg" (like form)
Now I understand the path file:/data/data/com.tek.teksmartlab/app_images/ is non existent in the internal storage so HOW DO I SAVE THE IMAGES FROM THIS PATH TO INTERNAL STORAGE??
I have tried copying the image from assets folder to internal storage code but that didn't work for me.
Your url is not complete you need it to start with file:// so the whole thing would be
file:///data/data/com.tek.teksmartlab/app_images/image1.jpg
Related
I implemented a share button in my app. When I want to share, I can select a saved json data from the device and select via which way I want to share it (mail etc.). The problem is, that the data is NOT in the attachements. The problem is likely because I use the internal app storage. Therefore I want to save tje json data into the external storage, what would be better in my case anyway. But I am not really sure how to do that. I am not sure if I should use the Media type of content of the Documents and other files type of content which is provided by android. There is also the Appspecific files type but this looks like it is not applicaple for me, because I need to share the json data wit ha share functin. At the moment my code looks like this:
Save Function, which get's a file name I can choose myself
private void saveState(String name) {
File file = new File(getFilesDir(), name + ".json");
try{
OutputStream out = new FileOutputStream(file);
MyJsonWriter writer = new MyJsonWriter();
writer.writeJsonStream(out, ... //data structure);
out.close();
}catch (Exception e){
Log.e("saveState ERROR", "----------------------------------------------------");
}
}
LoadButtonClick Functin which shows me all files
public void loadStateClick(View view) {
final LinearLayout layout = new LinearLayout(MainActivity.this);
layout.setOrientation(LinearLayout.VERTICAL);
String[] files = MainActivity.this.fileList();
... //more code which is not important here
Load Function
private void loadState(String name) {
File file = new File(getFilesDir(), name);
InputStream in = null;
... //setting my data structure, not important here
try{
in = new FileInputStream(file);
MyJsonReader reader = new MyJsonReader(MainActivity.this);
SaveData savedData = reader.readJsonStream(in);
... // handling data structure, not important here
in.close();
}catch (Exception e){
Log.e("LOAD ERROR", e.toString());
}
}
i'm getting a pdf file from an api, and i got something like that http://x/docs/document1
In my android project, i have like this:
try{
Android.Content.Intent activity = new Android.Content.Intent(this, typeof(WebViewPDF));
activity.AddFlags(Android.Content.ActivityFlags.GrantReadUriPermission);
activity.AddFlags(Android.Content.ActivityFlags.NoHistory);
string uriAndroid = "http://x/docs/document1";
activity.PutExtra("url", JsonConvert.SerializeObject(uriAndroid));
StartActivity(activity);
}catch (Exception){
...
}
The main problem is, i cannot modify the api, so the endpoint is http://x/docs/document1, but if i try another uri, with the .pdf extension, for example https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf it works fine.
I don't know if i need to get that info from the API in a different way,
How can i show the pdf in the webView or external app without download first the doc?
The solution was download first and then open from local.
void PrintPdf(Uri uri)
{
var webClient = new WebClient();
webClient.Proxy = WebRequest.DefaultWebProxy;
webClient.Credentials = new NetworkCredential("UserName", "Pass");
webClient.Encoding = Encoding.UTF8;
var bytes = webClient.DownloadData(uri);
var text = bytes; // get the downloaded text
string localFilename = "NameforPdf.PDF";
string localPath = System.IO.Path.Combine(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).ToString(), localFilename);
File.WriteAllBytes(localPath, text); // writes to local storage
bool exists = File.Exists(localPath);
if (exists)
{
Java.IO.File file = new Java.IO.File(localPath);
file.SetReadable(true);
//That's the important part, notice the content://
Android.Net.Uri uriLocal = Android.Net.Uri.Parse("content://" + localPath);
Intent intent = new Intent(Intent.ActionView);
intent.SetFlags(ActivityFlags.NewTask);
intent.SetDataAndType(uriLocal, "application/pdf");
intent.AddFlags(ActivityFlags.GrantReadUriPermission);
try
{
StartActivity(intent);
}
catch (Exception)
{
Toast.MakeText(Xamarin.Forms.Forms.Context, "pdf reader not installed", ToastLength.Short).Show();
}
}
}
I'm trying to read a text file in Unity. I have problems.
In desktop, when I generate the Stand Alone, I need to copy manually the text file. I don't know how include inside my application.
In web application (and Android), I copy the file manually but my game can't find it.
This is my "Read" code:
public static string Read(string filename) {
//string filePath = System.IO.Path.Combine(Application.streamingAssetsPath, filename);
string filePath = System.IO.Path.Combine(Application.dataPath, filename);
string result = "";
if (filePath.Contains("://")) {
// The next line is because if I use path.combine I
// get something like: "http://bla.bla/bla\filename.csv"
filePath = Application.dataPath +"/"+ System.Uri.EscapeUriString(filename);
//filePath = System.IO.Path.Combine(Application.streamingAssetsPath, filename);
WWW www = new WWW(filePath);
int timeout = 20*1000;
while(!www.isDone) {
System.Threading.Thread.Sleep(100);
timeout -= 100;
// NOTE: Always get a timeout exception ¬¬
if(timeout <= 0) {
throw new TimeoutException("The operation was timed-out ("+filePath+")");
}
}
//yield return www;
result = www.text;
} else {
#if !UNITY_WEBPLAYER
result = System.IO.File.ReadAllText(filePath);
#else
using(var read = System.IO.File.OpenRead(filePath)) {
using(var sr = new StreamReader(read)) {
result = sr.ReadToEnd();
}
}
#endif
}
return result;
}
My questions are:
How can I include my "text file" as a Game Resource?
Is something wrong on my code?
Unity offers a special folder called Resources where you can keep files and load them at runtime through Resources.Load
Resources.Load on Unity docs
Create a folder called Resources in your project, and put your files in it (in this case, you text file).
Here's an example. It assumes that you're sticking your file straight into the Resources folder (not a subfolder in Resources)
public static string Read(string filename) {
//Load the text file using Reources.Load
TextAsset theTextFile = Resources.Load<TextAsset>(filename);
//There's a text file named filename, lets get it's contents and return it
if(theTextFile != null)
return theTextFile.text;
//There's no file, return an empty string.
return string.Empty;
}
I have a database of recipes, each of which has an image.
The database can be updated from a JSON feed. I then need to retrieve any new images for a newly added recipe. I'm having issues getting an image from a URL, saving it and then updating a recipe with that image.
There are a lot of different answers on Stack Overflow and other sites. Often I can get to what I would expect to be a working point. Where images appear to be getting saved, and any debug print outs I add in show what I expect, but I cannot update my ImageView. By that I mean it remains blank.
I'm not sure if my issue is simply a poor attempt to update the ImageView, or a problem when saving the images. This code is a bit sloppy and inefficient at the moment. I've tried 10-15 variations on this from suggested other posts and have had no luck. Any help would be greatly appreciated.
Manifest
/* I have these two set (Not sure both are necessary) */
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Main frontend class
/* Create databaseHelper */
DatabaseHelper db = new DatabaseHelper(getApplicationContext());
/* ImageView to update image of */
ImageView foodpic = (ImageView)findViewById(R.id.foodpic);
/* Check if image is already available in drawable folder */
int resID = this.getResources().getIdentifier(filename, "drawable", "mypackage.name");
if (resID == 0) {
/* If not, call function to retrieve from external storage */
newPic = db.getOutputMediaFile(origFilename);
if(newPic.exists()) {
myBitmap = BitmapFactory.decodeFile(newPic.getAbsolutePath());
foodpic.setImageBitmap(myBitmap);
foodpic.invalidate(); /* Tried with and without this */
}
}
DatabaseHelper function to retrieve image saved from URL
public File getOutputMediaFile(String filename){
/* Dir I'm (attempting) to save and retrieve images from */
File mediaStorageDir = new File(Environment.getExternalStorageDirectory() + "/Android/data/mypackage.name/Files");
/* Create the storage directory if it does not exist */
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
return null;
}
}
/* Get file extension */
String[] fileNameSplit = filename.split("\\.");
String extension = fileNameSplit[(fileNameSplit.length-1)];
/* Get filename, remove special chars & make lowercase */
int extensionIndex = filename.lastIndexOf(".");
filename = filename.substring(0, extensionIndex);
filename = filename.toLowerCase(Locale.getDefault());
filename = filename.replaceAll("[^a-z0-9]", "");
/* Re-make filename to save image as */
String mImageName="r"+filename+"."+extension;
/* Get file
mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);
return mediaFile;
}
DatabaseHelper function to save image from URL
- Called per recipe/image added to the database, if image not found in drawable folder.
public static void saveImage(String imageUrl, String destinationFile, String extension) throws IOException {
URL url = new URL (imageUrl);
InputStream input = url.openStream();
try {
File storagePath = Environment.getExternalStorageDirectory();
OutputStream output = new FileOutputStream (new File(storagePath,destinationFile));
try {
byte[] buffer = new byte[2048];
int bytesRead = 0;
while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) {
output.write(buffer, 0, bytesRead);
}
} finally {
output.close();
}
} finally {
input.close();
}
*Formatting.
Store URL as string in DB and display it with Image Loader is more easy, but doesn't work off line ,if ur apps need internet to work, the image loader could be better.
android-loading-image-from-url-http
I ended up using this library.
It's not an ideal solution as I'd have preferred to look through this library, understand it fully and explain it for others who may need a similar answer. But for now, people attempting to do something similar should be able to use this too.
https://code.google.com/p/imagemanager/
ey up. ive built a simple music app that reads wav files from the sdcard and plays them.
how do i access the default media directory?
this is how i get the sdcard
public void LoadSounds() throws IOException
{
String extState = Environment.getExternalStorageState();
if(!extState.equals(Environment.MEDIA_MOUNTED)) {
//handle error here
}
else {
File sd = new File(Environment.getExternalStorageDirectory ()); //this needs to be a folder the user can access, like media
as usual the docs dont give an actual example of usage but it says this - If you're using API Level 8 or greater, use getExternalFilesDir() to open a File that represents the external storage directory where you should save your files. This method takes a type parameter that specifies the type of subdirectory you want, such as DIRECTORY_MUSIC...
how do i use it?
thank you
edit:
this makes it crash if i try to fill a spinner array with file path Strings.
File path = getExternalFilesDir(Environment.DIRECTORY_MUSIC);
File sd = new File(path, "/myFolder");
File[] sdDirList = sd.listFiles(new WavFilter());
if (sdDirList != null)
{
//sort the spinner
amountofiles = sdDirList.length;
array_spinner=new String[amountofiles];
......
final Spinner s = (Spinner) findViewById(R.id.spinner1); //crashes here
ArrayAdapter<?> adapter = new ArrayAdapter<Object>(this,
android.R.layout.select_dialog_item, array_spinner);
EDIT2:
ok so ive done this test that is supposed to write a txt file to the music directory.
i run the app, no txt file is written anywhere on the device i can find.
// Path to write files to
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath();
String fname = "mytest.txt";
// Current state of the external media
String extState = Environment.getExternalStorageState();
// External media can be written onto
if (extState.equals(Environment.MEDIA_MOUNTED))
{
try {
// Make sure the path exists
boolean exists = (new File(path)).exists();
if (!exists){ new File(path).mkdirs(); }
// Open output stream
FileOutputStream fOut = new FileOutputStream(path + fname);
fOut.write("Test".getBytes());
// Close output stream
fOut.flush();
fOut.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
another edit: i will get this working!!
so if i use this line it creates a folder on the sdcard called 'Musictest'. dont understand??
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC + "test").getAbsolutePath();
////////////////////////////////////////////////////////////////////
Final Edit:
right so this will look for a folder called test in the devices music directory.
if it doesnt exist, it will be created.
(some fixing to be done here, error if empty) it then lists the files in the directory and adds them to an array.
public void LoadSounds() throws IOException
{
String extState = Environment.getExternalStorageState();
// Path to write files to
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC + "/test").getAbsolutePath();
if(!extState.equals(Environment.MEDIA_MOUNTED)) {
//handle error here
}
else {
//do your file work here
// Make sure the path exists
boolean exists = (new File(path)).exists();
//if not create it
if (!exists){ new File(path).mkdirs(); }
File sd = new File(path);
//This will return an array with all the Files (directories and files)
//in the external storage folder
File[] sdDirList = sd.listFiles();
if (sdDirList != null)
{
//add the files to the spinner array
array_spinnerLoad=new String[sdDirList.length];
files = new String[sdDirList.length];
for(int i=0;i<sdDirList.length;i++){
array_spinnerLoad[i] = sdDirList[i].getName();
files[i] = sdDirList[i].getAbsolutePath();
}
}
}
}
as mentioned in the docs, getExternalFilesDir() return File. And File object can represent either file or directory.
Therefore:
File musicDirectory = new File( getExternalFilesDir(Environment.DIRECTORY_MUSIC));
Will give you the object to play with.