Google Fused Location Api, onLocationChanged firing two times in one interval - fusedlocationproviderapi

I am using Fused location API to track the location details, but onLocationChanged firing two times in one interval. please suggest any solution for this issue.
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
public void onConnected(Bundle bundle) {
Log.d(TAG, "onConnected - isConnected ...............: " + mGoogleApiClient.isConnected());
startLocationUpdates();
}
protected void startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
Log.d(TAG, "Location update started ..............: ");
}
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "Firing onLocationChanged..............................................");
}

Related

BroadcastProcessFunction Processing Delay

I'm fairly new to Flink and would be grateful for any advice with this issue.
I wrote a job that receives some input events and compares them with some rules before forwarding them on to kafka topics based on whatever rules match. I implemented this using a flatMap and found it worked well, with one downside: I was loading the rules just once, during application startup, by calling an API from my main() method, and passing the result of this API call into the flatMap function. This worked, but it means that if there are any changes to the rules I have to restart the application, so I wanted to improve it.
I found this page in the documentation which seems to be an appropriate solution to the problem. I wrote a custom source to poll my Rules API every few minutes, and then used a BroadcastProcessFunction, with the Rules added to to the broadcast state using processBroadcastElement and the events processed by processElement.
The solution is working, but with one problem. My first approach using a FlatMap would process the events almost instantly. Now that I changed to a BroadcastProcessFunction each event takes 60 seconds to process, and it seems to be more or less exactly 60 seconds every time with almost no variation. I made no changes to the rule matching logic itself.
I've had a look through the documentation and I can't seem to find a reason for this, so I'd appreciate if anyone more experienced in flink could offer a suggestion as to what might cause this delay.
The job:
public static void main(String[] args) throws Exception {
// set up the streaming execution environment
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStreamTimeCharacteristic(TimeCharacteristic.IngestionTime);
// read the input from Kafka
DataStream<KafkaEvent> documentStream = env.addSource(
createKafkaSource(getSourceTopic(), getSourceProperties())).name("Kafka[" + getSourceTopic() + "]");
// Configure the Rules data stream
DataStream<RulesEvent> ruleStream = env.addSource(
new RulesApiHttpSource(
getApiRulesSubdomain(),
getApiBearerToken(),
DataType.DataTypeName.LOGS,
getRulesApiCacheDuration()) // Currently set to 120000
);
MapStateDescriptor<String, RulesEvent> ruleStateDescriptor = new MapStateDescriptor<>(
"RulesBroadcastState",
BasicTypeInfo.STRING_TYPE_INFO,
TypeInformation.of(new TypeHint<RulesEvent>() {
}));
// broadcast the rules and create the broadcast state
BroadcastStream<RulesEvent> ruleBroadcastStream = ruleStream
.broadcast(ruleStateDescriptor);
// extract the resources and attributes
documentStream
.connect(ruleBroadcastStream)
.process(new FanOutLogsRuleMapper()).name("FanOut Stream")
.addSink(createKafkaSink(getDestinationProperties()))
.name("FanOut Sink");
// run the job
env.execute(FanOutJob.class.getName());
}
The custom HTTP source which gets the rules
public class RulesApiHttpSource extends RichSourceFunction<RulesEvent> {
private static final Logger LOGGER = LoggerFactory.getLogger(RulesApiHttpSource.class);
private final long pollIntervalMillis;
private final String endpoint;
private final String bearerToken;
private final DataType.DataTypeName dataType;
private final RulesApiCaller caller;
private volatile boolean running = true;
public RulesApiHttpSource(String endpoint, String bearerToken, DataType.DataTypeName dataType, long pollIntervalMillis) {
this.pollIntervalMillis = pollIntervalMillis;
this.endpoint = endpoint;
this.bearerToken = bearerToken;
this.dataType = dataType;
this.caller = new RulesApiCaller(this.endpoint, this.bearerToken);
}
#Override
public void open(Configuration configuration) throws Exception {
// do nothing
}
#Override
public void close() throws IOException {
// do nothing
}
#Override
public void run(SourceContext<RulesEvent> ctx) throws IOException {
while (running) {
if (pollIntervalMillis > 0) {
try {
RulesEvent event = new RulesEvent();
event.setRules(getCurrentRulesList());
event.setDataType(this.dataType);
event.setRetrievedAt(Instant.now());
ctx.collect(event);
Thread.sleep(pollIntervalMillis);
} catch (InterruptedException e) {
running = false;
}
} else if (pollIntervalMillis <= 0) {
cancel();
}
}
}
public List<Rule> getCurrentRulesList() throws IOException {
// call API and get rulles
}
#Override
public void cancel() {
running = false;
}
}
The BroadcastProcessFunction
public abstract class FanOutRuleMapper extends BroadcastProcessFunction<KafkaEvent, RulesEvent, KafkaEvent> {
protected final String RULES_EVENT_NAME = "rulesEvent";
protected final MapStateDescriptor<String, RulesEvent> ruleStateDescriptor = new MapStateDescriptor<>(
"RulesBroadcastState",
BasicTypeInfo.STRING_TYPE_INFO,
TypeInformation.of(new TypeHint<RulesEvent>() {
}));
#Override
public void processBroadcastElement(RulesEvent rulesEvent, BroadcastProcessFunction<KafkaEvent, RulesEvent, KafkaEvent>.Context ctx, Collector<KafkaEvent> out) throws Exception {
ctx.getBroadcastState(ruleStateDescriptor).put(RULES_EVENT_NAME, rulesEvent);
LOGGER.debug("Added to broadcast state {}", rulesEvent.toString());
}
// omitted rules matching logic
}
public class FanOutLogsRuleMapper extends FanOutRuleMapper {
public FanOutLogsJobRuleMapper() {
super();
}
#Override
public void processElement(KafkaEvent in, BroadcastProcessFunction<KafkaEvent, RulesEvent, KafkaEvent>.ReadOnlyContext ctx, Collector<KafkaEvent> out) throws Exception {
RulesEvent rulesEvent = ctx.getBroadcastState(ruleStateDescriptor).get(RULES_EVENT_NAME);
ExportLogsServiceRequest otlpLog = extractOtlpMessageFromJsonPayload(in);
for (Rule rule : rulesEvent.getRules()) {
boolean match = false;
// omitted rules matching logic
if (match) {
for (RuleDestination ruleDestination : rule.getRulesDestinations()) {
out.collect(fillInTheEvent(in, rule, ruleDestination, otlpLog));
}
}
}
}
}
Maybe you can give the complete code of the FanOutLogsRuleMapper class, currently the match variable is always false

