Unity Android java.io.FileNotFoundException - android

I made a game with Unity3D which is working on my own android phone fine, but it seems not working on other phones. I don't have access to those phones, but this is what I was told.
More detail: My game is an android app and needs to send data to a server to be stored. The URL is something like this "https://example.com/register". The server is hosted on the google app engine. When a user attempts to send the data he gets an error back which is something like this "java.io.FileNotFoundException https://example.com/register". I checked the logs in my server, there is no record regarding a request from that user. I read somewhere that it's because of htaccess and WWW class and you can't call an URL with htaccess data in it! But there is no htaccess to that page in my server. The page simply receives the data and store them, no authentication needed.
Would be great if anyone has any other idea why some devices get this error and some don't.
string url = "https://my-app-name.appspot.com/register";
WWWForm form = new WWWForm();
form.AddField("playerEmail", playerEmail);
form.AddField("registrationId", registrationId);
form.AddField("playerName", playerName);
form.AddField("playerPass", playerPass);
WWW www = new WWW(url, form);
yield return www;
the server-side then use those provided data and return a simple string.
<?php
$player_name = $_POST['playerName'];
$player_pass = $_POST['playerPass'];
$player_email = $_POST['playerEmail'];
$gcm_registration_id = $_POST['registrationId'];
//store data in the Datastore.
echo "success";
?>
app.yaml
application: my-app-name
version: 1
runtime: php55
api_version: 1
threadsafe: false
handlers:
- url: /register
script: register.php

