I'm developing an app in android which connects to a web service in php. The users can send pictures, or better said, will be able to send pictures cause I'm stuck on it, to other users.
Right now the image is sent to the web service via SOAP with type xsd:base64binary. The user take a picture and the byte array with data is converted to base64 before sending it in this way:
String img;
....
#Override
public void onPictureTaken(byte[] data, Camera camera) {
img = Base64.encodeToString(data, Base64.NO_WRAP);
}
In the server side, php stores img string in a mysql BLOB column.
When another user ask for the picture, the server retrieves the data from mysql in a stdClass, not only the image, also id, owner, etc... and encapsulate all this data into a JSON string with the php function json_encode. The return type for this in the WSDL file is xsd:string. Back in Android what I do is:
JSONArray array = new JSONArray(response);
JSONObject row;
String imgStr;
byte[] img;
for (int i = 0; i < array.length(); i++) {
row = array.getJSONObject(i);
...
imgStr = row.getString("image");
...
}
if (!TextUtils.isEmpty(imgStr)) {
img = Base64.decode(imgStr, Base64.NO_WRAP);
}
//Insert byte[] in android SQLite
dao.insert(id, owner, img);
The table column type in SQLite is BLOB as well. The problem comes up when I get the image from SQLite and try to convert it to Bitmap object. The code for this:
...
byte[] img = cursor.getBlob(cursor.getColumnIndex(DB.M_IMG));
Bitmap bmp = BitmapFactory.decodeByteArray(img, 0, img.length);
...
The img byte array seems to be alright but bmp is always null...
Some tests I've done are getting the base64 string on the image owner device before sending it and passing it to bitmap with good results, that's why I think my problem has something to do with encoding or addition of characters by json or php, I don't know...
UPDATE: If I hardcoded the base64 string from the mysql database, no bitmap is created, if I do the same with the base64 string generated in the moment I take the picture then it works.
What am I doing wrong?
After a couple of days with this problem, I have the answer, it was a MySQL issue.
Apparently MySQL BLOB type can just store up to 64Kb (a clue to find the bug is that all images take up the same space of 64 Kb...The aswer was there all along but I couldn't see it...). So the SOLUTION, in my case, has been changing BLOB type in MySQL by LONGBLOB...
Thank you all for your time.
Though I'm still thinking over this, something struck me: why use so much, when you can simply use HttpClient, cookie and retrieve image(s) instead of converting to & fro.
Also if possible, storing Blob is not highly recommended unless your picture size is small. To me, some design changes would make whole code (server & phone) lot more manageable.
Related
Right now, I'm using an ASYNC task to load data. In current case, php echoes the complete JSON, and then android reads the whole string and display it. Problem that I'm facing here is that, php takes time to echo the full data.Php does echo one entry in 2 sec. What I want is that, for my android device to read the response as it is coming, dont wait for the JSON to complete but read it as it is coming and display. Here is what the current code looks like
PHP:
<?php
while(entry!=0){
data[] = processentry(entry);//will take 1-2 secs to process a single entry
entry--;
}
echo json_encode(data);
?>
Android side:
URLConnection con = new URL("someURL").openConnection();
con.setDoOutput(true);
OutputWriter out = new OutputWriter(con.getOutputSream());
out.write(/* post params */);
out.close();
BufferedReader br = new BufferedReader(new InputReader(con.getInputStream));
while( (tmp = br.readline()) != null)
decodedStr += tmp;
decodedStr contained the complete json which can then be read by android device
I want PHP to echo in the while loop itself and let the android read as the data is recieved.
Any suggestions?
You have to set timeout once php finish it task you have to set timeout on android side
int ConnectTimeout=15000;
int ReadTimeout=15000;
con.setReadTimeout(ReadTimeout);
con.setConnectTimeout(ConnectTimeout);
I have list.php file from my server it gives me like 20 lines of file names
how can I put each file name separately inside ListView in Android.
2017-05-11_15-03-14-70-channel1-projecttsd2013-1618032742.3gpp
2017-05-11_15-15-39-58-channel1-projecttsd2013-1618032742.3gpp
2017-05-11_15-15-39-59-channel1-projecttsd2013-1949843892.3gpp
2017-05-11_15-15-39-60-channel1-projecttsd2013223240350.3gpp
2017-05-11_15-15-39-60-channel1-projecttsd2013451577137.3gpp
2017-05-11_15-23-32-25-channel1-projecttsd2013-1618032742.3gpp
2017-05-11_15-30-00-39-channel1-projecttsd2013-1618032742.3gpp
2017-05-11_15-30-46-53-channel1-projecttsd2013-1949843892.3gpp
2017-05-11_16-46-16-37-channel1-projecttsd2013-1396509740.3gpp
2017-05-11_16-55-39-56-channel1-projecttsd2013-1396509740.3gpp
2017-05-11_17-00-10-317-channel1-rafogasparyan92086898.3gpp
2017-05-11_17-32-30-48-channel1-projecttsd2013-1396509740.3gpp
2017-05-11_17-34-26-97-channel1-projecttsd2013-1396509740.3gpp
2017-05-11_17-36-50-91-channel1-projecttsd2013-1396509740.3gpp
2017-05-11_17-41-30-74-channel1-armtab17-1593149344.3gpp
2017-05-11_18-07-10-93-channel1-projecttsd2013-1396509740.3gpp
2017-05-11_18-09-23-35-channel1-projecttsd20131261788243.3gpp
2017-05-12_14-22-33-17-channel1--518666646.3gpp
2017-05-12_14-58-01-58-channel1-projecttsd2013-518666646.3gpp
2017-05-12_15-01-15-43-channel1-projecttsd20131215499264.3gpp
2017-05-12_15-07-36-54-channel1-projecttsd2013671830229.3gpp
2017-05-12_15-08-25-06-channel1-null125424439.3gpp
2017-05-12_15-08-33-18-channel1-null-431222664.3gpp
2017-05-12_15-09-01-82-channel1-null1563152754.3gpp
2017-05-12_15-09-29-24-channel1-null-972865152.3gpp
2017-05-12_15-25-08-04-channel1-projecttsd2013-518666646.3gpp
hel.3gpp
hello.3gpp
IMG_20100128_192814.jpg
sound.3gpp
sound1.3gpp
test.3gpp
Is it possible those are the names from http://ip/android/list.php shows in the browser?
Well I guess you have String which you have to make List<String>.
So you can simply use String.split() method.
String example = "2017-05-11_15-03-14-70-channel1-projecttsd2013-1618032742.3gpp
2017-05-11_15-15-39-58-channel1-projecttsd2013-1618032742.3gpp
2017-05-11_15-15-39-59-channel1-projecttsd2013-1949843892.3gpp";
String lines[] = example.split("\\r?\\n");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, lines);
listView.setAdapter(adapter);
UPDATE
In case of "a<br/>b<br/>" just change split to this line
String lines[] = example.split("</br>");
I assume you get a string from your PHP srcipt lets call it requestStr.
String[] lines = requestStr.split("\\r?\\n");
Now you have your array you can implement an adapter like this https://stackoverflow.com/a/43893273/3289338 and give the array as parameters
You just set this adapter to your listView and it's over
It's really basic, if this is for an app in production I would use a better implementation of the Adapter with custom views and ViewHolder pattern
And just for information if not already the case when you use the network to request your php script, you have to do this in an other thread than the UI-thread How to fix android.os.NetworkOnMainThreadException?
I've got a Minecraft Software written in C# that I want to send a heartbeat to my site. I've got the way to send the beat already written.
if (Server.Uri == null) return;
string uri = "http://GemsCraft.comli.com/Heartbeat.php";
// create a request
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
// turn request string into a byte stream
byte[] postBytes = Encoding.ASCII.GetBytes(string.Format("ServerName={0}&Url={1}&Players={2}&MaxPlayers={3}&Uptime={4}",
Uri.EscapeDataString(ConfigKey.ServerName.GetString()),
Server.Uri,
Server.Players.Length,
ConfigKey.MaxPlayers.GetInt(),
DateTime.UtcNow.Subtract(Server.StartTime).TotalMinutes));
request.ContentType = "application/x-www-form-urlencoded";
request.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore);
request.ContentLength = postBytes.Length;
request.Timeout = 5000;
Stream requestStream = request.GetRequestStream();
// send it
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Flush();
requestStream.Close();
/* try
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Logger.LogToConsole(new StreamReader(response.GetResponseStream()).ReadToEnd());
Logger.LogToConsole(response.StatusCode + "\n");
}
catch (Exception ex)
{
Logger.LogToConsole("" + ex);
}*/
}
Now, I want to be able to retrieve the heartbeat in PHP, upload it to the SQL database, and then display each user's server in a table that will be displayed on the webpage
How do I do this?
portforwardpodcast's answer isn't very well-suited for your purposes, here's a process for you to ponder
Server accesses the following page: heartbeat.php?port=25565&maxplayers=25&players=2&name=Cheese_Pizza_Palace
Your PHP script will then do the following...
Go through each value, making sure they're all the types you want them to be (integers/strings)
Connect to the database
Update the server in the database if it already exists, create it if it doesn't
Return some value so the server knows that it completed successfully.
And to display the servers
Fetch all 'active' servers
Loop through them and display each one.
Things you'll need to figure out:
How to determine uptime
How to determine "active" servers
How to update/create MySQL entries
How to (properly) connect to a database. I would suggest using PDO since you're using PHP. It's a bit difficult to learn, but it's much more secure than writing the queries directly.
How to loop through all the GET variables.
Good hunting!
I would create a simple php page accept a get variable. something like www.site.com/beat.php?lasttime=123456&serverid=1 where the number us the unix timestamp. Then you need to re-work your c# to do a simple get request on a website. Finally your php should insert into a mysql table with a column for id, timestamp, server_id etc.
First you need to pull the data from the request. The $_REQUEST variable in php is nice because it works for both GET and POST:
http://php.net/manual/en/reserved.variables.request.php
Start out by var_dump or echo the fields you want. Once you can get the needed data into variables you are done with the first part. For the next part you need to create a database and table in MySQL. The best tool for this is phpmyadmin. If you have a host like godaddy (or some others) you can get at this from the control panel. If not you may need to install upload the phpmyadmin files yourself. It's a pretty simple tool to use:
http://www.youtube.com/watch?v=xxQSFHADUIY
Once your database has the correct columns, you need to insert the data from your php file. This page should help:
http://www.w3schools.com/php/php_mysql_insert.asp
I'm looking for an efficient and secure way to store small amount of user data like a line of text, for an indefinite period of time.
The scenario: One client 'A' sends some data to another client 'B' , asynchronously via a server 'S'. For simplicity, consider the data to be a single line of text. Now, this data would be delivered to client 'B' by server 'S' , only when B asks for it. So until that time Server 'S' has to store this data.
For a simple demo, I implemented it very crudely as follows: Client 'A' does a POST request with XMLHttpRequest, sending the text to 'S' as follows
xhr.open("POST",url+"?sentText=text"); //url points to a php file on S
xhr.send();
The PHP code then saves the received text to a file as follows:
<?php
$selected = $_GET["sentText"];
$writefile = "text.txt";
$fh = fopen($writefile,'w');
fwrite($fh,$selected);
fclose($fh);
?>
Later, after any amount of time, B asks for the text in this file,using BufferedInputStream as follows:
URL fileurl = new URL("url/text.txt");
BufferedReader in = new BufferedReader(new InputStreamReader(fileurl.openStream()));
while((tmpReceived = in.readLine())!=null){
received = tmpReceived;
}
This demo works properly, but this is just a demo. However, if this were to be a full scale real world application with millions of users, how would I implement the following:The part where server S stores the text. Obviously, I can't save the text as plain text in a file, as it would breach my users' privacy. And it would also be ineffecient when there are millions of users. How do commercial services like Dropbox achieve this?
To keep things simple, I just need to know how to do this for text, then I can extrapolate to other types possibly.
Thanks a lot!
I'm a newbie with GWT and PHP, and after reading some tutorials it's not clear for me how to efficiently exchange data between the GWT frontend and PHP backend. I successfully followed the Google tutorials where is suggested to use the RequestBuilder class to get data from PHP.
But when I need to save the work done in GWT, how to efficiently pass the data to PHP?
It's not clear for me how to use the RequestBuilder for this task.
The solution that I found for now is
RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, URL.encode(url));
builder.setHeader("Content-Type", "application/json");
try {
Request request = builder.sendRequest("{\"done\":false,\"description\":\"Some text\",\"priority\":0}", new RequestCallback() {...
and in PHP side
$arr = json_decode(file_get_contents("php://input"),true);
$done = (int)$arr['done'];
$description = $arr['description'];
$priority = $arr['priority'];
mysql_query("INSERT INTO Tasks (done, description, priority)
VALUES ($done, '$description', $priority)");
Is this the best approach? Have someone found a working example in the web? Every opinion is welcome...
I think, working with JSON when interacting with non-Java servers is fine. You can build the JSON strings on the client side in a safer way by using the JSON module:
In your .gwt.xml file add
<inherits name='com.google.gwt.json.JSON'/>
Then you can construct your example string like
final JSONObject jsonObject = new JSONObject();
jsonObject.put("done", JSONBoolean.getInstance(false));
jsonObject.put("description", new JSONString("Some text"));
jsonObject.put("priority", new JSONNumber(0));
final String jsonString = jsonObject.toString();