I am trying to use peerjs in android vie webview, but the problem is it not working, when I debugged and tried different approaches I got to know that normal js functions work with no problem, the problem only when I call a function which includes peerjs
permissions i took in manifest file
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
MAINACTIVITY
here are two buttons 1 calls to simple js function named callJs and other one calls peerjs function named testweb
public class MainActivity extends AppCompatActivity {
#SuppressLint("JavascriptInterface")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView webView = findViewById(R.id.webview);
webView.getSettings().setJavaScriptEnabled(true);
// Setting Allowed JS Bullet Window
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webView.setWebChromeClient(new WebChromeClient(){
#Override
public void onPermissionRequest(PermissionRequest request) {
request.grant(request.getResources());
}
});
webView.addJavascriptInterface(new JavaScriptInterface(this),"AndroidFunction");
webView.loadUrl("file:///android_asset/webViewTest.html");
Button webTest1 = findViewById(R.id.webTest1);
//calls normal js function
webTest1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
webView.post(new Runnable() {
#Override
public void run() {
webView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
#Override
public void onReceiveValue(String value) {
}
});
}
});
}
});
Button webTest2 = findViewById(R.id.webTest2);
//calls js function with peerjs
webTest2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
webView.post(new Runnable() {
#Override
public void run() {
webView.evaluateJavascript("javascript:testWeb()", new ValueCallback<String>() {
#Override
public void onReceiveValue(String value) {
}
});
}
});
}
});
}
JAVASCRIPTINTERFACE
public class JavaScriptInterface {
MainActivity mainActivity;
public JavaScriptInterface(MainActivity mainActivity) {
this.mainActivity = mainActivity;
}
#JavascriptInterface
public void showToast(String toast){
Toast.makeText(mainActivity, toast, Toast.LENGTH_LONG).show();
}
js functions
<script src="./peerjs.js"></script>
<script type="text/javascript">
function callJS() {
AndroidFunction.showToast("Toast From javascript");
alert("Android Called JS Of callJS Method");
}
function testWeb() {
alert("testWeb Method called");
var peer = new Peer(1234, {
host: "192.168.****",
port: 8000,
path: "/strange",
});
peer.on("open", () => {
AndroidFunction.showToast("Toast From testWebPeer");
});
}
</script>
Related
I'm developing an Android app. In past projects, I used to use WebView to show web content. This gave me the capability to intercept events like page loaded and so on. The important thing that I was able to do was to get page content and use it in the Java code. To be honest, I use a trick, but it works. I put the essential code of my fragment to use a WebView to open an URL, do something and when the user arrives in a specific page and get the page content (with MyJavaScriptInterface):
public class LoginFragment extends MyAppFragment {
#BindView(R.id.webView)
public WebView webView;
public LoginFragment() {
}
#Override
public void onResume() {
super.onResume();
webView.setVisibility(View.VISIBLE);
}
#SuppressLint("SetJavaScriptEnabled")
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_login, container, false);
initBinder(rootView);
...
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setDisplayZoomControls(false);
webView.setWebViewClient(mWebViewClient);
/* Register a new JavaScript interface called HTMLOUT */
webView.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");
webView.loadUrl(getResources().getString(R.string.url_login).trim());
return rootView;
}
/* An instance of this class will be registered as a JavaScript interface */
class MyJavaScriptInterface {
#JavascriptInterface
#SuppressWarnings("unused")
public void processHTML(String token) {
if (token.contains(URL_LANDING)) {
...
}
}
}
private WebViewClient mWebViewClient = new WebViewClient() {
#Nullable
#Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
Logger.info("shouldInterceptRequest " + request.getUrl().toString());
if (URL_LANDING_SESAPP.equals(request.getUrl().toString())) {
...
}
return super.shouldInterceptRequest(view, request);
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
...
return super.shouldOverrideUrlLoading(view, request);
}
#Override
public void onLoadResource(WebView view, String url) {
...
super.onLoadResource(view, url);
}
#Override
public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
super.onReceivedHttpError(view, request, errorResponse);
}
#Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
...
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
...
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
pageLoading = false;
if (loginDone) {
view.loadUrl("javascript:window.HTMLOUT.processHTML(document.getElementsByTagName('body')[0].innerHTML);")
}
}
};
}
Is there an equivalent way to do this with Chrome Custom Tags? Thank you in advance.
This is code I got online for sending mail in android studio using the Gmail API, but I need to fixed sender and mail I need to send at the same time as like sender hazem#gmail.com and receiver will be hazem11#gmail.com without showing which account I need to send mail and which mail I should have added to send.
public class MainActivity extends AppCompatActivity {
FloatingActionButton sendFabButton;
EditText edtToAddress, edtSubject, edtMessage, edtAttachmentData;
Toolbar toolbar;
GoogleAccountCredential mCredential;
ProgressDialog mProgress;
private static final String PREF_ACCOUNT_NAME = "accountName";
private static final String[] SCOPES = {
GmailScopes.GMAIL_LABELS,
GmailScopes.GMAIL_COMPOSE,
GmailScopes.GMAIL_INSERT,
GmailScopes.GMAIL_MODIFY,
GmailScopes.GMAIL_READONLY,
GmailScopes.MAIL_GOOGLE_COM
};
private InternetDetector internetDetector;
private final int SELECT_PHOTO = 1;
public String fileName = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
findViewById(R.id.attachment).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Utils.checkPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);
} else {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, SELECT_PHOTO);
}
}
});
findViewById(R.id.changeAccount).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Utils.checkPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
startActivityForResult(mCredential.newChooseAccountIntent(), Utils.REQUEST_ACCOUNT_PICKER);
} else {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, SELECT_PHOTO);
}
}
});
sendFabButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getResultsFromApi(view);
}
});
}
I'm using android studio
I need to replace the body of an html document with other codes, this is an example that I tried to follow
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.grafico);
wv = (WebView) findViewById(R.id.prova);
wv.setWebViewClient(new MyWebViewClient());
new BackgroundWorker().execute();
}
// load links in WebView instead of default browser
private class MyWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return false;
}
#RequiresApi(21)
#Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
view.loadUrl(request.getUrl().toString());
return false;
}
}
private class BackgroundWorker extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... arg0) {
getDarewod();
return null;
}
public void getDarewod() {
try {
Document htmlDocument = Jsoup.connect(url).get();
Element element = htmlDocument.select("#gkHeaderMod > div.grafico-quotazione").first();
// replace body with selected element
htmlDocument.body().empty().append(element.toString());
final String html = htmlDocument.toString();
uiHandler.post(new Runnable() {
#Override
public void run() {
wv.loadData(html, "text/html", "UTF-8");
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
I want to replace the all body with the code in my element variable. However this line doesn't works. How can I do?
htmlDocument.body().empty().append(element.toString());
I was facing problem for calling android Admob interstitial from webview. I could not get any proper solution. Finally I figured out the solution to call the interstitial for javascript. Look into the below answer.
Solution for the above problem
Import all the required packages.
public class MainActivity extends AppCompatActivity {
WebView myWevView;
public InterstitialAd mInterstitialAd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_main);
myWevView =(WebView)findViewById(R.id.myWevView);
WebSettings ws= myWevView.getSettings();
ws.setJavaScriptEnabled(true);
ws.setDomStorageEnabled(true);
myWevView.getSettings().setUseWideViewPort(true);
myWevView.addJavascriptInterface(new WebAppInterface(this), "Android");
myWevView.setWebViewClient(new WebViewClient());
myWevView.setWebChromeClient(new WebChromeClient());
myWevView.getSettings().setBuiltInZoomControls(true);
myWevView.loadUrl("file:///android_asset/index.html");
mInterstitialAd = new InterstitialAd(this);
mInterstitialAd.setAdUnitId("ca-app-pub-3940256099942544/1033173712");
mInterstitialAd.loadAd(new AdRequest.Builder().build());
mInterstitialAd.setAdListener(new AdListener(){
#Override
public void onAdLoaded(){
}
#Override
public void onAdClosed() {
// Load the next interstitial.
mInterstitialAd.loadAd(new AdRequest.Builder().build());
}
});
}
public void displayLoadedAd(){
runOnUiThread(new Runnable() {
public void run() {
if (mInterstitialAd.isLoaded()) {
mInterstitialAd.show();
mInterstitialAd.loadAd(new AdRequest.Builder().build());
}
else
Toast.makeText(getApplicationContext(), "Ad not loded", Toast.LENGTH_SHORT).show();
}
});
}
public class WebAppInterface {
Context mContext;
/** Instantiate the interface and set the context */
WebAppInterface(Context c) {
mContext = c;
}
#JavascriptInterface
public void showAdFromJs(){
Toast.makeText(mContext, "Loading Ad", Toast.LENGTH_SHORT).show();
displayLoadedAd();
}
}
//Controlling navigation
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
if (myWevView.canGoBack()) {
myWevView.goBack();
}
else {
finish();
}
return true;
}
}
return super.onKeyDown(keyCode, event);
}
}
calling from javascript
$("#btn1").click(function(){
Android.showAdFromJs();
});
I used this without the javascript call like this:
#Override
public void onAdLoaded(){
displayLoadedAd();
}
You would need to lower the number of interstitial ads to your pref. in your admob console.
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
web = (WebView) findViewById(R.id.webview1);
web.setWebChromeClient(new MyWebChromeClient());
web.addJavascriptInterface(new DemoJavaScriptInterface(), "temp_1");
web.loadUrl("file:///android_asset/temp_1.html");
}
}
final class DemoJavaScriptInterface {
private Handler mHandler = new Handler();
WebView web;
DemoJavaScriptInterface() {
}
public void clickOnAndroid() {
mHandler.post(new Runnable() {
public void run() {
web.loadUrl("javascript:init();");
}
});
}
}
final class MyWebChromeClient extends WebChromeClient {
private static final String LOG_TAG = "WebViewDemo";
#Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
Log.e(LOG_TAG, message);
result.confirm();
return true;
}
}
Try to write this line
web = (WebView) findViewById(R.id.webview1);
web.setWebChromeClient(new MyWebChromeClient());
web.getSettings().setJavaScriptEnabled(true);
web.addJavascriptInterface(new DemoJavaScriptInterface(), "temp_1");
web.loadUrl("file:///android_asset/temp_1.html");
[2]: Both Elements are coming from html file ,when going to click on "Click It" nothing happens instead of displaying xml data that i want