Push notification not reaching when app in foreground

I'm having trouble getting Push Notifications when the app is in foreground in an Android device. As soon as I put the app in the background all goes well.
This is the java code I use to send de notifications:
HttpClient client = HttpClientBuilder.create().build();
HttpPost httpPost = new HttpPost(URL_SERVER);
List<NameValuePair> arguments = new ArrayList<>();
arguments.add(new BasicNameValuePair("token", TOKEN));
arguments.add(new BasicNameValuePair("device", codigoApp));
arguments.add(new BasicNameValuePair("type", "1"));
arguments.add(new BasicNameValuePair("body", ip));
arguments.add(new BasicNameValuePair("auth", GOOGLE_AUTH));
try {
httpPost.setEntity(new UrlEncodedFormEntity(arguments));
HttpResponse response = client.execute(httpPost);
String result = EntityUtils.toString(response.getEntity());
System.out.println(result);
} catch (IOException ex) {
Logger.getLogger(NotificaReview.class.getName()).log(Level.SEVERE, null, ex);
}
And this is the code in the app:
public void start() {
if(current != null){
current.show();
return;
}
if (Push.getPushKey() != null)
devicePush = Push.getPushKey();
else
Display.getInstance().registerPush();
Form inicioGUI = new InicioGUI(devicePush);
inicioGUI.show();
}
public void stop() {
current = getCurrentForm();
if(current instanceof Dialog) {
((Dialog)current).dispose();
current = getCurrentForm();
}
}
public void destroy() {
}
#Override
public void push(String value) {
ToastBar.showMessage("Archivo recibido correctamente con IP" + value, FontImage.MATERIAL_INFO);
}
#Override
public void registeredForPush(String deviceId) {
devicePush = deviceId;
}
#Override
public void pushRegistrationError(String error, int errorCode) {
}
The ToastBar only shows when I bring the app to foreground after receiving the push while in background. The Push callback is never called if the app is alive.
Any ideas?
I need answers to my comment in the question which might help explain the issue. I'll edit this answer based on the updates to the question.
In the meantime I see several issues in the code. See my highlighted comments/fixes below:
public void start() {
if(current != null){
current.show();
return;
}
// don't check the push key, always register the device and
// always do it in a callSerially as it might trigger a prompt
callSerially(() -> registerPush());
Form inicioGUI = new InicioGUI(Push.getPushKey());
inicioGUI.show();
}
#Override
public void push(String value) {
ToastBar.showMessage("Archivo recibido correctamente con IP" + value, FontImage.MATERIAL_INFO);
}
#Override
public void registeredForPush(String deviceId) {
// deviceId is the native push key you need to use the actual
// push key value never device ID
devicePush = Push.getPushKey();
}
#Override
public void pushRegistrationError(String error, int errorCode) {
// you might have gotten a push error which might have explained the
// cause of the problem
Log.p("Push error " + errorCode + ":" + error);
Log.sendLogAsync();
}