I also had this problem. The takeaway I had was
Java.io.filenotfound exception is bogus error. It's not anything to do with file io - it's the request failing at the server.
To find the actual error in unity - look at the www requestHeaders - this will give you back the response headers from the request from the server - mine was a 500, but it could be a 400+ type error (especially if you're using authentication).
You can do this by doing a
foreach(var header in request.responseHeaders)
....
If anyone wants I can post my diagnostic code to help out.

Related

"SSL: CERTIFICATE_VERIFY_FAILED" Error in Kivy Launcher

I'm building a short python script, logging into a website and grabbing some data on the page, using requests.
The script runs perfectly fine on my Mac, but when launched in Kivy Launcher, I get a certificate error, and the data is not grabbed
The code is as follows :
s = requests.session()
response = s.post('URL', data=form)
responsetext = response.text
On my Mac, responsetext is the data I need. On Android, I get the same message as here : "SSL: CERTIFICATE_VERIFY_FAILED" Error and the variable remains empty. I of course have tried the solutions proposed in the said post, but they are of course NOT working.
I can't use Kivy's UrlRequest because I need to stay logged into the website (and thus using Requests' sessions)
Thanks !

Google oauth2 works with one time code generated from Android but not working for code generated from JS SDK

I am trying to authenticate the user using oauth2 api from Google. There are 2 platforms, Android and Web. For new users, I am fetching the one-time auth code on the client and sending it to the server on both platforms. Once server receives the code, it is fetching the access token and after that, the user details. The server is able to fetch the token from the one-time auth code sent from Android device, but it is failing for the code sent from Web.
This is my code snippet in JS for fetching one-time auth code..
gauth2.grantOfflineAccess({
'scope': 'profile email',
'redirect_uri': 'postmessage'
}).then(function(e){
if(!e){
// Error
}
else{
console.log('Auth code: '+e.code);
}
});
On server side, this is the POST request that I am doing to fetch the token from one-time code..
post_data = {'code': one_time_code, 'client_id': settings.GOOGLE_OAUTH2_CLIENT_ID, 'client_secret': settings.GOOGLE_OAUTH2_CLIENT_SECRET, 'grant_type': 'authorization_code'}
req = urllib2.Request("https://www.googleapis.com/oauth2/v3/token", data=urllib.urlencode(post_data), headers={'User-Agent': 'Mozilla/5.0'})
req.get_method = lambda: 'POST'
res = urllib2.urlopen(req)
if res.code == 200:
print "response 200 : "
else:
print "Access Token Validation Return Code: ", res.code
This web service call returns 200 and token when the auth-code is generated from Android. When it is sent from web, the same method throws the following error..
Error: 400, invalid request; missing parameter 'redirect_uri'
In this case, I don't need to send any redirect_uri, because I am reading the response there itself. But I still tried setting an empty value and also tried setting it to some value that exactly matches one of the values in google developers console. In that case, I am still getting..
Error: 400, invalid request; redirect_uri mismatch.
I cannot get my head around the fact that this web service call is working perfectly for android codes and not for web codes. Please note that scopes are different for Android app and Web app. But still, this seems to be some fundamental error. Any help would be appreciated.

Upload assignment on Moodle using REST webservice function

I am trying to develop a Moodle Android app. I am using MoodleREST source code for my reference. But rest code to upload assignment is not provided by this library. I want to be able to upload assignment from mobile client with a webservice call. Uploading assignment using a webview is possible but in that case user need to login again to access upload assignment page.
I have found something similar here https://moodle.org/mod/forum/discuss.php?d=207875.
I am new to moodle and still learning it, so my question can be a little naive so please bear with it :)
It is kind of possible to upload a submission with a file to the assignment using Moodle webservices.
First upload a file to draft using core_files_upload
http://my-moodle-url/moodle/webservice/rest/server.php?wstoken=token_value_xyz&moodlewsrestformat=json&wsfunction=core_files_upload&component=user&filearea=draft&itemid=0&filepath=/&filename=test2.txt&filecontent=TWFuIGlzIGRpc3Rpbmd1aXNoZWQ=&contextlevel=user&instanceid=8
where:
itemid=0 - moodle will generate and return an itemid or you set itemid
filecontent - base64 encoded file contents
instanceid - userId whose is webservices token
Sample response:
{
"contextid": 26,
"component": "user",
"filearea": "draft",
"itemid": 293005570,
"filepath": "/",
"filename": "test3.txt",
"url": "http://my-moodle-url/moodle/draftfile.php/26/user/draft/293005570/test3.txt"
}
You can search for an assignment id for the next call with mod_assign_get_assignments
Then use itemid received, here "293005570", in mod_assign_save_submission
http://my-moodle-url/moodle/webservice/rest/server.php?wstoken=token_value_xyz&moodlewsrestformat=json&wsfunction=mod_assign_save_submission&assignmentid=5&plugindata[onlinetext_editor][text]
=some_text_here&plugindata[onlinetext_editor][format]
=1&plugindata[onlinetext_editor][itemid]=521767865&plugindata[files_filemanager]=521767865
This will add an assignment submission with this file.
The problem I could core_files_upload and mod_assign_save_submission only using a webservices token for a particular user, i.e. each user needs a webservices token which might be not practical. With a webservices user token I get on the first call:
{
"exception": "moodle_exception",
"errorcode": "nofile",
"message": "File not specified"
}
Tested with Postman. This might be related: https://tracker.moodle.org/browse/MDL-61276
Doesnt look like there is existing solution for this in moodle web services. Moodle actually encodes files in base64 which creates burden on mobile devices. Mobile devices dont have that much memory to encode big files.
Closet solution published by Moodle HQ (and otherwise) is this : https://github.com/moodlehq/sample-ws-clients/blob/master/PHP-HTTP-filehandling/client.php which saves file as private file and not as assignment. You may have to modify substantially the plugin.
To upload files I'm using this API with a POST method
https://{YOUR_URL}/webservice/upload.php?moodlewsrestformat=json&wstoken={WSTOKEN}
And you must pass the following parameters as FormData
file => File // your file
token => Int // same user's wstoken
filearea => String // draft, private... etc
itemid => Int // set to 0 to create a new file

Avoiding content type issues when downloading a file via browser on Android

If I have a file made available to a browser through my webapp, I normally just set the URL to something like http://website.com/webapp/download/89347/image.jpg. I then set the HTTP headers Content-Type: application/octet-stream; filename=image.jpg and Content-Disposition: Attachment.
However, on the Android. It seems the only way I can get the file to download is to set Content-Type: image/jpg. Otherwise the file name says <Unknown> and an error comes
Download unsuccessful
Cannot download. The content is not supported on this phone
Is there any way I can get Android to download and open the file through the browser without keeping a list of mime types?
To make any downloads work on all (and especially older) Android versions as expected, you need to...
set the ContentType to application/octet-stream
put the Content-Disposition filename value in double quotes
write the Content-Disposition filename extension in UPPERCASE
Read my blog post for more details:
http://digiblog.de/2011/04/19/android-and-the-download-file-headers/
Dmitriy (or others looking for a possible solution) if an html page is appearing in your downloaded file, I suspect this is due to the double HttpRequest GET issue. A typical scenario is the following POST, Redirect, GET model:
Android browser issues a HttpRequest POST to server (e.g. submit button or link to request a download file, filename.ext say)
Server streams the requested filename.ext to bytes, stores in a session variable, and then issues a Response.Redirect to Download.aspx, for example, to handle the response object construction
Android browser correctly sends HttpRequest GET to server for Download.aspx
Server responds with typical Content-Disposition: attachment; filename="filename.ext" style construct with the response object containing the requested filename.ext, being the bytes in the session variable.
Android download manager, I believe, then sends another HttpRequest GET to server for Download.aspx. I suspect that the download manager interprets the previous "attachment" response as a trigger to send this second GET.
Server (Download.aspx) again tries to construct the response object to send back to the browser.
Android download manager downloads filename.ext, using the response object contents from the second Download.aspx.
In many scenarios this would be fine. But if, for example, the server in the Download.aspx code does some housekeeping and removes the session variable the first time it is called, then the next time around there is no session variable. So, depending on how the code is written it is possible that the response object doesn't get explicity constructed and maybe the Response.End doesn't get called and so only the Download.aspx's html ends up being sent.
This is what we discovered using Wireshark, although I admit I am assuming it is the Android download manager that is the cause for the double GET.
I hope this explanation has been of some help.
As I wrote at downloading files from android:
Android browser will not download file in button Post events. In post events the file will be some .htm garbage file. to over come this do as below.
In download button click
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
Response.Redirect("download-file.aspx");
}
and on download-file.aspx file do as below
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class mobile_download_file : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string filename = "usermanual.pdf";
Response.ContentType = "application/octet-stream";
Response.AppendHeader("Content-Disposition", "attachment; filename=" + "" + filename + "");
Response.Write(Server.MapPath(Request.ApplicationPath) + "\\" + filename);
Response.TransmitFile(Server.MapPath(Request.ApplicationPath) + "\\" + filename);
Response.End();
}
}
the same can be implemented in php also.
I have tried all recommendations from Jspy blog and nothing worked so far. Content-disposition brings browser in downloading mode, however nothing gets downloaded except HTML of page from which download got initiated. So my conclusion, it is pure bug from Google and we may only pray for that Google fix it. My work around was to set content type to some type coming from Accept header form mobile browser. It generally works, you can even download zip files as text.
In theory, the filename parameter should be set on Content-Disposition, not Content-Type. Not sure whether this will help with the Android browser.

