I am currently working on an app where i use a webview to display a webapp. I want to make it so that a user does not have to type his username everytime he starts the app . I want to automatically fill the textbox in the webview with text from c#. I have the following code untill now but I think my javascript is far from good (I don't have any specific knowledge about javascript).
private async void asyncjevoordeuser()
{
var inputValue = "test";
var functionString = string.Format(#"document.getElementById('username');", inputValue);
await WebView.InvokeScriptAsync("eval", new string[] { functionString });
}
I am calling this method from
private void WebView_LoadCompleted(object sender, NavigationEventArgs e)
{
asyncjevoordeuser();
}
I hope someone can help me out.
await WebViewObj.InvokeScriptAsync("eval", new string[] { "document.getElementById('username').value = 'username here';" });
Related
my company choose "Mercure" (https://mercure.rocks/docs/getting-started) to manage Server-Sent Events.
We install "Mercure HUB" on a server and now, in C# .NET 5.0, I must implement the server-side (publisher, that I already implemented) and the client-side (subscriber).
The subscriber must be done with a WPF
From the "getting-started" page I can see a Javascript example that I need to transform into C#
I don't know how to manage a "EventSource" in C#
Any ideas ?
// The subscriber subscribes to updates for the https://example.com/users/dunglas topic
// and to any topic matching https://example.com/books/{id}
const url = new URL('https://localhost/.well-known/mercure');
url.searchParams.append('topic', 'https://example.com/books/{id}');
url.searchParams.append('topic', 'https://example.com/users/dunglas');
// The URL class is a convenient way to generate URLs such as https://localhost/.well-known/mercure?topic=https://example.com/books/{id}&topic=https://example.com/users/dunglas
const eventSource = new EventSource(url);
// The callback will be called every time an update is published
eventSource.onmessage = e => console.log(e); // do something with the payload
The code of this page works (https://makolyte.com/event-driven-dotnet-how-to-consume-an-sse-endpoint-with-httpclient/)
static async Task Main(string[] args)
{
HttpClient client = new HttpClient();
client.Timeout = TimeSpan.FromSeconds(5);
string stockSymbol = "VTSAX";
string url = $"http://localhost:9000/stockpriceupdates/{stockSymbol}";
while (true)
{
try
{
Console.WriteLine("Establishing connection");
using (var streamReader = new StreamReader(await client.GetStreamAsync(url)))
{
while (!streamReader.EndOfStream)
{
var message = await streamReader.ReadLineAsync();
Console.WriteLine($"Received price update: {message}");
}
}
}
catch(Exception ex)
{
//Here you can check for
//specific types of errors before continuing
//Since this is a simple example, i'm always going to retry
Console.WriteLine($"Error: {ex.Message}");
Console.WriteLine("Retrying in 5 seconds");
await Task.Delay(TimeSpan.FromSeconds(5));
}
}
}
So I'm trying to make a webservice that allows someone to obtain data from a server. Right now, the server I'm using is written using java's HttpServer class. I plan to make the server accessible using fetch() in javascript, but it's not working.
When I was first testing out my server, I used Apache's HttpComponents library, and that client(written in java). was able to receive the test json that came from my server. However, when I used fetch() on my javascript client, nothing is received when I console.log everything. It doesn't make sense to me why it would work in Java, but not javascript. Does anyone know why this is not working? Am I just doing the javascript part wrong, and it does actually work? Thanks!
Code snippets for reference:
java server:
public class Main {
private static final int PORT = 1337;
private static final int BACKLOG = 1;
public static void main(String[] args) {
try {
HttpServer server = HttpServer.create(new InetSocketAddress(PORT), BACKLOG);
System.out.print("started on" + PORT);
HttpContext context = server.createContext("/ex", new Handler());
server.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Handler implements HttpHandler {
#Override
public void handle(HttpExchange he) throws IOException {
System.out.println("handled");
JSONObject obj = new JSONObject();
obj.put("name", "value");
obj.put("num", new Integer(100));
obj.put("balance", new Double(1000.21));
obj.put("is_vip", new Boolean(true));
obj.put("array", new int[]{1, 2, 3});
String response = obj.toJSONString();
he.sendResponseHeaders(200, response.length());
he.getResponseBody().write(response.getBytes());
}
}
java client:
public class PostTest {
public static void main(String[] args) throws IOException {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httppost = new HttpPost("http://localhost:1337/ex");
CloseableHttpResponse response = httpClient.execute(httppost);
System.out.println("STATUS LINE");
System.out.println(response.getStatusLine().toString());
System.out.println("HEADER");
Header[] h = response.getAllHeaders();
for(int i = 0; i < h.length; i++) {
System.out.println(h[i]);
}
System.out.println("ENTITY.CONTENT");
try(BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"))) {
String s;
while((s = br.readLine()) != null) {
System.out.println(s);
}
}
}
}
Javascript:
var init = {mode: "no-cors"};
async function f() {
return fetch("http://localhost:1337/ex", init).then(res => res.text()).then(posts => console.log(posts));
}
f();
I'm trying to modify the Screenshoot.java file from this plugin to take a screenshot of user home screen instead of appView screen when the app runs in background mode. When the app goes to background mode using this plugin, the app continues to take a screenshot of appView even in background and not the foreground screen or user home screen.
You can see part of original Screenshoot.java file below:
#Override
public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
// starting on ICS, some WebView methods
// can only be called on UI threads
if (action.equals("saveScreenshot")) {
final String format = (String) args.get(0);
final Integer quality = (Integer) args.get(1);
final String fileName = (String)args.get(2);
super.cordova.getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
View view = webView.getRootView();
try {
if(format.equals("png") || format.equals("jpg")){
view.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
File folder = new File(Environment.getExternalStorageDirectory(), "Pictures");
if (!folder.exists()) {
folder.mkdirs();
}
File f = new File(folder, fileName + "."+format);
FileOutputStream fos = new FileOutputStream(f);
if(format.equals("png")){
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
}
if(format.equals("jpg")){
bitmap.compress(Bitmap.CompressFormat.JPEG, quality == null?100:quality, fos);
}
JSONObject jsonRes = new JSONObject();
jsonRes.put("filePath",f.getAbsolutePath());
PluginResult result = new PluginResult(PluginResult.Status.OK, jsonRes);
callbackContext.sendPluginResult(result);
}else{
callbackContext.error("format "+format+" not found");
}
} catch (JSONException e) {
callbackContext.error(e.getMessage());
} catch (IOException e) {
callbackContext.error(e.getMessage());
}
}
});
return true;
}
callbackContext.error("action not found");
return false;
};
After some research, I have tried to change the code:
View view = webView.getRootView();
to code:
View view = getWindow().getDecorView().getRootView();
but it gives an error that method getWindow() can not found even after I insert:
import android.view.Window;
Then I changed the code to:
View view = cordova.getActivity().getWindow().getDecorView().getRootView();
The above code compiles but still captures the app screen even if it's running in background and not the user home screen.
Any help to figure out how to get the "view" of user home screen instead of app screen when the app is in background mode?
Regards.
I have Silverlight app. For example I want add some JS script which can interact with SL app. For example I want add google map use JS api. Can I do this, But I must send some data from SL to JS to add pins on map, draw figures on map ect.
If you are using Windows Phone and you dont mind that part of the xaml to be a webview yo can.
First add a webview to the xaml
<phone:WebBrowser Name="webView" BorderThickness="0" BorderBrush="Transparent" IsScriptEnabled="True"
ScriptNotify="WebBrowser_ScriptNotify" />
Then you have to bind the webview with the load event and then saveg files to storage and load your html and js files
webView.Loaded += WebBrowser_OnLoaded;
private void WebBrowser_OnLoaded(object sender, RoutedEventArgs e)
{
SaveFilesToIsoStore();
chatView.Navigate(new Uri("Assets/HtmlContent/index.html", UriKind.Relative));
}
private void SaveFilesToIsoStore()
{
//These files must match what is included in the application package,
//or BinaryStream.Dispose below will throw an exception.
string[] files = {
"Assets/HtmlContent/index.html",
"Assets/HtmlContent/js/libs/jquery-1.11.0.min.js", "Assets/HtmlContent/js/pagejs.js", "Assets/HtmlContent/css/style.css"
};
IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication();
if (false == isoStore.FileExists(files[0]))
{
foreach (string f in files)
{
StreamResourceInfo sr = Application.GetResourceStream(new Uri(f, UriKind.Relative));
using (BinaryReader br = new BinaryReader(sr.Stream))
{
byte[] data = br.ReadBytes((int)sr.Stream.Length);
SaveToIsoStore(f, data);
}
}
}
}
private void SaveToIsoStore(string fileName, byte[] data)
{
string strBaseDir = string.Empty;
string delimStr = "/";
char[] delimiter = delimStr.ToCharArray();
string[] dirsPath = fileName.Split(delimiter);
//Get the IsoStore.
IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication();
//Re-create the directory structure.
for (int i = 0; i < dirsPath.Length - 1; i++)
{
strBaseDir = System.IO.Path.Combine(strBaseDir, dirsPath[i]);
isoStore.CreateDirectory(strBaseDir);
}
//Remove the existing file.
if (isoStore.FileExists(fileName))
{
isoStore.DeleteFile(fileName);
}
//Write the file.
using (BinaryWriter bw = new BinaryWriter(isoStore.CreateFile(fileName)))
{
bw.Write(data);
bw.Close();
So on the js you have to talk to the c# like this
function sendMessageToCodeBehind(someData) {
window.external.notify(JSON.stringify({ method: 'AddMessage', data: someData }));
}
On the code behind you would recibe the messages from the webview like this:
private void WebBrowser_ScriptNotify(object sender, NotifyEventArgs e)
{
var example = new { method = string.Empty, data = new object() };
var obj = JsonConvert.DeserializeAnonymousType(e.Value, example);
switch (obj.method) {
case "methodName":
}
}
And you would send back messages to the js like this
webView.InvokeScript("jsMethodName", JsonConvert.SerializeObject(new { Message = "some json message" }));
I have one hi-bride application in which one html page has file picker and i want to load that page in Android webview.
This pickers works well in Device browser but not in webview.
For to support this i am using one hidden method of WebChromeClient which is as below
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType){
/**updated, out of the IF **/
mUploadMessage = uploadMsg;
/**updated, out of the IF **/
if(boolFileChooser){ //Take picture from filechooser
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
startActivityForResult( Intent.createChooser( i, "Pick File.." ), FILECHOOSER_RESULTCODE );
} else { //Take photo and upload picture
Intent cameraIntent = new Intent("android.media.action.IMAGE_CAPTURE");
photo = new File(Environment.getExternalStorageDirectory(), "Pic.jpg");
if(photo.exists())
photo.delete();
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
mCapturedImageURI = Uri.fromFile(photo);
startActivityForResult(cameraIntent, CAMERAREQUEST_RESULTCODE);
}
}
// Per Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg){
openFileChooser(uploadMsg, "");
}
//Aftre
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
openFileChooser(uploadMsg, "");
}
It was working fine till 4.3 but from 4.4 this method is not getting called.
And they said https://code.google.com/p/android/issues/detail?id=62220 this has been removed.
Do anyone knows any alternate way. Please let me know your help will greatly appreciated
There are no ways to openFileChooser method after 4.3 as google has removed that and they will come up with other way to handle this file chooser stuff in next version (Confirmed by Google engineer).
I moved to hybrid architecture to and write native function for file picker.
In Android 5.0, they introduced onShowFileChooser(), with which you can use an input form field in the webview and launch a file chooser to select images and files from the device.
Bitmap bitmap;
private static final int READ_REQUEST_CODE = 42;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
// Filter to only show results that can be "opened", such as a
// file (as opposed to a list of contacts or timezones)
intent.addCategory(Intent.CATEGORY_OPENABLE);
// Filter to show only images, using the image MIME data type.
// If one wanted to search for ogg vorbis files, the type would be "audio/ogg".
// To search for all documents available via installed storage providers,
// it would be "*/*".
intent.setType("image/*");
startActivityForResult(intent, READ_REQUEST_CODE);
}
#Override
public void onActivityResult(int requestCode, int resultCode,
Intent resultData) {
// The ACTION_OPEN_DOCUMENT intent was sent with the request code
// READ_REQUEST_CODE. If the request code seen here doesn't match, it's the
// response to some other intent, and the code below shouldn't run at all.
if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
// The document selected by the user won't be returned in the intent.
// Instead, a URI to that document will be contained in the return intent
// provided to this method as a parameter.
// Pull that URI using resultData.getData().
Uri uri = null;
if (resultData != null) {
uri = resultData.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(),uri);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ImageView my_img_view = (ImageView ) findViewById (R.id.uploadlayout2);
my_img_view.setImageBitmap(bitmap);
}
}
}