ConnectionRequest when the app is in the background

I've tested Geofence example by cn1 where it sets local notification. When the app is closed(get destroyed), it still gives notification. But I want to get location through GPS and run connectionRequest to save them in the server. I replaced the connectionRequest code instead of LocalNotification in following code but it doesnot work. What should I do to run the connectionRequest when the app is closed(not when it is minimized but destroyed) so that once the user installs and close (destroys) it, the app sent his/her location data in the server forever untill the app is uninstalled.
Geofence gf = new Geofence("test", loc, 100, 100000);
LocationManager.getLocationManager().addGeoFencing(GeofenceListenerImpl.class, gf);
Geofence with localNotification:
public class GeofenceListenerImpl implements GeofenceListener {
#Override
public void onExit(String id) {
}
#Override
public void onEntered(String id) {
if(Display.getInstance().isMinimized()) {
Display.getInstance().callSerially(() -> {
Dialog.show("Welcome", "Thanks for arriving", "OK", null);
});
} else {
LocalNotification ln = new LocalNotification();
ln.setId("LnMessage");
ln.setAlertTitle("Welcome");
ln.setAlertBody("Thanks for arriving!");
Display.getInstance().scheduleLocalNotification(ln, 10, LocalNotification.REPEAT_NONE);
}
}
}
Why the following doesnot work? (it only work when the app is running or is minimized but not when it is destroyed.)
public class GeofenceListenerImpl implements GeofenceListener {
#Override
public void onExit(String id) {
System.out.println("geofence onExit");
}
#Override
public void onEntered(String id) {
if(Display.getInstance().isMinimized()) {
Display.getInstance().callSerially(() -> {
System.out.println("geofence isMinimized");
});
} else {
System.out.println("geofence when app is closed");
//I want to run connectionRequest here but is not working
}
}
}
PS. I've used background fetch but it only works when the app is minimized.
Update1: Demo of how I used connectionRequest outside of minimized() method...
public class GeofenceListenerImpl implements GeofenceListener {
#Override
public void onExit(String id) {
System.out.println("geofence onExit");
}
#Override
public void onEntered(String id) {
if(Display.getInstance().isMinimized()) {
Display.getInstance().callSerially(() -> {
});
} else {
System.out.println("geofence when app is closed");
Connection c = new Connection();
c.liveTrackConnectionMethod("22" , "23");
}
}
}
Connection class
public class Connection {
ArrayList<Map<String, Object>> response;
public void liveTrackConnectionMethod(String lat, String lon) {
ConnectionRequest cr = new ConnectionRequest() {
#Override
protected void readResponse(InputStream input) throws IOException {
JSONParser jSONParser = new JSONParser();
Map parser = jSONParser.parseJSON(new InputStreamReader(input));
response = null;
}
};
cr.setPost(true);
cr.setUrl("http://url.com");
cr.addArgument("userid", Preferences.get(AllUrls.userIdPreference, null));
cr.addArgument("lat", lat + "");
cr.addArgument("long", lon + "");
cr.addRequestHeader("Accept", "application/json");
NetworkManager.getInstance().addToQueueAndWait(cr);
}
}
I think an app will always return false for isMinimized() when the app is closed or minimized (i.e. not currently running in the foreground) I may be wrong about this.
Try calling your connectionRequest script outside the isMinimized(). After all, you will want to keep track of user location whether they are using the app or not.
Your first solution with LocalNotification will show users a notification by calling the else part, rather than the Dialog when they're using the app, because isMinimized() will be false.