Post an image from Android client to Rails server without triggering InvalidAuthenticityToken

I'm building an Android app that runs off of a rails server. At first, when I tried to post simple String data to the server, I ran into an InvalidAuthenticityToken issue, but realized that I can bypass the authentication by setting the content type to "json"
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(Constants.REST_HOST + "/add_comment");
post.addHeader("Content-Type", "application/json");
The next step was trying to get upload profile picture working. However, when I tried uploading a photo via a MultipartEntity post, setting the content type to "json" causes the following error
StandardError (Invalid JSON string):
but not setting the content type brings back the InvalidAuthenticityToken exception. What's the correct way to post an image to a rails server from a foreign Java client?
ActionController::InvalidAuthenticityToken
(ActionController::InvalidAuthenticityToken):
Based on Jesse's suggestion, I ended up using
protect_from_forgery :except => :upload_avatar_pic
to disable authenticity check, but only for a specific function, so checks for browser requests are still validated.
You can disable authenticity checking on API non-get calls from non-web clients. You can do this in a before filter
class ApiController < ApplicationController
skip_before_filter :verify_authenticity_token
def create
#or whatever
end
end
The problem solved by Jesse Wolgamott said, but the page show "You are being redirected" message when I submit the form (Update,create,show). In before that the page redirected correctly. I am using rails 2.3.8.how to resolve this?

Categories

Resources