Passing array from js to android - javascript

Hi I have this activity code:
public class WebActivity extends ActionBarActivity {
TextView number;
WebView mWebView;
CountDownTimer mTimer;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web);
number = (TextView) findViewById(R.id.number);
mTimer=new CountDownTimer(10000, 1000) {
String[] myArray={"javascript:document.getElementById(\"utente\").value=\""+LoginActivity.username+"\"; document.getElementById(\"j_password\").value=\""+LoginActivity.password+"\"; document.querySelector(\"input[type=submit]\").click();","javascript:document.getElementById(\"menu-servizialunno:_idJsp14\").click();"};
int currentIndex=0;
public void onTick(long millisUntilFinished) {
number.setText("seconds remaining: " + millisUntilFinished / 1000 + " " + (currentIndex + 1) + "/" + (myArray.length + 1));
}
//code comment start
// i think this part could be written better
// but it works!!
public void onFinish() {
if (currentIndex<myArray.length) {
number.setText("done!");
mWebView.loadUrl(myArray[currentIndex]);
currentIndex++;
mTimer.start();
} else{
mTimer.cancel();
}
}
//code comment end
};
mTimer.start();
mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebViewClient(new WebSliderWebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(mWebView, url);
Toast.makeText(getApplicationContext(), "Done!", Toast.LENGTH_SHORT).show();
}
#Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Toast.makeText(getApplicationContext(), "Oh no! " + description, Toast.LENGTH_SHORT).show();
}
});
mWebView.loadUrl("http://www.ss16374.scuolanext.info");
}
and this js function:
function voti( showSubject, showData, showVote ){
var votitotali = []
document.getElementById("menu-servizialunno:_idJsp14").click();
setTimeout(function(){
elems = document.querySelectorAll("td, legend");
for(var i = 0; i < elems.length; i++){
curText = elems[i].innerHTML;
if( elems[i].tagName == "LEGEND" && showSubject ){
votitotali += [curText]
//console.log( curText );
}else if( elems[i].innerHTML.indexOf("Voto") != -1 && showVote ){
votitotali += [curText.replace(/.*\(([0-9\.]+)\)/,"$1")]
//console.log( curText.replace(/.*\(([0-9\.]+)\)/,"$1") );
}else if( /\d{2}\/\d{2}\/\d{4}/.test(elems[i].innerHTML) && showData ){
votitotali += [curText.replace(/.*(\d{2}\/\d{2}\/\d{4}).*/,"$1")]
//console.log( curText.replace(/.*(\d{2}\/\d{2}\/\d{4}).*/,"$1") );
}
}
document.getElementsByClassName("btl-modal-closeButton")[0].click()
},3000);
return votitotali
}
Can I store the votitotali array in my android app? Because I need to get some informations from a site and I have to print them on a textView in the app, but I really do not know how to do this using webview...

That's actually easy. You need to inject a Java object which has a method receiving an array:
class MyReceiver {
#JavascriptInterface
public void receive(String[] input) {
// input is your data!
}
}
// At the very beginning
mWebView.addJavascriptInterface(new MyReceiver(), "receiver");
// ...
Then if you call it like that in your JavaScript code:
receiver.receive(voti( ... ));
You will get the array inside MyReceiver.receive.
Note that non-string array elements (e.g. numbers) will not be converted into strings, and will be replaced by nulls instead.

Related

AVG(COLUMN_SCORE) Not Getting Written To SQLite Database