Need examples headers and cookies

IDE: NetBeans
Desktop OS Windows 10
Simulator Android/iOS
Device Android/iOS
I am able to get authentication to work with connection request. I am having to get header information and then in another part of the app, send that same information back to the cgi-bin. Below is my code and I commented on the parts where I believe I need to do something with a header and or cookie. I'm very new to this and It's been difficult finding even a basic header/cookie tutorial.
/**
* Your application code goes here<br>
* This file was generated by Codename One for the purpose
* of building native mobile applications using Java.
*/
package userclasses;
import com.codename1.io.ConnectionRequest;
import com.codename1.io.Cookie;
import com.codename1.io.NetworkEvent;
import com.codename1.io.NetworkManager;
import com.codename1.io.Storage;
import com.codename1.notifications.LocalNotification;
import generated.StateMachineBase;
import com.codename1.ui.*;
import com.codename1.ui.events.*;
import com.codename1.ui.util.Resources;
import java.util.Timer;
import java.util.TimerTask;
//import org.apache.commons.httpclient.UsernamePasswordCredentials;
//import org.apache.commons.httpclient.auth.AuthScope;
/**
*
* #John Barrett
*/
public class StateMachine extends StateMachineBase {
public StateMachine(String resFile) {
super(resFile);
// do not modify, write code in initVars and initialize class members there,
// the constructor might be invoked too late due to race conditions that might occur
}
/**
* this method should be used to initialize variables instead of
* the constructor/class scope to avoid race conditions
*/
protected void initVars(Resources res) {
}
boolean stop = false;
boolean notify = false;
String OnOff;
#Override // Starts monitor action.
protected void onMain_ButtonAction(Component c, ActionEvent event){
// starts a timer to repeat monitor every minute.
Timer timer = new Timer();
String text = (String) Storage.getInstance().readObject("SavedData");
timer.schedule( new TimerTask(){
#Override
public void run(){
if (stop == true){
cancel();//Monitor ends
}
//Starts a connection with the URL to monitor
ConnectionRequest r = new ConnectionRequest();
r.setUrl("http://vault.infinitevault.com/cgi-bin/absentmedia?customer=" + text.toLowerCase().trim());
r.setPost(true);
// Post Header/Cookie information to URL for access NEED HELP WITH THIS!
r.setHttpMethod("HEAD");
r.setContentType("text/xml");
r.setCookiesEnabled(true);
findCodeLabel(c).setText("Monitoring: " + text.toUpperCase());
r.addResponseListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ev){
// Monitor starts
try{
NetworkEvent event = (NetworkEvent) ev;
// Need to post header/cookie information here? HELP!
Cookie.isAutoStored();
byte[] data= (byte[]) event.getMetaData();
String decodedData = new String(data,"UTF-8");
boolean none;
none = decodedData.endsWith("NONE\n");
if (!none){
System.out.println(decodedData);
findCodeTextArea(c).setText(decodedData);
LocalNotification n = new LocalNotification();
n.setId("OSStorage");
n.setAlertBody(decodedData);
n.setAlertTitle("Absent Media");
Display.getInstance().scheduleLocalNotification(
n,
System.currentTimeMillis() + 10 * 1000, // fire date/time
LocalNotification.REPEAT_MINUTE // Whether to repeat and what frequency
);
if (notify != true){
Display.getInstance().vibrate(5000);
}
Storage.getInstance().writeObject("MonitorData", decodedData);
}
else{
System.out.println("None");
findCodeTextArea(c).setText("System is Good");
}
}
catch (Exception ex){
ex.printStackTrace();
}
}
});
NetworkManager.getInstance().addToQueue(r);
}
}, 0, 60*1000);
}
#Override // Stops the monitoring action.
protected void onMain_StopButtonAction(Component c, ActionEvent event) {
super.onMain_StopButtonAction(c, event);//To change body of generated methods, choose Tools | Templates.
stop = true;
findCodeLabel(c).setText("Monitor Stopped");
findCodeTextArea(c).setText("");
findCodeTextArea(c).setHint("System information will show here");
Storage.getInstance().deleteStorageFile("MonitorData");
}
#Override // Saves the settings to storage.
protected void onSettings_SetSaveAction(Component c, ActionEvent event) {
String Station = findSetStation(c).getText();
Storage.getInstance().writeObject("SavedData", Station);
String LoadStation = (String) Storage.getInstance().readObject("SavedData");
findStationLabel(c).setText("Saved Station is " + LoadStation);
}
#Override // Sets what is saved to appear when in settings.
protected void beforeSettings(Form f) {
String LoadStation = (String) Storage.getInstance().readObject("SavedData");
findStationLabel(f).setText("Saved Station is " + LoadStation);
findSetStation(f).setText(LoadStation);
String CurrentNotify = (String) Storage.getInstance().readObject("OnOff");
findSetNotifyLabel(f).setText("Vibration is " + CurrentNotify);
}
#Override // Sets what is saved to appear when in monitor screen.
protected void beforeMain(Form f) {
String LoadStation = (String) Storage.getInstance().readObject("SavedData");
findCodeLabel(f).setText(LoadStation);
if (findCodeTextArea(f) != null){
String foundData = (String) Storage.getInstance().readObject("MonitorData");
findCodeTextArea(f).setText(foundData);
}
}
#Override // Sets notification for turning vibration on.
protected void onSettings_SetNotifyOnAction(Component c, ActionEvent event) {
notify = false;
OnOff = "ON";
Storage.getInstance().writeObject("NotifyOn", notify);
Storage.getInstance().writeObject("OnOff", OnOff);
findSetNotifyLabel(c).setText("Vibration is " + OnOff);
}
#Override // Sets notification for turning vibration off.
protected void onSettings_SetNotifyOffAction(Component c, ActionEvent event) {
notify = true;
OnOff = "OFF";
Storage.getInstance().writeObject("NotifyOn", notify);
Storage.getInstance().writeObject("OnOff", OnOff);
findSetNotifyLabel(c).setText("Vibration is " + OnOff);
}
#Override // Sets message for monitoring or not.
protected void beforeStartPage(Form f) {
Storage.getInstance().deleteStorageFile("MonitorData");
String LoadStation = (String) Storage.getInstance().readObject("SavedData");
}
#Override // Login button pressed after entering username and password.
protected void onLogin_LoginAction(Component c, ActionEvent event) {
// Gets the username and password entered.
String userName = findUsename().getText();
String passWord = findPassword().getText();
// Establishes a conneciton to authentication.
ConnectionRequest req=new ConnectionRequest();
req.setPost(false);
req.setUrl("http://authentication.infinitevault.com/validate.php");
req.addArgument("username",userName);
req.addArgument("password",passWord);
req.addArgument("grant_type","client_credentials");
// To get the Header/Cookie information.
req.getHttpMethod();
req.setCookiesEnabled(true);
Cookie.setAutoStored(true);
Cookie.isAutoStored();
// Sends message to user that system is verifying.
findDenied(c).setText("Verifying");
NetworkManager.getInstance().addToQueueAndWait(req);
if (req.getResponseData() != null) {
String token = new String(req.getResponseData());
token = token.substring(token.indexOf('=') + 1);
System.out.println(token);
// Checks credentials if response is denied, goes back,
// If response is authenticated goes to main monitor form.
if (token.endsWith("denied")){
/*try {
Thread.sleep(2000); //1000 milliseconds is one second.
} catch(InterruptedException e) {
Thread.currentThread().interrupt();
}*/
back();
}
else {
showForm("Main",null);
}
}
}
}//end of app
Just override the connection request method cookieReceived(Cookie c) and handle the logic of each cookie there.

