I am trying to print an HTML-page from a webview on KitKat (4.4.4) basically using the sample code provided in Google's API documentation. Accordingly, I set a print job name as follows:
String jobName = getString(R.string.app_name) + " Document";
PrintJob printJob = printManager.print(jobName, printAdapter,
new PrintAttributes.Builder().build());
My code runs fine and the page is printed as intended. Even if the user chooses the option "save as PDF" in the Android standard printing dialog, the codes renders a nice PDF and the user can choose a file name. At this point I would expect Android to use the string stored in the jobName field as file name. Instead it always uses webview as file name, although my code does not contain webview as string.
Is there a way to set another default name for storing a PDF file that is generated in my application?
Thanks for your hints...
Update:
I spent some additional time investigating this issue and I found that the WebView uses AwPrintDocumentAdapter as print adapter if the adapter is created by calling createPrintDocumentAdapter() as proposed in the API documentation. That class then calls
PrintDocumentInfo.Builder("webview") which seems to be the reason why the PDF always is named "webview". Some research reveals the following code snippet in AwPrintDocumentAdapter:
#Override
public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
CancellationSignal cancellationSignal, LayoutResultCallback callback,
Bundle metadata) {
mAttributes = newAttributes;
// TODO(sgurun) pass a meaningful string once b/10705082 is resolved
PrintDocumentInfo documentInfo = new PrintDocumentInfo
.Builder("webview")
.build();
// TODO(sgurun) once componentization is done, do layout changes and
// generate PDF here, set the page range information to documentinfo
// and call onLayoutFinished with true/false depending on whether
// layout actually changed.
callback.onLayoutFinished(documentInfo, true);
}
Hence, this seems to be the root cause for my problem - at least if that code made its way to my Nexus 4 test device... Finally, the best way to deal with this naming issue seems to be a custom print adapter implementation.
Are there any other solutions that do not require a custom print adapter (which should contain code for calculating the number of pages etc...)?
Related
I'm creating an Intent for Android, to send e-mails.
And I'm getting confused about the behavior of Uri.fromParts.
Mi code:
This works fine!
uri=Uri.parse(
"mailto:" + toAddress +
(subject != null ?
("?" + "subject=" + Uri.encode(subject)) :
"")
The previous work fine, and create an Uri in the form mailto:john#doe.com?subject=Test
But if I try to use Uri.from parts, with this sample:
uriBuilder=Uri.fromParts("mailto",toAddress,null).buildUpon();
if (subject!=null) {
uriBuilder.appendQueryParameter("subject",subject);
}
uri=uriBuilder.build();
I get an error. The final uri is mailto:?subject=Test
The intermediate is correct, but when I use appendQueryParameter, it removes the content after the mailto scheme.
Do you know why? Which is the canonical way to do this?
Uri#fromParts()
Creates an opaque Uri from the given components. Encodes the ssp which means this method cannot be used to create hierarchical URIs.
When you call buildUpon() on this, the Builder contains the scheme, scheme-specific part (ssp) and the fragment (null in your case).
appendQueryParameter() then turns the Builder to a hierarchical one, deleting the opaque ssp data.
I don't think there's a "canonical" way. Just don't mix hierarchical and opaque builders.
For details on what happens under the hood, read the source.
I'm using Xamarin.android and I followed this
I Want to save a print to a specific path without showing dialogue screen to user.
How can I say the path I want to save without asking user ?
I have that code:
myWebView = new Android.Webkit.WebView(this.Context);
var printManager = (Android.Print.PrintManager)Forms.Context.GetSystemService(Android.Content.Context.PrintService);
var text = new ContractHTML() { Model = new Model.Model() { img = null } };
myWebView.LoadDataWithBaseURL("file:///android_asset/", text.GenerateString(), "text/html", "UTF-8", null);
string fileName = "MyPrint_" + Guid.NewGuid().ToString() + ".pdf";
var printAdapter = myWebView.CreatePrintDocumentAdapter(fileName);
Android.Print.PrintJob printJob = printManager.Print("MyPrintJob", printAdapter, null);
This code is working and generate a pdf, but it's asking user where to save it, I want to save it in some path.
Is it possible ?
Save pdf without showing the user the print dialogue screen
AFAIK you can not implement this feature in Android.
The user needs to be able to choose some configuration, such as choosing what printer to print on. So when you use printManager.Print() method a print dialog will show up. You could find that In android PrintManager Source code, PrintManager class is final(In C# it's sealed), we are not allowed to override this method to prevent the dialog.
When you execute printManager.Print("MyPrintJob", printAdapter, null) method from an Activity, it starts PrintJob also it will bringing up the system print UI. This is did by Android printing framework, we cannot silently print by using the platform API.
There is an open issue on AOSP issue tracker : https://code.google.com/p/android/issues/detail?id=160908.
After searching far and wide, I used this GitHub project to solve this problem. I was able to silently print the document without the user's knowledge.
It seems like the developer was able to add some classes to the android.print package to access private members, making this possible.
https://github.com/UttamPanchasara/PDF-Generator?utm_source=android-arsenal.com&utm_medium=referral&utm_campaign=7355
Alright, here goes. I'm dealing with an ionic project. In this specific scenario we're dealing with testing the Android version of the app. I can get images from the file system just fine, they come back in the form of a string url that looks something like this,
content://com.android.providers.media.documents/document/image%3A5744
The processor that is then supposed to blob the file and pass it up the line looks like this:
return this.file.readAsArrayBuffer(urlData.url, urlData.fileName)
.then((item) => {
return new Blob([new Uint8Array(item)]);
})
.catch((err) => {
console.log(err.message)
}).then((res)=>{
return new Blob([res])
})
But then I get the error SECURITY_ERR, which the documentation doesn't really talk about.
This works just fine for the pictures I take with the camera, which all have urls that look like this
file:///storage/emulated/0/Android/data/<appname>/cache/1502211622334.jpg
The issue is, as far as i can find, there is no documentation on what causes this error. I have no idea what to change to make my code work. I have verified the URI is valid, using the checkFile method.
So it turns out you can't use content urls with file.readAsArrayBuffer instead you have to first resolve the url into something readAsArrayBuffer can understand. To do this, i used the ionic native filePath plugin.
Once it was installed and included in the page where I needed it, I used the
filePath.resolveNativePath(url)
method on my url, since this returns a promise, I chained my readAsArrayBuffer onto a then statement prepended to it. I did have to use an if statement to have branching paths for content urls (Which required resolveNativePath) and non-content urls which were already working.
This solution works as far as I can tell.
In my project i need to include searchs to a API Rest to query with a url that points to a jpg picture and it returns a list of urls with similar pictures.
Google Images performs via web like i am looking for, but the clients for Android that i have found (github projects) they work simply with an input text.
The simplest code would be something as below:
String inputUrlPic = "https://cdn.pixabay.com/photo/2014/03/14/20/13/dog-287420__340.jpg";
String[] returnedUrlPictures = null; //list of returned pictures similars to inputUrlPic
ReverseImageApi reverseImageApi = new ReverseImageApi();//My desired Api object
returnedUrlPictures = reverseImageApi.findSimilarPicturesFromUrl(inputUrlPic); //Ok, it would be an asynctask
So, my question is, exists a API or an Android client API to perform in this way?
I want to know how to upload multiple photos at a time thru google plus?
I found how to upload one photo and one message at a time from google plus sample code.
String action = "/?view=true";
Uri callToActionUrl = Uri.parse(getString(R.string.plus_example_deep_link_url) + action);
String callToActionDeepLinkId = getString(R.string.plus_example_deep_link_id) + action;
// Create an interactive post builder.
builder = new PlusShare.Builder(this, plusClient);
// Set call-to-action metadata.
builder.addCallToAction(LABEL_VIEW_ITEM, callToActionUrl, callToActionDeepLinkId);
// Set the target url (for desktop use).
builder.setContentUrl(Uri.parse(getString(R.string.plus_example_deep_link_url)));
// Set the target deep-link ID (for mobile use).
builder.setContentDeepLinkId(getString(R.string.plus_example_deep_link_id),
null, null, null);
// Set the message.
builder.setText("user message");
// Set the image
Uri uri = Uri.fromFile(new File("[user file path]"));
builder.setStream(uri);
Anyone knows about uploading multiple photos like facebook and twitter?
It should work with addStream() method, unfortunately... it doesn't work. Indeed it makes the application crash.
After a long search, I finally got it: it's not possible if using the simplified G+ SDK! (the one dedicated to Android).
There is a second one, included in the Google API family that you can find there:
http://code.google.com/p/google-api-java-client/wiki/APIs#Google+_API
This one will let you build more advanced post, included, several pic one.
Unfortunately the second SDK is much more low level, not dedicated to Android, it's a kind of Java abstraction over http request.
Regards