Sending a response from PHP to an Android/Java mobile app? - java

I currently have a piece of code in my Android application that picks up the devices IMEI and sends that IMEI as a parameter to a PHP script that is hosted on the Internet.
The PHP script then takes the IMEI parameter and checks a file to see if the IMEI exists in the file, if it does I want to be able to let my Android application know that the IMEI exists. So essentially I just want to be able to return True to my application.
Is this possible using PHP?
Here is my code so far:
Android/Java
//Test HTTP Get for PHP
public void executeHttpGet() throws Exception {
BufferedReader in = null;
try {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI("http://testsite.com/" +
"imei_script.php?imei=" + telManager.getDeviceId()
));
HttpResponse response = client.execute(request);
in = new BufferedReader
(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String page = sb.toString();
System.out.println(page);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The above sends the IMEI as a parameter to the PHP script which picks it up successfully and runs a check against the file successfully, however I neeed to then be able to send a positive response back from the PHP script if the IMEI matches one in the file.
Here is the PHP:
<?php
// to return plain text
header("Content-Type: plain/text");
$imei = $_GET["imei"];
$file=fopen("imei.txt","r") or exit("Unable to open file!");
while(!feof($file))
{
if ($imei==chop(fgets($file)))
echo "True";
}
fclose($file);
?>
So instead of echo True I want to be able to let my application know that the IMEI was found, is this possible and if so what should I be using to achieve it?

this is good stuff! actually, you're nearly there. your php shouldn't change, your java should! you just need to check the result of the response inside your java code. redeclare your java method as
public String executeHttpGet() {
then, let this method return the variable page.
now you can create a helper method somewhere. if you put it in the same class as executeHttpGet, it will look like this:
public boolean imeiIsKnown(){
return executeHttpGet().equals("True");
}
now you can call this method to find out if your imei is known in your php backend.

I'm not sure is it good for you or not - but you can use headers. If the IMEI was found you can send header("Status: HTTP/1.1 200 OK") otherwise send header("Status: 404 Not Found").
And then you should check response status in your application.

your code is basically sound, all you need to do is tweak it up a bit. i mixed and matched the answers above, because i needed to accomplish exactly what you were trying to. i created a database, instead of checking txt files.
CREATE TABLE IF NOT EXISTS `user_device` (
`Id_User_Device` int(11) NOT NULL auto_increment,
`Nr_User_Device` varchar(60) collate utf8_bin NOT NULL,
`Ic_User_Device_Satus` int(11) NOT NULL default '1',
PRIMARY KEY (`Id_User_Device`),
KEY `Nr_User_Device` (`Nr_User_Device`,`Ic_User_Device_Satus`)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=20 ;
the java android code would be (dont forget to create the proper adjustements in the main.xml layout file, inserting 2 elements to a classical helloworld screen:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class ZdeltestEMEIActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DeviceUuidFactory deviceUuidFactory = new DeviceUuidFactory(this);
String deviceUuid = deviceUuidFactory.getDeviceUuid().toString();
Log.d("tgpost",deviceUuid);
try {
String webPostAnswer = deviceIdCheck(deviceUuid);
if (webPostAnswer != null) {
TextView tv1 = (TextView) findViewById(R.id.textdisplay01);
TextView tv2 = (TextView) findViewById(R.id.textdisplay02);
tv1.setText(webPostAnswer);
tv2.setText(deviceUuid);
Log.d("tgpost", "okok "+webPostAnswer);
} else {
Log.d("tgpost", "nono empty");
}
} catch (Exception e) {
// TODO Auto-generated catch block
Log.i("tgpost", "exc " + e.getMessage());
Log.i("tgpost", e.toString());
Log.e("tgpost", e.getStackTrace().toString());
e.printStackTrace();
}
}
public String deviceIdCheck(String deviceUuidIn) throws Exception {
boolean flagOK = false;
BufferedReader in = null;
try {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
Log.v("tgpost", "okok");
//"imei_script.php?deviceId="; + telManager.getDeviceId()
request.setURI(new URI("http://www.you.net/" +
"deviceIdCheck.php?deviceId=" + deviceUuidIn
));
HttpResponse response = client.execute(request);
Log.d("tgpost", "php answered> "+response);
in = new BufferedReader
(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String page = sb.toString();
Log.d("tgpost", "php answered HUMAN> "+page);
return page;
} catch (Exception e) {
return "problems with connection "+e.getMessage();
}
}
}
with an addtional class
import android.content.Context;
import android.content.SharedPreferences;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import java.io.UnsupportedEncodingException;
import java.util.UUID;
public class DeviceUuidFactory {
protected static final String PREFS_FILE = "device_id.xml";
protected static final String PREFS_DEVICE_ID = "device_id";
protected static UUID uuid;
public DeviceUuidFactory(Context context) {
if( uuid ==null ) {
synchronized (DeviceUuidFactory.class) {
if( uuid == null) {
final SharedPreferences prefs = context.getSharedPreferences( PREFS_FILE, 0);
final String id = prefs.getString(PREFS_DEVICE_ID, null );
if (id != null) {
// Use the ids previously computed and stored in the prefs file
uuid = UUID.fromString(id);
} else {
final String androidId = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
// Use the Android ID unless it's broken, in which case fallback on deviceId,
// unless it's not available, then fallback on a random number which we store
// to a prefs file
try {
if (!"9774d56d682e549c".equals(androidId)) {
uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8"));
} else {
final String deviceId = ((TelephonyManager) context.getSystemService( Context.TELEPHONY_SERVICE )).getDeviceId();
uuid = deviceId!=null ? UUID.nameUUIDFromBytes(deviceId.getBytes("utf8")) : UUID.randomUUID();
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
// Write the value out to the prefs file
prefs.edit().putString(PREFS_DEVICE_ID, uuid.toString() ).commit();
}
}
}
}
}
/**
* Returns a unique UUID for the current android device. As with all UUIDs, this unique ID is "very highly likely"
* to be unique across all Android devices. Much more so than ANDROID_ID is.
*
* The UUID is generated by using ANDROID_ID as the base key if appropriate, falling back on
* TelephonyManager.getDeviceID() if ANDROID_ID is known to be incorrect, and finally falling back
* on a random UUID that's persisted to SharedPreferences if getDeviceID() does not return a
* usable value.
*
* In some rare circumstances, this ID may change. In particular, if the device is factory reset a new device ID
* may be generated. In addition, if a user upgrades their phone from certain buggy implementations of Android 2.2
* to a newer, non-buggy version of Android, the device ID may change. Or, if a user uninstalls your app on
* a device that has neither a proper Android ID nor a Device ID, this ID may change on reinstallation.
*
* Note that if the code falls back on using TelephonyManager.getDeviceId(), the resulting ID will NOT
* change after a factory reset. Something to be aware of.
*
* Works around a bug in Android 2.2 for many devices when using ANDROID_ID directly.
*
* #see http://code.google.com/p/android/issues/detail?id=10603
*
* #return a UUID that may be used to uniquely identify your device for most purposes.
*/
public UUID getDeviceUuid() {
return uuid;
}
}
on the php side:
<?php
// to return plain text
// header("Content-Type: plain/text");
include('/home/public_html/ConnStrDB.php');
$deviceId = $_GET["deviceId"];
$sql = "SELECT Nr_User_Device FROM user_device WHERE Nr_User_Device = '".$deviceId."'";
$result = mysql_query($sql);
if ($result) {
$row = mysql_fetch_array($result);
if ($row[0]) {$deviceIdFile = $row[0];} else {$deviceIdFile = "device not found";}
} else {
$deviceIdFile = "no check was made, empty set";
}
echo $_GET["deviceId"]." ".$deviceIdFile;
?>
and (so that you dont have to insert the numbers manually (just change the php fileName in the submit):
<?php
// to return plain text
// header("Content-Type: plain/text");
include('/home/public_html/ConnStrDB.php');
$deviceId = $_GET["deviceId"];
$sql = "SELECT Nr_User_Device, Ic_User_Device_Status FROM user_device WHERE Nr_User_Device = ".$deviceId;
$sql = "INSERT INTO user_device (Nr_User_Device) VALUES ('".$deviceId."')";
$result = mysql_query($sql);
if ($result) {
$deviceIdFile = "device inserted";
} else {
$deviceIdFile = "not inserted";
}
echo $_GET["deviceId"]." ".$deviceIdFile;
?>
if succesful, your mobile screen will display the imei 3 times (the one on the device, the one received in php and the one retrieved on the database).
ConnStrDB.php is a file that contains your complete connection to MySQL database.
if you reply with long text, the android application will receive it, as well as the verbose version of any php warning. if you dont need json, you can answer any xml thru a php echo. thanx for your question, very useful! and thanx for the EXCELLENT answers!

Related

How can I update custom properties in alfresco workflow task using only Java?

First, I want to say thanks to everyone that took their time to help me figure this out because I was searching for more than a week for a solution to my problem. Here it is:
My goal is to start a custom workflow in Alfresco Community 5.2 and to set some custom properties in the first task trough a web script using only the Public Java API. My class is extending AbstractWebScript. Currently I have success with starting the workflow and setting properties like bpm:workflowDescription, but I'm not able to set my custom properties in the tasks.
Here is the code:
public class StartWorkflow extends AbstractWebScript {
/**
* The Alfresco Service Registry that gives access to all public content services in Alfresco.
*/
private ServiceRegistry serviceRegistry;
public void setServiceRegistry(ServiceRegistry serviceRegistry) {
this.serviceRegistry = serviceRegistry;
}
#Override
public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException {
// Create JSON object for the response
JSONObject obj = new JSONObject();
try {
// Check if parameter defName is present in the request
String wfDefFromReq = req.getParameter("defName");
if (wfDefFromReq == null) {
obj.put("resultCode", "1 (Error)");
obj.put("errorMessage", "Parameter defName not found.");
return;
}
// Get the WFL Service
WorkflowService workflowService = serviceRegistry.getWorkflowService();
// Build WFL Definition name
String wfDefName = "activiti$" + wfDefFromReq;
// Get WorkflowDefinition object
WorkflowDefinition wfDef = workflowService.getDefinitionByName(wfDefName);
// Check if such WorkflowDefinition exists
if (wfDef == null) {
obj.put("resultCode", "1 (Error)");
obj.put("errorMessage", "No workflow definition found for defName = " + wfDefName);
return;
}
// Get parameters from the request
Content reqContent = req.getContent();
if (reqContent == null) {
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Missing request body.");
}
String content;
content = reqContent.getContent();
if (content.isEmpty()) {
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Content is empty");
}
JSONTokener jsonTokener = new JSONTokener(content);
JSONObject json = new JSONObject(jsonTokener);
// Set the workflow description
Map<QName, Serializable> params = new HashMap();
params.put(WorkflowModel.PROP_WORKFLOW_DESCRIPTION, "Workflow started from JAVA API");
// Start the workflow
WorkflowPath wfPath = workflowService.startWorkflow(wfDef.getId(), params);
// Get params from the POST request
Map<QName, Serializable> reqParams = new HashMap();
Iterator<String> i = json.keys();
while (i.hasNext()) {
String paramName = i.next();
QName qName = QName.createQName(paramName);
String value = json.getString(qName.getLocalName());
reqParams.put(qName, value);
}
// Try to update the task properties
// Get the next active task which contains the properties to update
WorkflowTask wfTask = workflowService.getTasksForWorkflowPath(wfPath.getId()).get(0);
// Update properties
WorkflowTask updatedTask = workflowService.updateTask(wfTask.getId(), reqParams, null, null);
obj.put("resultCode", "0 (Success)");
obj.put("workflowId", wfPath.getId());
} catch (JSONException e) {
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
e.getLocalizedMessage());
} catch (IOException ioe) {
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
"Error when parsing the request.",
ioe);
} finally {
// build a JSON string and send it back
String jsonString = obj.toString();
res.getWriter().write(jsonString);
}
}
}
Here is how I call the webscript:
curl -v -uadmin:admin -X POST -d #postParams.json localhost:8080/alfresco/s/workflow/startJava?defName=nameOfTheWFLDefinition -H "Content-Type:application/json"
In postParams.json file I have the required pairs for property/value which I need to update:
{
"cmprop:propOne" : "Value 1",
"cmprop:propTwo" : "Value 2",
"cmprop:propThree" : "Value 3"
}
The workflow is started, bpm:workflowDescription is set correctly, but the properties in the task are not visible to be set.
I made a JS script which I call when the workflow is started:
execution.setVariable('bpm_workflowDescription', 'Some String ' + execution.getVariable('cmprop:propOne'));
And actually the value for cmprop:propOne is used and the description is properly updated - which means that those properties are updated somewhere (on execution level maybe?) but I cannot figure out why they are not visible when I open the task.
I had success with starting the workflow and updating the properties using the JavaScript API with:
if (wfdef) {
// Get the params
wfparams = {};
if (jsonRequest) {
for ( var prop in jsonRequest) {
wfparams[prop] = jsonRequest[prop];
}
}
wfpackage = workflow.createPackage();
wfpath = wfdef.startWorkflow(wfpackage, wfparams);
The problem is that I only want to use the public Java API, please help.
Thanks!
Do you set your variables locally in your tasks? From what I see, it seems that you define your variables at the execution level, but not at the state level. If you take a look at the ootb adhoc.bpmn20.xml file (https://github.com/Activiti/Activiti-Designer/blob/master/org.activiti.designer.eclipse/src/main/resources/templates/adhoc.bpmn20.xml), you can notice an event listener that sets the variable locally:
<extensionElements>
<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string>
if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
</activiti:string>
</activiti:field>
</activiti:taskListener>
</extensionElements>
Usually, I just try to import all tasks for my custom model prefix. So for you, it should look like that:
import java.util.Set;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.DelegateTask;
import org.apache.log4j.Logger;
public class ImportVariables extends AbstractTaskListener {
private Logger logger = Logger.getLogger(ImportVariables.class);
#Override
public void notify(DelegateTask task) {
logger.debug("Inside ImportVariables.notify()");
logger.debug("Task ID:" + task.getId());
logger.debug("Task name:" + task.getName());
logger.debug("Task proc ID:" + task.getProcessInstanceId());
logger.debug("Task def key:" + task.getTaskDefinitionKey());
DelegateExecution execution = task.getExecution();
Set<String> executionVariables = execution.getVariableNamesLocal();
for (String variableName : executionVariables) {
// If the variable starts by "cmprop_"
if (variableName.startsWith("cmprop_")) {
// Publish it at the task level
task.setVariableLocal(variableName, execution.getVariableLocal(variableName));
}
}
}
}

Not able to insert record to MySQL, but showing no error

Task: sync records from android sqlite to mysql.
Problem: mysql/php is not inserting data into my table in mysql. But no errors were shown.
DB_Connect.php:
<?php
class DB_Connect {
// constructor
function __construct(){
}
// destructor
function __destruct(){
}
// connecting to database
public function connect(){
require_once 'config.php'; // defined DB_HOST,DB_USER,DB_PASSWORD here
// connecting to mysql
$con = mysqli_connect(DB_HOST,DB_USER,DB_PASSWORD);
// selecting database
mysqli_select_db($con,"heart");
// return database handler
return $con;
}
// closing database connection
public function close(){
mysqli_close($this->connect());
}
}
?>
DB_Operations.php:
<?php
class DB_Operations {
private $db;
public $last_id;
public $error;
public $error_conn;
public $error_no;
// constructor
function __construct(){
require 'DB_Connect.php';
$this->db = new DB_Connect();
$this->db->connect();
}
// destructor
function __destruct(){
}
// Storing new doctor
public function storeDoctor($_id,$firstName,$lastName,$specialization,$licenseNumber,$clinicAddress,$email,$contactNum,$username,$password,$aboutMe){
$result = mysqli_query($this->db->connect(),"INSERT INTO doctor(_id,first_name,last_name,specialization,license_number,clinic_address,email,contact_number,username,password,about_me) VALUES('$_id','$firstName','$lastName','$specialization','$licenseNumber','$clinicAddress','$email','$contactNum','$username','$password','$aboutMe')");
if (mysqli_connect_errno()){
$this->error_conn = mysqli_connect_error();
}
if(!$result){
if(mysqli_errno($this->db->connect()) == 1062){
// duplicate key - primary key violation
return true;
} else{
// for other reasons
$this->error = mysqli_error($this->db->connect());
$this->error_no = mysqli_errno($this->db->connect());
return false;
}
} else{
$this->last_id = mysqli_insert_id($this->db->connect());
return true;
}
}
// getters
public function getError(){
return $this->error;
}
public function getError_no(){
return $this->error_no;
}
public function getError_conn(){
return $this->error_conn;
}
...
insertuser.php:
<?php
include 'DB_Operations.php';
// create object for DB_Operations class
$db = new DB_Operations();
// get JSON posted by Android Application
$json = $_POST["doctorsJSON"];
// remove slashes
if(get_magic_quotes_gpc()){
$json = stripslashes($json);
}
// decode JSON into Array
$data = json_decode($json);
// util arrays to create response JSON
$a = array();
$b = array();
// loop through an array and insert data read from JSON into MySQL DB
for($i=0; $i<count($data); $i++){
// store doctor into MySQL DB
$res = $db->storeDoctor($data[$i]->_id,$data[$i]->first_name,$data[$i]->last_name,$data[$i]->specialization,$data[$i]->license_number,$data[$i]->clinic_address,$data[$i]->email,$data[$i]->contact_number,$data[$i]->username,$data[$i]->password,$data[$i]->about_me);
// based on insertion, create JSON response
$b["local_id"] = $data[$i]->_id;
if($res){
$b["server_id"] = $db->last_id;
$b["status"] = 'yes';
}else{
$b["status"] = 'no';
$b["err_no"] = $db->getError_no();
$b["error"] = $db->getError();
$b["error_conn"] = $db->getError_conn();
}
array_push($a,$b);
}
// post JSON response back to Android Application
echo json_encode($a);
?>
I have a function in java which syncs the sqlite data to mysql:
public void syncSQLiteToMySQL(Context context,String selectQuery){
dop = new DatabaseOperations(context);
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
ArrayList<HashMap<String,String>> doctorList = new ArrayList<HashMap<String,String>>();
doctorList = dop.getAllDoctors();
if(doctorList.size()!=0){
String json = dop.composeJSONfromSQLite(selectQuery);
params.put("doctorsJSON", json);
Log.i("json to pass", json);
client.post("http://"+ip+":8080/changed_server_name/insertuser.php",params ,new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
Log.e("client response",response);
try {
JSONArray arr = new JSONArray(response);
for(int i=0; i<arr.length();i++){
JSONObject obj = (JSONObject)arr.get(i);
// did something with json response here
dop.updateSyncStatus(obj.getString("local_id"),obj.getString("status"));
}
message = "DB Sync completed!";
} catch (JSONException e) {
message = "Error Occured [Server's JSON response might be invalid]!";
Log.e("JSONException",e.getMessage());
}
}
#Override
public void onFailure(int statusCode, Throwable error, String content) {
if(statusCode == 404){
message = "Requested resource not found";
}else if(statusCode == 500){
message = "Something went wrong at server end";
}else{
message = "Unexpected Error occcured! [Most common Error: Device might not be connected to Internet]";
Log.e("sync post failure",error.toString());
}
}
});
}
}
So, here's the response:
[{"local_id":"0","status":"no","err_no":0,"error":"","error_conn":null}]
The JSON works fine. No problem with it. I have checked and it passes correct data. Just the PHP and MySQL side. Somehow, I couldn't find the error to this code. There is no error message, error number is 0, and there was no error in connecting to DB. But the query in storeDoctor() returns false. How could this be? I have been reading about this problem on this site and others, but I have not really found something that's close to my problem.
Please enlighten me. Your help would really be appreciated. Thanks in advance.
Edit: I also tried mysqli_ping($this->db->connect()); and it returns true which means the connection is okay. So, what really is this something that makes the query fail?
Did you try using error_reporting(E_ALL);
Also inside the constructor you used
$this->db->connect();
And then in the store you used
$result = mysqli_query($this->db->connect(),
Can you post the code for connect

Android - getting Google Places Photos and API calls

I wrote the method below in Spring to obtain a Google Places Photo this morning. The method is still buggy - 10 points for someone who can fix up the code - but it shows the gist of what I want to do:
#RequestMapping(method=RequestMethod.GET, value="/placedetails")
public BufferedImage PlaceDetails(#PathVariable String placeid) {
ArrayList<String> placePhotos = new ArrayList<>();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://maps.googleapis.com/maps/api/place/details/json?placeid="+placeid+"&key="+serverKey)
.build();
try {
//calling the GoogleAPI to get the PlaceDetails so that I can extract the photo_reference
Response response = client.newCall(request).execute();
//parsing the response with Jackson so that I can get the photo_reference
ObjectMapper m = new ObjectMapper();
JsonNode rootNode = m.readTree(response.body().string());
JsonNode resultNode = rootNode.get("result");
final JsonNode photoArrayNode = resultNode.get("photos");
if (photoArrayNode.isArray()) {
for (JsonNode photo: photoArrayNode) {
placePhotos.add(photo.get("photo_reference").textValue());
}
}
//calling the GoogleAPI again so that I can get the photoUrl
String photoUrl = String.format("https://maps.googleapis.com/maps/api/place/photo?maxwidth=%s&photoreference=%s&key=%s",
400,
placePhotos.get(0),
serverKey);
System.out.println(photoUrl);
//getting the actual photo
Request photoRequest = new Request.Builder().url(photoUrl).build();
Response photoResponse = client.newCall(photoRequest).execute();
if (!photoResponse.isSuccessful()) throw new IOException("Unexpected code " + response);
//returning the photo
return ImageIO.read(photoResponse.body().byteStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
I think to get an android app to display a Google Places picture, one would have to do the following:
Obtain the PlaceID first in Android. In my case, I obtained my PlaceID through an AutoCompleteTextView on my android app: (https://developers.google.com/places/android/autocomplete) (Call 1)
Then I call my method below. I call the Google Places API to get the Place Details (Call 2) and then once the details returns, I parse out the photo_reference using Jackson and call the Google Places API again to get the photo returned as a bitmap etc. (Call 3).
I'm making 3 calls to Google Places to return a Photo. When compared to the quota of 1000 calls a day, that is quite a significant amount of calls for getting 1 Photo.
Is there no other less way to get Photos without making so many calls?
I looked at this thread: How to get a picture of a place from google maps or places API
The person suggested that one uses panaramio instead which seems to be a really good option in the beginning but when I tested it out by typing in the example in my browser: http://www.panoramio.com/map/get_panoramas.php?set=public&from=0&to=20&minx=-33.868&miny=151.193&maxx=-33.864&maxy=151.197&size=medium&mapfilter=true, no photos were returned in the .php file.
I'm not sure if panaramio API still works?
Hi your problem is here
if (photoArrayNode.isArray()) {
for (JsonNode photo: photoArrayNode) {
placePhotos.add(photo.get("photo_reference").textValue());
}
Which should be
if (photoArrayNode.isArray()) {
for (JsonNode photo: photoArrayNode) {
placePhotos.add(photo.get("photo_reference").getString());
}
The photo_reference is a String value within the photo array element
Also, the below is unnecessary work:
//calling the GoogleAPI again so that I can get the photoUrl
String photoUrl = String.format("https://maps.googleapis.com/maps/api/place/photo?maxwidth=%s&photoreference=%s&key=%s",
There is no need to format the url string. The snippet below is part of the example I recommended below which answers your question specifically.
package in.wptrafficanalyzer.locationnearbyplacesphotos;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class PlaceJSONParser {
/** Receives a JSONObject and returns a list */
public Place[] parse(JSONObject jObject){
JSONArray jPlaces = null;
try {
/** Retrieves all the elements in the 'places' array */
jPlaces = jObject.getJSONArray("results");
} catch (JSONException e) {
e.printStackTrace();
}
/** Invoking getPlaces with the array of json object
* where each json object represent a place
*/
return getPlaces(jPlaces);
}
private Place[] getPlaces(JSONArray jPlaces){
int placesCount = jPlaces.length();
Place[] places = new Place[placesCount];
/** Taking each place, parses and adds to list object */
for(int i=0; i<placesCount;i++){
try {
/** Call getPlace with place JSON object to parse the place */
places[i] = getPlace((JSONObject)jPlaces.get(i));
} catch (JSONException e) {
e.printStackTrace();
}
}
return places;
}
/** Parsing the Place JSON object */
private Place getPlace(JSONObject jPlace){
Place place = new Place();
try {
// Extracting Place name, if available
if(!jPlace.isNull("name")){
place.mPlaceName = jPlace.getString("name");
}
// Extracting Place Vicinity, if available
if(!jPlace.isNull("vicinity")){
place.mVicinity = jPlace.getString("vicinity");
}
if(!jPlace.isNull("photos")){
JSONArray photos = jPlace.getJSONArray("photos");
place.mPhotos = new Photo[photos.length()];
for(int i=0;i<photos.length();i++){
place.mPhotos[i] = new Photo();
place.mPhotos[i].mWidth = ((JSONObject)photos.get(i)).getInt("width");
place.mPhotos[i].mHeight = ((JSONObject)photos.get(i)).getInt("height");
place.mPhotos[i].mPhotoReference = ((JSONObject)photos.get(i)).getString("photo_reference");
JSONArray attributions = ((JSONObject)photos.get(i)).getJSONArray("html_attributions");
place.mPhotos[i].mAttributions = new Attribution[attributions.length()];
for(int j=0;j<attributions.length();j++){
place.mPhotos[i].mAttributions[j] = new Attribution();
place.mPhotos[i].mAttributions[j].mHtmlAttribution = attributions.getString(j);
}
}
}
place.mLat = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lat");
place.mLng = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lng");
} catch (JSONException e) {
e.printStackTrace();
Log.d("EXCEPTION", e.toString());
}
return place;
}
}
For a complete example please see: the source code is available for download.
http://wptrafficanalyzer.in/blog/showing-nearby-places-with-photos-at-any-location-in-google-maps-android-api-v2/

how to fetch public data and images from flicker using java?

I am trying to get the Flickr data by using API key and secret key provided by flickr . I have written a java code for it.
`package com.flickr.project;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import com.aetrion.flickr.Flickr;
import com.aetrion.flickr.FlickrException;
import com.aetrion.flickr.REST;
import com.aetrion.flickr.auth.Permission;
import com.aetrion.flickr.photos.SearchParameters;
import com.aetrion.flickr.photos.PhotoList;
import com.aetrion.flickr.photos.PhotosInterface;
import com.aetrion.flickr.photos.Photo;
import com.flickr4java.flickr.Auth;
import com.flickr4java.flickr.RequestContext;
public class SampleProgram{
public static void main(String[] args) {
try {
searchImages();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void searchImages() {
// Search photos with tag keywords and get result
try{
//Set api key
String key="";
String svr="www.flickr.com";
String secret="";
RequestContext requestContext = RequestContext.getRequestContext();
Auth auth = new Auth();
auth.setPermission(Permission.READ);
auth.setToken("");
auth.setTokenSecret("");
requestContext.setAuth(auth);
REST rest=new REST();
rest.setHost(svr);
//initialize Flickr object with key and rest
Flickr flickr=new Flickr(key,secret,rest);
Flickr.debugRequest = false;
Flickr.debugStream = false;
Flickr.debugStream=false;
//initialize SearchParameter object, this object stores the search keyword
SearchParameters searchParams=new SearchParameters();
searchParams.setSort(SearchParameters.INTERESTINGNESS_DESC);
//Create tag keyword array
String[] tags=new String[]{"Dog","Doberman"};
searchParams.setTags(tags);
//Initialize PhotosInterface object
PhotosInterface photosInterface=flickr.getPhotosInterface();
//Execute search with entered tags
// PhotoList photoList=null;
PhotoList photoList=photosInterface.search(searchParams,20,1);
System.out.println("here");
//get search result and fetch the photo object and get small square imag's url
if(photoList!=null){
//Get search result and check the size of photo result
for(int i=0;i<photoList.size();i++){
//get photo object
Photo photo=(Photo)photoList.get(i);
//Get small square url photo
StringBuffer strBuf=new StringBuffer();
strBuf.append("<a href=\"\">");
strBuf.append("<img border=\"0\" src=\""+photo.getSmallSquareUrl()+"\">");
strBuf.append("</a>\n");
// ....
}
}
}catch(Exception e){
e.printStackTrace();
}
}
public void userAuthentication(){
/*InputStream in = null;
try {
in = getClass().getResourceAsStream("/setup.properties");
// properties = new Properties();
// properties.load(in);
} finally {
IOUtilities.close(in);
}
f = new Flickr(properties.getProperty("apiKey"), properties.getProperty("secret"), new REST());
requestContext = RequestContext.getRequestContext();
Auth auth = new Auth();
auth.setPermission(Permission.READ);
auth.setToken(properties.getProperty("token"));
auth.setTokenSecret(properties.getProperty("tokensecret"));
requestContext.setAuth(auth);
Flickr.debugRequest = false;
Flickr.debugStream = false;*/
}
} `
I need to fetch all data including images from flickr using the key words i mentioned in the program.
From the look of things, Photo has several methods like the following:
"getSmallSquareAsInputStream" - This returns an input stream, this can be used to fetch the image data.
The full API's list for Photo class is available here

GWT and REST (jax-rs)

I have a project where you can ask for resources that are served by jax-rs in the json format. Everything works properly in the browser when I query the rest URL the json appears.
Now I want my GWT project to request those resources and process them and show them in my interface. The simplest way I found to do so is using a request builder and an overlay. Code is lower. The problem is, it seems when the code is running it never goes into the actual RequestCallback(). The status string is never changed. I thought it could be a SOP so I added the <add-linker name="xs"/> but still doesn't work. Any ideal?
package com.workoutcell.client;
//import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.http.client.*;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
/**
*
* #author
*/
public class RestToInfoSession{
String queryReturn = null;
JsArray<InfoJSO> arrayOfInfo = null;
String host = "http://localhost:8080/mysite";
String restModule = "/calendar/getinfo";
String id = null;
String year = null;
String month = null;
String status = "Not Initialized";
public RestToInfoSession(String id, String year, String month){
this.id =id;
this.year = year;
this.month = month;
String url = host + restModule + "/"+this.id + "/"+this.year + "/"+this.month;
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);
try {
status = "Initialized at Url " + builder.getUrl();
Request request = builder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception) {
// Couldn't connect to server (could be timeout, SOP violation, etc.)
status = "Error on connecting to Server";
}
public void onResponseReceived(Request request, Response response) {
if (200 == response.getStatusCode()) {
// arrayOfInfo = jsonToJsArray(response.getText());
status = "JSON has been Fetched. Result is:" + response.getText();
} else if(0 == response.getStatusCode()) {
status = "Error is 0";
} else {
status = "Error in JSON Request:" + response.getStatusCode();
//response.getStatusText();
}
}
});
} catch (RequestException ex) {
status = "Error in Request Builder Startup";
}
}
//get an jso object in array
private final native JsArray<InfoJSO> jsonToJsArray(String json) /*-{
return eval(json);
}-*/;
public JsArray<InfoJSO> getInfoArray (){
return arrayOfInfo;
}
}
UPDATE: My problem is the same as Referring to a non-final variable data inside an inner class . I wasn't aware of asynchronous calls working mechanism. I still don't know how to pass my response.getText() to update a label that isn't part of my RestToInfoSession class any ideas?
Consider using the RestyGWT project. It will make calling JAXRS JSON resources as easy as using GWT-RPC. Plus you can typically reuse the same request response DTOs from the server side on the client side.
I have put a timer that checks every 1000ms if my json string has updated from null to the xhttp requested data. This works, but I got a feeling there is a more elegant way of resolving this problem.

Categories