The problem is to send local image from phone as encoded Base64 string to Chromecast. And decode it using my Custom Receiver. I was following this guide which is based on this project sample.
I suggest the problem might be in:
Custom Receiver is not proper (I'm not strong in JS).
Chromecast didn't load that Receiver (I don't know how to check that).
Image was encoded wrong on device or decoded on Chromecast.
You see, it seems like I coded everithing right since the status of Chromecast when I send photo is:
statusCode 0 (success),
application name: Default Media Receiver,
status: Ready To Cast,
sessionId: 34D6CE75-4798-4294-BF45-2F4701CE4782,
wasLaunched: true.
This is how I send image as String:
mCastManager.castImage(mCastManager.getEncodedImage(currentEntryPictureByPoint.getPath()));
Methods used:
public void castImage(String encodedImage)
{
Log.d(TAG, "castImage()");
String image_string = createJsonMessage(MessageType.image, encodedImage);
sendMessage(image_string);
}
private static String createJsonMessage(MessageType type, String message)
{
return String.format("{\"type\":\"%s\", \"data\":\"%s\"}", type.toString(), message);
}
/**
* Convert Image to encoded String
* */
public String getEncodedImage(String path){
Bitmap bm = BitmapFactory.decodeFile(path);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos); //bm is the bitmap object
byte[] byteArrayImage = baos.toByteArray();
String encodedImage = Base64.encodeToString(byteArrayImage, Base64.DEFAULT);
return encodedImage;
}
/**
* Send a text message to the receiver
*
* #param message
*/
private void sendMessage(String message) {
if (mApiClient != null && mCustomImageChannel != null) {
try {
Cast.CastApi.sendMessage(mApiClient,
mCustomImageChannel.getNamespace(), message)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status result) {
if (!result.isSuccess()) {
//ALWAYS REACHING HERE :(
Log.e(TAG, "Sending message failed");
}
}
});
} catch (Exception e) {
Log.e(TAG, "Exception while sending message", e);
}
} else {
Toast.makeText(mContext, message, Toast.LENGTH_SHORT)
.show();
}
}
If the sending process is correct then the Receiver is wrong and don't know how to decode this message properly.
The way I uploaded it (well, at least I think that its uploaded...)
Registered new Custom Receiver on Google Cast Console and received Application ID.
Created cast_receiver.js file. The code inside this file is supposed to decode Base64 string into image.
Copied the code for Receiver from guide to .js file and changed NAMESPACE inside to my one: urn:x-cast:com.it.innovations.smartbus
Uploaded file on Google Drive and modified its access visibility to full public
Copied the link to file to URL field in Cast Console. This link is direct download of file.
Restarted Chromecast. Seems like it tried to download something but not sure if succeed
If anyone faced this problem, please point me out what I am doing wrong. Appreciate any help.
P.S. tell if some more code needed...
I very strongly suggest to avoid using the sendMessage() for sending any large data set; those channels are meant to be used as control channels and not as a way to send a chunk of data. A much much simpler and more robust approach is to embed a tiny dumb web server in your local app (on the sender side) and "serve" your images to your chromecast. There is a number of ready-to-use embedded web servers that you can put in your app and requires almost no configuration; then you can serve all sorts of media, including images, to your chromecast with even the default or styled receiver.
Related
This question already has answers here:
Recommended way to save uploaded files in a servlet application
(2 answers)
Closed 1 year ago.
I am try uploading the image using the below servlet
But after upload I am able save the file but I am not able to open I checked the file is corrupted.
Instead of using the annotation I have describe multipart-config in web.xml.
I this code I am trying to get the image file I send the data using AJAX.
Then I am redirected to Register servlet there I am using InputStream class to handle data.
After this I creating the file and upload this Inputdata to file in some directory on server.
public class Register extends HttpServlet{
#Override
protected void doPost(HttpServletRequest req,HttpServletResponse res) throws ServletException,IOException{
String username=req.getParameter("username");
String password=req.getParameter("password");
String email=req.getParameter("email");
Part part = req.getPart("image");
String filename = part.getSubmittedFileName();
InputStream is = req.getInputStream();
byte[] data = new byte[is.available()];
String path = "D:\\FullstackWeb\\images\\icon\\"+filename;
System.out.println(path);
FileOutputStream fos=new FileOutputStream(path);
fos.write(data);
res.setContentType("text/html");
PrintWriter out = res.getWriter();
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://dns1.nishchay.com:3306/register","demouser","123Nbr#");
String query = "Insert INTO register.signup(username,email,userpassword,filename) values(? ,?, ?,?)";
PreparedStatement pstmt= conn.prepareStatement(query);
pstmt.setString(1, username);
pstmt.setString(2, email);
pstmt.setString(3, password);
pstmt.setString(4, path);
pstmt.executeUpdate();
conn.close();
}catch(Exception e) {
out.println("<h1>Issue is occured</h1>");
}
}
}```
You are not reading in the image data:
InputStream is = req.getInputStream();
byte[] data = new byte[is.available()];
String path = "D:\\FullstackWeb\\images\\icon\\"+filename;
System.out.println(path);
FileOutputStream fos=new FileOutputStream(path);
fos.write(data);
does not contain any is.read() call and it doesn't close the FileOutputStream.
In addition to that your allocated buffer is to small for most images. The JavaDoc for InputStream.available() states
Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking
To completely read the image data you could simply replace the above code with
Files.copy(is, Paths.get("D:\\FullstackWeb\\images\\icon\\"+filename));
but with a big caveat: since the file name is supplied by the user of your service this opens your code to security problems.
So I have defined an integration in the Helium Console (i.e. - an IoT LoRaWAN networking service). When I test out sending data from my IoT device to my Helium Console integration endpoint, I can see the payload. And I can manually decode it back to the JSON request body that's correct. But am having trouble defining a custom function in the Helium Console that will automate this for the integration. My IoT device is serializing a MsgPack payload of environmental data that's then sent to the Helium Console integration endpoint. And the Helium Console custom function allows Javascript, although just bare-bones without any requires, imports, etc.
Below is the Python script that can manually decode the payload. If anyone is familiar with this area I'd be interested as to suggestions. There are pre-defined decoders available for Helium, although none that match exactly my hardware.
If anyone has created custom decoding functions for Helium Console integrations I'd be curious as to how I could knock this out. Here is some info about this --> https://docs.helium.com/use-the-network/console/functions/.
import ssl, sys, json, base64
import msgpack
payload = "haJiVspAozMzo3RfQxilZWNfbVMWonBoB6NvcnAC"
# decode the payload from base64 and unpack
b64 = base64.b64decode(payload)
mp_dict = msgpack.unpackb(b64)
print(mp_dict) # output is {'bV': 5.099999904632568, 't_C': 24, 'orp': 2, 'ph': 7, 'ec_mS': 22}
Rather than reinvent the wheel, I modified the Arduino code running on my device. Pulling in the CayenneLPP library I manually encode what I need, so that the Helium Console's canned CayenneLPP decoding function can correctly parse the data.
Arduino code snippet below.
#include <CayenneLPP.h>
...
/*CayenneLPP variable*/
CayenneLPP lpp(51);
...
static void prepareTxFrame( uint8_t port )
{
appDataSize = lpp.getSize();
uint8_t lppBuffer[128];
memcpy(lppBuffer, lpp.getBuffer(), 128);
memcpy(appData, lppBuffer, lpp.getSize());
}
...
// The loop function is called in an endless loop
void loop()
{
lpp.reset();
lpp.addTemperature(1, 22.5);
lpp.addBarometricPressure(2, 1073.21);
lpp.addGPS(3, 52.37365, 4.88650, 2);
...
LoRaWAN.displaySending();
prepareTxFrame( appPort );
LoRaWAN.send(loraWanClass);
...
}
https://github.com/helium/console-decoders/blob/master/debugDecodeBase64.js
// LoRaWan devices automatically base64 encode data sent
// Sometimes nice just to view what original payload was sent
//
// This can help when writing your own decoder
//
//
function Decoder(bytes, port, uplink_info) {
var decoded={};
try{
var result = String.fromCharCode.apply(null, bytes);
decoded.value = result;
return decoded;
} catch (err) {
return 'Decoder: ' + err.name + " : " + err.message;;
}
}
// And in the integration section of the Helium console use this JSON
// For an Adafruit.io integration which is expecting JSON like { "value" : "56" }
//
// { "value": {{decoded.payload.value}} }
Create account on https://app.datacake.de/
Create integration to Datacake in here: https://console.helium.com/integrations
integrations
Link the flow in here:
https://console.helium.com/flows
flows
Create project and add device to DataCake, as decoder function use modified above (as is - it will receive a string)
I have an xml document that I generated in C#, I would like to return the string/document via WCF/REST so it will be downloaded by the browser. What is the operationcontract/return type that I should use? And how can I get it to be prompted to save by javascript and the browser.
Your operation contract should not be one way and you should return Stream
[OperationContract(IsOneWay = false)]
[WebGet(UriTemplate = "GetXml/{xmlFileName}")]
Stream GetXml(string xmlFileName);
public Stream GetXml(string xmlFileName)
{
WebOperationContext.Current.OutgoingResponse.ContentType = "application/octet-stream";
string xmlLocation=GetXmlLocation(xmlFileName);
try
{
return File.OpenRead(xmlLocation);
}
catch
{
// File Not Found
return null;
}
}
I had the similar issue with NodeJS backend.
I returned XML as a string and then on front-end I used next code:
Download
I'm trying to configure wifi credentials for a particle photon (wifi microcontroller with cloud support).
There are existing methods for Java / ios / android / javascript.
However, i need to do this in C# (for a desktop and xamarin multiplatform app).
I succesfully managed to connect to the device, retreive it's ID, retreive the public key and the nearby wifi access points (using Webrequests and deserialized json objects)
However, i am stuck with the RSA encryption of the wifi password i need to pass through.
I'm trying to use the RSACryptoServiceProvider but to encrypt i need to pass a xml string and probably the key in a different (base64?) format. Also there seems to be some kind of splicing that needs to happen.
This is the retreived public key (in HEX):
30819F300D06092A864886F70D010101050003818D00308189028181009885DC94E34A23A2942BB9EB6721C4233E9EDCC9A967F587CEA527E1D447F48319CA6C4178DFF739C0AB079E02467DD4D3AD3214416F0983C3967EA71378D7D93A885F1575D71D009990BFFC0882FC721F4DC98A0D80B4CCF12E51066D69055E9A3C95E247BEB9DC16176A083DE7FA93C23449A3870D599DA9D507964F7FC4B90203010001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
This is a function in github softap-js:
SoftAP.prototype.publicKey = function publicKey(cb) {
is(cb);
var sock = this.__sendCommand('public-key', response.bind(this));
function response(err, dat) {
if(err) { return cb(err); }
if(!dat) { return cb(new Error('No data received')); }
if(dat.r !== 0) {
return cb(new Error('Received non-zero response code'));
}
var buff = new Buffer(dat.b, 'hex');
this.__publicKey = new rsa(buff.slice(22), 'pkcs1-public-der', {
encryptionScheme: 'pkcs1'
})
cb(null, this.__publicKey.exportKey('pkcs8-public'));
};
return sock;
};
Which appears to handle the public key. i guess i just need to somehow convert this to .net but i would appreciate any help or hint with that since I'm not familiar at all with encryption.
I am trying to do pretty much the same, as is for example on Sourceforge. After a user creates some data, I generate a file and I want it to be offered to him after a page load. However, I know almost nothing about javascript and simple copy-paste of
<script type="text/javascript">
var download_url = "http://downloads.sourceforge.net/sourceforge/itextsharp/itextsharp-4.1.2-dll.zip?use_mirror=dfn";
function downloadURL() {
if (download_url.length != 0 && !jQuery.browser.msie) {
window.location.href = download_url;
}
}
jQuery(window).load(downloadURL);
</script>
is not enough. It is important for the user to download the file, so how to do that?
A question related to the previous is - where to store the file i created? Once while using the asp.net development server and then on the real IIS server? And how should this address look? When I tried
setTimeout("window.location.href='file://localhost/C:/Downloads/file.pdf'", 2000);
I was getting nothing, with HTTP an error of unknown address.
See Haack's DownloadResult example. It explains (I think) exactly what you're truing to do. Except you would provide the timeout call with your download action url.
you're asking the user's browser to look for a file on their own computer... that you're trying to save there.
you could use something like:
window.location.href='http://www.yourServer.com/generatePDF.asp?whatever=whatever'
where http://www.yourServer.com/generatePDF.asp?whatever=whatever is what is generating the pdf file for the user
On the server, you have to set the content disposition in the response header to "Attachment" as described in these answers.
If you do that, the download will not affect the page that is currently displayed in the browser. So, if you initiate a request in Javascript that gets an attachment, the browser will leave the page alone, and the user will see a message box with the Open/Save/Cancel question.
You can create your own PdfResult which extends ActionResult like this:
public class PdfResult : ActionResult
{
public byte[] Content { get; set; }
public string FileName { get; set; }
public override void ExecuteResult(ControllerContext context)
{
var response = context.HttpContext.Response;
response.AddHeader("content-disposition", "attachment; filename=" + this.FileName);
response.AddHeader("content-length", this.Content.Length.ToString());
response.ContentType = "application/pdf";
using (MemoryStream memoryStream = new MemoryStream(this.Content))
{
memoryStream.WriteTo(response.OutputStream);
}
response.End();
}
Then in your action you can simply return the file as follows:
public ActionResult Pdf(string param1...)
{
var content = GeneratePdf(); //etc
var fileName = AssignFileName();
return new PdfResult { Content = content, FileName = fileName + ".pdf" };
}
A couple of different things. First, since you are using MVC, create an action that actually generates the file and returns it as a FileResult. The file can be an actual file on the server, but it can also be generated dynamically -- say in a MemoryStream -- and the FileResult created from that. Set the content to application/octet-stream or the actual file type if it's not one that will render in the browser via a plugin. Second, don't generate the file in the action that renders the page, but rather call the action that generates the FileResult from that page using the technique you've referenced (though it looks like they are doing something different for IE). If the MIME type is not one that can be rendered it will be downloaded.
public ActionResult GenerateFile( string value, int other )
{
MemoryStream file = new MemoryStream();
...
return File( file, "application/octet-stream" );
}