I have created the following method to generate the average score for a series:
//Getting Series Averages From Game.COLUMN_SCORE
public String getSeriesAverage(String leagueId, String bowlerId)
{
String total = "";
Series series = new Series();
ContentValues values = new ContentValues();
SQLiteDatabase database = getWritableDatabase();
Cursor cursor = database.rawQuery("SELECT AVG(" + Game.COLUMN_SCORE + ") FROM " + Game.TABLE_NAME + " WHERE " + Game.COLUMN_LEAGUE_ID + " = '" + leagueId + "'" + " AND " + Game.COLUMN_BOWLER_ID + " = '" + bowlerId + "'" + " GROUP BY " + Game.COLUMN_SERIES_ID /*+ " = '" + seriesId + "'"*/, null);
if (cursor.moveToFirst()) {
do {
total = cursor.getString(0);
values.put(Series.COLUMN_SERIES_AVERAGE, total);
database.update(Series.TABLE_NAME, values, Series.COLUMN_ID + "=" + series.getId(), null);
Log.d("SERIES_AVERAGE - SQL","COLUMN_SERIES_AVERAGE = >>>>" + Series.COLUMN_SERIES_AVERAGE + "<<<<");
Log.d("TOTAL - CURSOR VALUE","Total = >>>>" + total + "<<<<");
} while (cursor.moveToNext());
values.put(Series.COLUMN_SERIES_AVERAGE, total);
database.update(Series.TABLE_NAME, values, Series.COLUMN_ID + "=" + series.getId(), null);
}
cursor.close();
//Close Database Connection
database.close();
//Log.d("GET AVERAGE FROM SQL","Average = >>>>" + total + "<<<<");
return total;
}
It seems to work and I can see the averages for each of the Series listed for an individual Bowler in Logcat:
07-26 14:50:15.158 25330-25330/ca.rvogl.tpbcui D/GETALLSERIES-SQL: SQL used = >>>>SELECT * FROM Series WHERE league_id = '1' AND bowler_id = '1' ORDER BY timestamp DESC<<<<
07-26 14:50:15.167 25330-25330/ca.rvogl.tpbcui D/GETALLSERIESS-CNT: Number of rows retrieved = 3
07-26 14:50:15.175 25330-25330/ca.rvogl.tpbcui D/SERIES_AVERAGE - SQL: COLUMN_SERIES_AVERAGE = >>>>average<<<<
07-26 14:50:15.175 25330-25330/ca.rvogl.tpbcui D/AVERAGE OF FIRST SERIES: Average = >>>>207<<<<
07-26 14:50:15.175 25330-25330/ca.rvogl.tpbcui D/SERIES_AVERAGE - SQL: COLUMN_SERIES_AVERAGE = >>>>average<<<<
07-26 14:50:15.175 25330-25330/ca.rvogl.tpbcui D/AVERAGE OF FIRST SERIES: Average = >>>>111<<<<
07-26 14:50:15.175 25330-25330/ca.rvogl.tpbcui D/SERIES_AVERAGE - SQL: COLUMN_SERIES_AVERAGE = >>>>average<<<<
07-26 14:50:15.175 25330-25330/ca.rvogl.tpbcui D/AVERAGE OF FIRST SERIES: Average = >>>>300<<<<
07-26 14:50:15.175 25330-25330/ca.rvogl.tpbcui D/SERIES_AVERAGE - SQL: COLUMN_SERIES_AVERAGE = >>>>average<<<<
07-26 14:50:15.175 25330-25330/ca.rvogl.tpbcui D/AVERAGE OF FIRST SERIES: Average = >>>>1<<<<
07-26 14:50:15.175 25330-25330/ca.rvogl.tpbcui D/AVERAGE OF SERIES: Average = >>>>1<<<<
07-26 14:50:15.177 25330-25330/ca.rvogl.tpbcui D/GETALLSERIES-CNT: Number of elements in serieslist = 3
However as you can also see from the logcat the value is not being written to the database as shown here:
07-26 14:50:15.175 25330-25330/ca.rvogl.tpbcui D/AVERAGE OF FIRST SERIES: Average = >>>>300<<<<
07-26 14:50:15.175 25330-25330/ca.rvogl.tpbcui D/SERIES_AVERAGE - SQL: COLUMN_SERIES_AVERAGE = >>>>average<<<<
It is actually only displaying the name of the variable from Series Class.
Can anyone help me get these values written to the database. I am not sure what I am doing incorrectly and any assistance would be appreciated. If you need to see any additional code please let me know I will post it.
Structure of Series Table:
// Create table SQL query
public static final String CREATE_TABLE =
"CREATE TABLE " + TABLE_NAME + "("
+ COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_LEAGUE_ID + " TEXT,"
+ COLUMN_BOWLER_ID + " TEXT,"
+ COLUMN_NAME + " TEXT,"
+ COLUMN_SERIES_AVERAGE + " TEXT,"
+ COLUMN_TIMESTAMP + " DATETIME DEFAULT CURRENT_TIMESTAMP"
+ ")";
public Series() {
}
public Series(int id, String league_id, String bowler_id, String name, String average, String timestamp) {
this.id = id;
this.league_id = league_id;
this.bowler_id = bowler_id;
this.name = name;
this.average = average;
this.timestamp = timestamp;
}
Logcat:
07-26 19:00:42.250 32441-32441/ca.rvogl.tpbcui D/GETALLSERIES-SQL: SQL used = >>>>SELECT * FROM Series WHERE league_id = '1' AND bowler_id = '1' ORDER BY timestamp DESC<<<<
07-26 19:00:42.263 32441-32441/ca.rvogl.tpbcui D/GETALLSERIESS-CNT: Number of rows retrieved = 2
07-26 19:00:42.279 32441-32441/ca.rvogl.tpbcui D/SERIES_AVERAGE - SQL: COLUMN_SERIES_AVERAGE = >>>>null<<<<
07-26 19:00:42.279 32441-32441/ca.rvogl.tpbcui D/TOTAL - CURSOR VALUE: Total = >>>>111<<<<
07-26 19:00:42.281 32441-32441/ca.rvogl.tpbcui D/SERIES_AVERAGE - SQL: COLUMN_SERIES_AVERAGE = >>>>null<<<<
07-26 19:00:42.281 32441-32441/ca.rvogl.tpbcui D/TOTAL - CURSOR VALUE: Total = >>>>300<<<<
07-26 19:00:42.286 32441-32441/ca.rvogl.tpbcui D/GETALLSERIES-CNT: Number of elements in serieslist = 2
SeriesActivity
public class SeriesActivity extends AppCompatActivity {
private SeriesAdapter mAdapter;
private final List<Series> seriesList = new ArrayList<>();
private TextView noSeriesView;
private DatabaseHelper db;
private TextView leagueId;
private String savedLeagueId;
private TextView bowlerId;
private String savedBowlerId;
private TextView seriesAverage;
private String savedSeriesAverage;
private static final String PREFS_NAME = "prefs";
private static final String PREF_BLUE_THEME = "blue_theme";
private static final String PREF_GREEN_THEME = "green_theme";
private static final String PREF_ORANGE_THEME = "purple_theme";
private static final String PREF_RED_THEME = "red_theme";
private static final String PREF_YELLOW_THEME = "yellow_theme";
#Override
protected void onCreate(Bundle savedInstanceState) {
//Use Chosen Theme
SharedPreferences preferences = getSharedPreferences( PREFS_NAME, MODE_PRIVATE );
boolean useBlueTheme = preferences.getBoolean( PREF_BLUE_THEME, false );
if (useBlueTheme) {
setTheme( R.style.AppTheme_Blue_NoActionBar );
}
boolean useGreenTheme = preferences.getBoolean( PREF_GREEN_THEME, false );
if (useGreenTheme) {
setTheme( R.style.AppTheme_Green_NoActionBar );
}
boolean useOrangeTheme = preferences.getBoolean( PREF_ORANGE_THEME, false );
if (useOrangeTheme) {
setTheme( R.style.AppTheme_Orange_NoActionBar );
}
boolean useRedTheme = preferences.getBoolean( PREF_RED_THEME, false );
if (useRedTheme) {
setTheme( R.style.AppTheme_Red_NoActionBar );
}
boolean useYellowTheme = preferences.getBoolean( PREF_YELLOW_THEME, false );
if (useYellowTheme) {
setTheme(R.style.AppTheme_Yellow_NoActionBar);
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_series);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar( toolbar );
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String seriesLeagueId = String.valueOf( getIntent().getStringExtra( "seriesLeagueId" ) );
String seriesBowlerId = String.valueOf( getIntent().getIntExtra( "seriesBowlerId", 2 ) );
Intent intent=new Intent();
intent.putExtra("seriesLeagueId",seriesLeagueId);
intent.putExtra("seriesBowlerId",seriesBowlerId);
setResult(1,intent);
finish();//finishing activity
overridePendingTransition(0, 0);
}
/*#Override
public void onClick(View v) {
startActivity(new Intent(SeriesActivity.this, BowlerActivity.class));
finish();
}*/
});
savedLeagueId = String.valueOf( getIntent().getStringExtra( "seriesLeagueId" ) );
leagueId = (TextView) findViewById( R.id.tvLeagueId );
savedBowlerId = String.valueOf( getIntent().getIntExtra( "seriesBowlerId", 2 ) );
bowlerId = (TextView) findViewById( R.id.tvBowlerId );
seriesAverage = (TextView) findViewById(R.id.tvSeriesAverage);
CoordinatorLayout coordinatorLayout = findViewById( R.id.coordinator_layout );
RecyclerView recyclerView = findViewById( R.id.recycler_view );
noSeriesView = findViewById( R.id.empty_series_view );
db = new DatabaseHelper( this );
seriesList.addAll( db.getAllSeries( savedLeagueId, savedBowlerId) );
FloatingActionButton fab = (FloatingActionButton) findViewById( R.id.add_series_fab );
fab.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View view) {
showSeriesDialog( false, null, -1 );
}
} );
mAdapter = new SeriesAdapter( this, seriesList );
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager( getApplicationContext() );
recyclerView.setLayoutManager( mLayoutManager );
recyclerView.setItemAnimator( new DefaultItemAnimator() );
recyclerView.addItemDecoration( new MyDividerItemDecoration( this, LinearLayoutManager.VERTICAL, 16 ) );
recyclerView.setAdapter( mAdapter );
toggleEmptySeries();
//On Long Click On The RecyclerView Item An Alert Dialog Is Opened With The Option To Choose Edit/Delete
recyclerView.addOnItemTouchListener( new RecyclerTouchListener( this, recyclerView, new RecyclerTouchListener.ClickListener() {
#Override
public void onClick(View view, final int position) {
int seriesId = seriesList.get( position ).getId();
String seriesLeagueId = seriesList.get( position ).getLeagueId();
String seriesBowlerId = seriesList.get( position ).getBowlerId();
Intent myIntent = new Intent( SeriesActivity.this, GameActivity.class );
myIntent.putExtra( "gameLeagueId", seriesLeagueId );
myIntent.putExtra( "gameBowlerId", seriesBowlerId );
myIntent.putExtra( "gameSeriesId", seriesId );
startActivityForResult(myIntent, 1);
overridePendingTransition(0, 0);
}
#Override
public void onLongClick(View view, int position) {
showActionsDialog( position );
}
} ) );
}
//Inserting New Series In The Database And Refreshing The List
private void createSeries(String leagueId, String bowlerId, String series) {
//Inserting Series In The Database And Getting Newly Inserted Series Id
long id = db.insertSeries( leagueId, bowlerId, series );
//Get The Newly Inserted Series From The Database
Series n = db.getSeries( leagueId, bowlerId );
if (n != null) {
//Adding New Series To The Array List At Position 0
seriesList.add( 0, n );
//Refreshing The List
mAdapter.notifyDatasetChanged( db.getAllSeries( savedLeagueId, savedBowlerId ) );
toggleEmptySeries();
}
}
//Updating Series In The Database And Updating The Item In The List By Its Position
private void updateSeries(String name, int position) {
Series n = seriesList.get( position );
//Updating Series Text
n.setLeagueId( savedLeagueId );
n.setBowlerId( savedBowlerId );
n.setName( name );
//Updating The Series In The Database
db.updateSeries( n );
//Refreshing The List
seriesList.set( position, n );
//mAdapter.notifyItemChanged(position);
mAdapter.notifyDatasetChanged( db.getAllSeries( savedLeagueId, savedBowlerId ) );
toggleEmptySeries();
}
//Deleting Series From SQLite Database And Removing The Bowler Item From The List By Its Position
private void deleteSeries(int position) {
//Deleting The Series From The Database
db.deleteSeries( seriesList.get( position ) );
//Removing The Bowler From The List
seriesList.remove( position );
mAdapter.notifyItemRemoved( position );
toggleEmptySeries();
}
//Opens Dialog With Edit/Delete Options
//Edit - 0
//Delete - 0
private void showActionsDialog(final int position) {
CharSequence colors[] = new CharSequence[]{"Edit", "Delete"};
AlertDialog.Builder builder = new AlertDialog.Builder( this );
builder.setTitle( "Choose option" );
builder.setItems( colors, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (which == 0) {
showSeriesDialog( true, seriesList.get( position ), position );
} else {
deleteSeries( position );
}
}
} );
builder.show();
}
//Show Alert Dialog With EditText Options to Enter/Edit A Series
//When shouldUpdate = true, It Will Automatically Display Old Series Name And Change The Button Text To UPDATE
private void showSeriesDialog(final boolean shouldUpdate, final Series series, final int position) {
LayoutInflater layoutInflaterAndroid = LayoutInflater.from( getApplicationContext() );
final View view = View.inflate( this, R.layout.dialog_series, null );
AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder( SeriesActivity.this );
alertDialogBuilderUserInput.setView( view );
final EditText inputSeries = view.findViewById( R.id.etSeriesNameInput );
leagueId.setText( savedLeagueId );
bowlerId.setText( savedBowlerId );
TextView dialogTitle = view.findViewById( R.id.dialog_title );
dialogTitle.setText( !shouldUpdate ? getString( R.string.lbl_new_series_title ) : getString( R.string.lbl_edit_series_title ) );
if (shouldUpdate && series != null) {
inputSeries.setText( series.getName() );
leagueId.setText( series.getLeagueId() );
bowlerId.setText( series.getBowlerId() );
}
alertDialogBuilderUserInput.setCancelable( false ).setPositiveButton( shouldUpdate ? "update" : "save", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogBox, int id) {
}
} ).setNegativeButton( "cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogBox, int id) {
dialogBox.cancel();
}
} ) .setNeutralButton("use date",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogBox, int id) {
String dateNow = getDateNow();
inputSeries.setText(dateNow);
}
});
final AlertDialog alertDialog = alertDialogBuilderUserInput.create();
alertDialog.show();
alertDialog.getButton( AlertDialog.BUTTON_NEUTRAL ).setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v) {
//Show Toast Message When No Text Is Entered
if (inputSeries.getText().toString() !=null || !inputSeries.getText().toString().isEmpty() ) {
String dateNow = getDateNow();
inputSeries.setText(dateNow);
return;
} else {
alertDialog.dismiss();
}
//Check If User Is Updating Series
if (shouldUpdate && series != null) {
//Updating Series By Its Id
updateSeries( inputSeries.getText().toString(), position );
} else {
//Creating New Series
createSeries( leagueId.getText().toString(), bowlerId.getText().toString(), inputSeries.getText().toString() );
}
}
} );
alertDialog.getButton( AlertDialog.BUTTON_POSITIVE ).setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v) {
//Show Toast Message When No Text Is Entered
if (TextUtils.isEmpty( inputSeries.getText().toString() )) {
Toast.makeText( SeriesActivity.this, "Enter Series!", Toast.LENGTH_SHORT ).show();
return;
} else {
alertDialog.dismiss();
}
//Check If User Is Updating Series
if (shouldUpdate && series != null) {
//Updating Series By Its Id
updateSeries( inputSeries.getText().toString(), position );
} else {
//Creating New Series
createSeries( leagueId.getText().toString(), bowlerId.getText().toString(), inputSeries.getText().toString() );
}
}
} );
}
//Toggling List And Empty Series View
private void toggleEmptySeries() {
//You Can Check seriesList.size() > 0
if (db.getSeriesCount() > 0) {
noSeriesView.setVisibility( View.GONE );
} else {
noSeriesView.setVisibility( View.VISIBLE );
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate( R.menu.menu_main, menu );
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
overridePendingTransition(0, 0);
return true;
}
return super.onOptionsItemSelected( item );
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
//Check If Request Code Is The Same As What Is Passed - Here It Is 1
if(requestCode==1)
{
String savedLeagueId=data.getStringExtra("seriesLeagueId");
String savedBowlerId=data.getStringExtra("seriesBowlerId");
seriesList.addAll( db.getAllSeries( savedLeagueId, savedBowlerId ) );
}
}
private String getDateNow() {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("EEE. MMM. dd, yyyy", Locale.ENGLISH);
return sdf.format(cal.getTime());
}
#Override protected void onResume() {
super.onResume(); //seriesList.addAll( db.getAllSeries( savedLeagueId, savedBowlerId) );
}
}
In order for the values to be written in the db you must call:
values.put(Series.COLUMN_SERIES_AVERAGE, total);
update(table_name, values, "column_name=column_value", null)
table_name is the name of the table where you insert the values