Retry request onErrorResponse Android volley

When i receive an error in onerrorrepsonse of android volley request i want to retry the request. How can i achieve this?
well, you can create the RetryPolicy to change default retry behavior, only specify timeout milliseconds, retry count arguments :
public class YourRequest extends StringRequest {
public YourRequest(String url, Response.Listener<String> listener,
Response.ErrorListener errorListener) {
super(url, listener, errorListener);
setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
}
}
the another way is estimate the VolleyError, re-execute the same request again when if was TimeoutError instance :
public static void executeRequest() {
RequestQueue.add(new YourRequest("http://your.url.com/", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if (error instanceof TimeoutError) {
// note : may cause recursive invoke if always timeout.
executeRequest();
}
}
}));
}
you may have a question at this very moment : "have Volley offer some retry callback methods ?", the answer is "none". but there have a project calls Netroid which based Volley and satisfy preceded question, with it, you can take a retry callback if you care about that, you can calculate how much time used when retry coming and how long this request execute, the code style like this :
final String REQUESTS_TAG = "Request-Demo";
String url = "http://facebook.com/";
JsonObjectRequest request = new JsonObjectRequest(url, null, new Listener<JSONObject>() {
long startTimeMs;
int retryCount;
#Override
public void onPreExecute() {
startTimeMs = SystemClock.elapsedRealtime();
}
#Override
public void onFinish() {
RequestQueue.add(request);
NetroidLog.e(REQUESTS_TAG);
}
#Override
public void onRetry() {
long executedTime = SystemClock.elapsedRealtime() - startTimeMs;
if (++retryCount > 5 || executedTime > 30000) {
NetroidLog.e("retryCount : " + retryCount + " executedTime : " + executedTime);
mQueue.cancelAll(REQUESTS_TAG);
} else {
NetroidLog.e(REQUESTS_TAG);
}
}
});
request.setRetryPolicy(new DefaultRetryPolicy(5000, 20, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
request.setTag(REQUESTS_TAG);
RequestQueue.add(request);
Netroid also have many other handy and powerful features, hope that will help you enough :).
You can set counter variable for trying specific time with out making it full recursive
static int count=10; //so its will try ten time
public void userLogin(final View view)
{
final RequestQueue requestQueue= Volley.newRequestQueue(getApplicationContext());
String url = "http://192.168.43.107/mobodb/register.php";
StringRequest stringRequest=new StringRequest(Request.Method.POST,url,new Response.Listener<String>()
{
#Override
public void onResponse(String response) {
Toast.makeText(getApplicationContext(),"Updated",Toast.LENGTH_LONG).show();
}
}
},new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
count=count-1;
Toast.makeText(getApplicationContext(),"Retry left"+count,Toast.LENGTH_LONG).show();
if (count>0) {
// note : may cause recursive invoke if always timeout.
userLogin(view);
}
else
{
Toast.makeText(getApplicationContext(),"Request failed pls check network connection or the error is "+error.getMessage(),Toast.LENGTH_LONG).show();
}
}
})
{
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> paramter=new HashMap<String,String>();
paramter.put("name",login_name);
paramter.put("user_pass",login_pass);
return paramter;
}
};
requestQueue.add(stringRequest);
stringRequest.setRetryPolicy(new DefaultRetryPolicy(20 * 1000, 10, 1.0f));
you can also check response inside which you can return from php and deal in your java class
#Override
public void onResponse(String response) {
if(response.contains("no record found for"))
Toast.makeText(getApplicationContext(),response.toString(),Toast.LENGTH_LONG).show();
else
{
Toast.makeText(getApplicationContext(),"Updated num of row is"+response.toString(),Toast.LENGTH_LONG).show();
}
}
your PHP code will be
if($res){
$resp=mysql_affected_rows();
if($resp==0)
{
$resp="no record found for".$_POST['name'];
}
if($resp==1 or $resp>1)
{
$resp=mysql_affected_rows();
}else $resp="efrror is".mysql_error();

Resources