cant decode a message from a Websocket

I`m trying to connect my HTML/JS client to my C# server as a part of a university project in order to allow the user real-time notification. (I just need the server to be able to send a specific user a message at any given time)
My server Is just a mock in order to implement it in my project.
I Successfully passed the handshake stage and I am trying to send a plain string from the server to the client. I read something about Encoding the message is a way that the client will not give the "One or more reserved bits are on: reserved1 = 0, reserved2 = 1, reserved3 = 1" error but without success.
How can I send primitive data through the Sockets and decode them on the client?
My server code:
while (true)
{
TcpListener sck = new TcpListener(IPAddress.Any, 7878);
sck.Start(1000);
TcpClient client = sck.AcceptTcpClient();
NetworkStream _stream = client.GetStream();
StreamReader clientStreamReader = new StreamReader(_stream);
StreamWriter clientStreamWriter = new StreamWriter(_stream);
while (true)
{
while (!_stream.DataAvailable) ;
Byte[] bytes = new Byte[client.Available];
_stream.Read(bytes, 0, bytes.Count());
String data = Encoding.UTF8.GetString(bytes);
if (Regex.IsMatch(data, "^GET"))
{
const string eol = "\r\n"; // HTTP/1.1 defines the sequence CR LF as the end-of-line marker
Byte[] response = Encoding.UTF8.GetBytes("HTTP/1.1 101 Switching Protocols" + eol
+ "Connection: Upgrade" + eol
+ "Upgrade: websocket" + eol
+ "Sec-WebSocket-Accept: " + Convert.ToBase64String(
System.Security.Cryptography.SHA1.Create().ComputeHash(
Encoding.UTF8.GetBytes(
new System.Text.RegularExpressions.Regex("Sec-WebSocket-Key: (.*)").Match(data).Groups[1].Value.Trim() + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
)
)
) + eol
+ eol);
_stream.Write(response, 0, response.Length);
}
else
{
}
}
}
My Client Code:
<script type="text/javascript">
function WebSocketTest() {
if ("WebSocket" in window) {
alert("WebSocket is supported by your Browser!");
// Let us open a web socket
var ws = new WebSocket("ws://localhost:7878");
ws.onopen = function () {
// Web Socket is connected, send data using send()
ws.send("Message to send");
alert("Message is sent...");
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
alert("Message is received...");
};
ws.onclose = function () {
// websocket is closed.
alert("Connection is closed...");
};
} else {
// The browser doesn't support WebSocket
alert("WebSocket NOT supported by your Browser!");
}
}
</script>
I kept my server as above but added a send string function, and a decode message function:
public static string DecodeMessage(Byte[] bytes)
{
string incomingData = string.Empty;
byte secondByte = bytes[1];
int dataLength = secondByte & 127;
int indexFirstMask = 2;
if (dataLength == 126)
indexFirstMask = 4;
else if (dataLength == 127)
indexFirstMask = 10;
IEnumerable<byte> keys = bytes.Skip(indexFirstMask).Take(4);
int indexFirstDataByte = indexFirstMask + 4;
byte[] decoded = new byte[bytes.Length - indexFirstDataByte];
for (int i = indexFirstDataByte, j = 0; i < bytes.Length; i++, j++)
{
decoded[j] = (byte)(bytes[i] ^ keys.ElementAt(j % 4));
}
return Encoding.UTF8.GetString(decoded, 0, decoded.Length);
}
public static void SendString(string userName ,string str)
{
if (!userConnections.ContainsKey(userName))
return;
TcpClient client = userConnections[userName];
NetworkStream _stream = client.GetStream();
try
{
var buf = Encoding.UTF8.GetBytes(str);
int frameSize = 64;
var parts = buf.Select((b, i) => new { b, i })
.GroupBy(x => x.i / (frameSize - 1))
.Select(x => x.Select(y => y.b).ToArray())
.ToList();
for (int i = 0; i < parts.Count; i++)
{
byte cmd = 0;
if (i == 0) cmd |= 1;
if (i == parts.Count - 1) cmd |= 0x80;
_stream.WriteByte(cmd);
_stream.WriteByte((byte)parts[i].Length);
_stream.Write(parts[i], 0, parts[i].Length);
}
_stream.Flush();
}
catch (Exception ex)
{
Console.WriteLine("Error");
}
}
Where userConnections is: public static Dictionary userConnections = new Dictionary();
in order to maintain user - connection relation
You can use SuperWebSocket, this library sends the handshake automatically.
Server:
using SuperSocket.SocketBase;
using SuperWebSocket;
using System;
using System.Net;
using System.Net.Sockets;
namespace Jees.Library.WebSocket
{
public class WebSocket
{
WebSocketServer appServer;
public event EventHandler ServerStarted;
public event EventHandler ServerStopped;
public event EventHandler MessageReceived;
public string IP { get; } = string.Empty;
public int Port { get; } = 1337; //change this to the port you want to use
public WebSocket() => this.IP = GetLocalIPAddress(); //or set it manually
public void Start()
{
appServer = new WebSocketServer();
if (!appServer.Setup(this.IP, this.Port))
{
this.OnServerStarted(new WebSocketServerEventArgs(false));
return;
}
/* start listening */
appServer.NewMessageReceived += new SessionHandler<WebSocketSession, string>(AppServer_NewMessageReceived);
if (appServer.Start())
this.OnServerStarted(new WebSocketServerEventArgs(true));
else
{
this.OnServerStarted(new WebSocketServerEventArgs(false));
appServer = null;
appServer.Dispose();
}
}
public void Stop()
{
if (appServer != null)
{
appServer.Stop();
this.OnServerStopped(new EventArgs());
appServer = null;
appServer.Dispose();
}
}
private void AppServer_NewMessageReceived(WebSocketSession session, string message)
{
this.OnMessageReceived(new MessageReceivedEventArgs(message, session));
}
protected virtual void OnMessageReceived(EventArgs e) => this.MessageReceived?.Invoke(this, e);
protected virtual void OnServerStarted(EventArgs e) => this.ServerStarted?.Invoke(this, e);
protected virtual void OnServerStopped(EventArgs e) => this.ServerStopped?.Invoke(this, e);
private string GetLocalIPAddress()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
if (ip.AddressFamily == AddressFamily.InterNetwork)
return ip.ToString();
throw new Exception("No network adapters with an IPv4 address in the system!");
}
}
public class WebSocketServerEventArgs : EventArgs
{
public WebSocketServerEventArgs(bool success) => this.Success = success;
public bool Success { get; }
}
public class MessageReceivedEventArgs : EventArgs
{
public MessageReceivedEventArgs(string message, WebSocketSession session)
{
this.Message = message;
this.Session = session;
}
public string Message { get; }
public WebSocketSession Session { get; }
}
}
Server Setup (I use a UserControl):
using DevExpress.XtraEditors;
using SuperWebSocket;
using System;
using System.Linq;
using System.Windows.Forms;
namespace WebSocketServer
{
public partial class Server : UserControl
{
WebSocket server;
WebSocketSession session;
public Server()
{
InitializeComponent();
server = new WebSocket();
server.ServerStarted += Server_ServerStarted;
server.ServerStopped += Server_ServerStopped;
server.MessageReceived += Server_MessageReceived;
}
private void Server_MessageReceived(object sender, EventArgs e)
{
MessageReceivedEventArgs eventArgs = (MessageReceivedEventArgs)e;
/* save session */
this.session = eventArgs.Session;
this.Log("SessionID: " + session.RemoteEndPoint.ToString() + "; Message: " + eventArgs.Message);
/* send back the message to the client */
this.session.Send(eventArgs.Message); //comment out if needed
}
private void Server_ServerStopped(object sender, EventArgs e)
{
this.Log("Server stopped!");
}
private void Server_ServerStarted(object sender, EventArgs e)
{
if ((e as WebSocketServerEventArgs).Success)
{
this.Log("Server started on ws://" + server.IP + ":" + server.Port + "/");
}
else
this.Log("Can't start the server!");
}
private void Log(string message)
{
/* here, this.log is a TextBox */
if (this.log.InvokeRequired)
this.log.Invoke((MethodInvoker)delegate
{
this.log.Text += DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + " > " + message + Environment.NewLine;
});
else
{
this.log.Text += DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + " > " + message + Environment.NewLine;
}
}
/* a button to start the server */
private void BtnStart_Click(object sender, EventArgs e) => server.Start();
/* a button to stop the server */
private void BtnStop_Click(object sender, EventArgs e) => server.Stop();
/* a button to send a message from a TextBox to the client */
private void BtnSend_Click(object sender, EventArgs e)
{
if (this.txtMessage.Text != string.Empty)
this.SendMessage(this.txtMessage.Text);
}
private void SendMessage(string message)
{
try
{
/* use current session to send the message */
this.session.Send(message);
this.Log("Message: " + message + " sent to client!");
}
catch (Exception e)
{
this.Log(e.Message);
}
}
}
}
If you need more clarification, add a comment and I'll update my answer!

Java Program TextFile Issue

I have a program where a text file is read in and then each word in the file is outputted, followed by the # of times it is repeated throughout the file.
Use the following code.
import java.io.*;
class FileRead {
public static void main(String args[]) {
try {
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream("C:\\Users\\Desktop\\formate.txt");
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
System.out.println(strLine);
}
//Close the input stream
in.close();
} catch (Exception e) {//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
}
Try this code:
public static void main(String[] args) throws Throwable
{
File inputFile = new File("input.txt");
File outputFile = new File("output.txt");
Scanner scanner = new Scanner(inputFile);
HashMap<String, Integer> count = new HashMap<String, Integer>();
while (scanner.hasNext())
{
String word = scanner.next();
if (count.containsKey(word))
{
count.put(word, count.get(word) + 1);
}
else
{
count.put(word, 1);
}
}
scanner.close();
BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile));
for (Entry<String, Integer> entry : count.entrySet())
{
writer.write("#" + entry.getKey() + " " + entry.getValue()+"\r\n");
}
writer.close();
}
This also, it is a lot simpler if You can't use HashMap or BufferedReader:
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;
import java.util.Scanner;
public class WordCounter
{
public static void main(String[] args) throws Throwable
{
File inputFile = new File("input.txt");
File outputFile = new File("output.txt");
Scanner scanner = new Scanner(inputFile);
LinkedList<Word> words = new LinkedList<Word>();
while (scanner.hasNext())
{
String word = scanner.next();
addWord(words, word);
}
scanner.close();
WriteToFile(outputFile, words);
}
private static void WriteToFile(File outputFile, LinkedList<Word> words) throws IOException
{
BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile));
for (Word word : words)
{
writer.write("#" + word.getWord() + " " + word.getCount() + "\r\n");
}
writer.close();
}
private static void addWord(LinkedList<Word> words, String word)
{
for (Word aWord : words)
{
if (aWord.getWord().equals(word))
{
aWord.incrementCount();
return;
}
}
words.add(new Word(word, 1));
}
}
class Word
{
private String word;
private int count;
public Word(String word, int count)
{
this.word = word;
this.count = count;
}
public String getWord()
{
return word;
}
public void setWord(String word)
{
this.word = word;
}
public int getCount()
{
return count;
}
public void setCount(int count)
{
this.count = count;
}
public void incrementCount()
{
count++;
}
#Override
public String toString()
{
return "Word: " + word + " Count: " + count;
}
}

Android WebView Compile a Form and submit with Javascript

I'm trying to complete this form :
http://www.lbalberti.it/whatsup.asp?codist=57247
I was able to insert value to the two textbox but the button doesn't work.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_page);
final String user = getIntent().getStringExtra("username");
final String psw = getIntent().getStringExtra("password");
MyWebView view = new MyWebView(this);
view.getSettings().setJavaScriptEnabled(true);
view.getSettings().setDomStorageEnabled(true);
view.loadUrl("http://www.lbalberti.it/whatsup.asp?codist=57247");
view.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView v, String url) {
v.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView v, String url) {
v.loadUrl("javascript:" +
"var y = document.getElementsByName('login')[0].value='"+user+"';" +
"var x = document.getElementsByName('password')[0].value='"+psw+"';");
}
});
setContentView(view);
}
class MyWebView extends WebView {
Context context;
public MyWebView(Context context) {
super(context);
this.context = context;
}
}
The following code doesn't work :
"var k = document.getElementByTagName('form')[0].submit();"
or
"var k = document.getElementByName('newlogin')[0].submit();"
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
view.evaluateJavascript("javascript:document.getElementById('username').value ='" + strUsername + "';javascript:document.getElementById('password').value = '" + strPassword + "';javascript:document.getElementById('loginButton').click();", null);
} else {
view.loadUrl("javascript:document.getElementById('username').value = '" + strUsername + "';javascript:document.getElementById('password').value = '" + strPassword + "';javascript:document.getElementById('loginButton').click();");
}
}

Mustache/handlebars templating: figure out context data structure from template html

In mustache/handlerbars or any templating system in js,
are there any tools to gather all the variables that a template refers to?
for example, given input
templateHTML:
<div class="{{divclass}}">
{#item}}
<h1>{{title}}</h1>
<span>{{text}}</span>
{{/item}}
</div>
would return
{
divclass: "",
item: {
title: "",
text: ""
}
}
when used like MyTemplateTool.getTemplateData(templateHTML)
I tried googling around and checking out handlebars docs but could not find anything suitable
I believe it's just .. See the related docs on paths. Example:
{{#srcs}}
<script src="{{.}}"></script>
{{/srcs}}
I had the same in mind and I thought it was worth while writing something so here you go:
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MustacheSchemaBuilder
{
static String javaIdentifierRegExp = "[a-zA-Z_$0-9]+";
static String tab = " ";
static Format format = Format.java;
enum Format {
json,
java,
;
}
enum TagType {
variable("\\{\\{\\s*" + javaIdentifierRegExp + "\\s*\\}\\}"),
escapedVariable("\\{\\{\\{\\s*" + javaIdentifierRegExp + "\\s*\\}\\}\\}"),
sectionStart("\\{\\{#\\s*" + javaIdentifierRegExp + "\\s*\\}\\}"),
invertedSectionStart("\\{\\{\\^\\s*" + javaIdentifierRegExp + "\\s*\\}\\}"),
sectionEnd("\\{\\{/\\s*" + javaIdentifierRegExp + "\\s*\\}\\}"),
//partial("\\{\\{>\\s*" + javaIdentifierRegExp + "\\s*\\}\\}"),
// no support for set delimiters or partials
;
Pattern pat;
private TagType(String aRegExp) {
pat = Pattern.compile(aRegExp);
}
public Pattern getPattern() { return pat; };
}
class Tag{
public TagType type;
public String identifier;
Tag(TagType aType, String aIdentifier) { type = aType; identifier = aIdentifier;}
public String toString() { return type.name() + " : " + identifier; }
#Override
public boolean equals(Object aOther) {
if(!(aOther instanceof Tag)) return false;
Tag ot = (Tag) aOther;
return ot.type.equals(this.type) && ot.identifier.equals(this.identifier);
}
#Override
public int hashCode() {return identifier.hashCode();}
}
class Node {
public Section parent;
public Tag tag;
Node(Section aParent, Tag aTag){parent = aParent; tag = aTag; if(parent != null) parent.children.put(tag, this);}
#Override
public int hashCode() {return tag.hashCode();}
public int depth() {
int depth = 0;
Node currentNode = this;
while(currentNode.parent != null) {
depth++;
currentNode = currentNode.parent;
}
return depth;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
for(int i = 0; i < this.depth(); i++) sb.append(tab);
switch(format) {
case java:
sb.append("public Object ").append(tag.identifier).append(";\n");
break;
case json:
default:
sb.append(tag.identifier).append(": {},\n");
}
return sb.toString();
}
}
class Section extends Node{
public Map<Tag, Node> children = new LinkedHashMap();
Section(Section aParent, Tag aTag) { super(aParent, aTag); };
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
for(int i = 0; i < this.depth(); i++) sb.append(tab);
switch(format) {
case java:
sb.append("public Object ").append(tag.identifier).append(" = new Object() {\n");
for(Node child : this.children.values()) sb.append(child);
for(int i = 0; i < this.depth(); i++) sb.append(tab);
sb.append("};\n");
break;
case json:
default:
sb.append(tag.identifier).append(": {\n");
for(Node child : this.children.values()) sb.append(child);
for(int i = 0; i < this.depth(); i++) sb.append(tab);
sb.append("},\n");
}
return sb.toString();
}
}
class MustacheSchemaBuildException extends Exception {
private static final long serialVersionUID = 1L;
MustacheSchemaBuildException(String aMessage) {super(aMessage);}
}
Section rootSection;
public MustacheSchemaBuilder(String aContents) throws Exception
{
TreeMap<Integer, Tag> tagMap = new TreeMap();
for(TagType type : TagType.values()) {
populateMap(tagMap, type, aContents);
}
System.out.println(tagMap);
rootSection = new Section(null, new Tag(TagType.sectionStart, "$root$"));
Section currentSection = rootSection;
for(Tag tag : tagMap.values()) {
if(currentSection.tag.type == TagType.invertedSectionStart) {
if(tag.type == TagType.sectionEnd) {
if(!tag.identifier.equals(currentSection.tag.identifier))
throw new MustacheSchemaBuildException("The end tag: " + tag.identifier + " doesn't match the expected start tag: " + currentSection.tag.identifier + "\n\n" + rootSection);
currentSection = currentSection.parent;
}
continue;
}
switch(tag.type)
{
case variable:
if(!currentSection.children.containsKey(tag))
new Node(currentSection, tag);
break;
case sectionStart:
Tag invertedSectionStartTag = new Tag(TagType.invertedSectionStart, tag.identifier);
if(!(currentSection.children.containsKey(tag) || currentSection.children.containsKey(invertedSectionStartTag)))
new Section(currentSection, tag);
currentSection = (Section)currentSection.children.get(tag);
break;
case invertedSectionStart:
Tag sectionStartTag = new Tag(TagType.sectionStart, tag.identifier);
if(!(currentSection.children.containsKey(tag) || currentSection.children.containsKey(sectionStartTag)))
new Section(currentSection, tag);
currentSection = (Section)currentSection.children.get(sectionStartTag);
break;
case sectionEnd:
if(!tag.identifier.equals(currentSection.tag.identifier))
throw new MustacheSchemaBuildException("The end tag: " + tag.identifier + " doesn't match the expected start tag: " + currentSection.tag.identifier + "\n\n" + rootSection);
currentSection = currentSection.parent;
break;
default:
}
}
}
public void build() {
System.out.println(rootSection);
}
public static void main(String[] args) throws Exception
{
String contents;
try {
contents = readFile(args[0], Charset.defaultCharset());
}catch(Exception e)
{
System.out.println("Unable to open file!");
throw e;
}
MustacheSchemaBuilder builder = new MustacheSchemaBuilder(contents);
builder.build();
}
void populateMap(Map<Integer, Tag> map, TagType aType, String aContents) {
Matcher m = aType.getPattern().matcher(aContents);
while(m.find()) {
int start = m.start() + 3;
if(aType == TagType.variable) start = m.start() + 2;
map.put(m.start(), new Tag(aType, aContents.substring(start, m.end() - 2).trim()));
}
}
static String readFile(String path, Charset encoding) throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
}
Give the template file path at the command line - you need java 7 or higher to open the file, or you can just rewrite the readFile - method. You can produce a json or java 'schema' by changing the format at the top of the class. The 'schema' gets written to stdout, you can copy it from there and paste it into where you need it. Hope this helps. Ah! This doesn't support partials or set delimiters, but if you get round to writing support ping it to me as I might want it :)

Categories

Resources