I'm using IP Webcam app in my android phone to use it as an IP camera and I'm using another android phone to run my app that recognizes faces using Kairos API. I'm using the IP Webcam app and the image is streamed at a url which is something like:
"http://xxx.xxx.x.xxx:8080/photo.jpg" and I am able to view the image through this url on all the devices, however the API that I'm using has a recognize function that takes image url as one of it's parameters but when I'm using the streamed image URL, it doesn't work. I tried figuring out what's happening through logs but all I could see was that it threw a SocketTimeoutException(read time out) and tried solutions for it from SO but nothing worked, any suggestions here?
code:
public void getUrlText(){
try{
url = new URL("http://xxx.xxx.x.xxx:8080/photo.jpg");
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
Handler handler = new Handler();
Runnable timedTask = new Runnable(){
#Override
public void run() {
getUrlText();
handler.postDelayed(timedTask, 1000);
}};
and this is inside onCreate method:
getUrlText();
handler.post(timedTask);
recognizePhotoKairos(Uri.parse(url.toString()), userPhoneNumber);
When you are using ip webcam make sure your all the devices connected to same server.
Second thing is that you have to refresh the url again and again in order to get the latest image. I think this is your main problem in refreshing the url. I suggest you to use handler for this, which wait for a particular time and then refresh the url again or api in your case.
Read more about handler
I am adding the my source code of a project where i start the handler again and again
public class CounterActivity extends AppCompatActivity {
TextView textView;
private boolean started = false;
private PowerManager.WakeLock wl;
private Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_counter);
textView=findViewById(R.id.points);
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "My:Tag");
// screen stays on in this section
start();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
final String URL="http://172.16.16.108:8080/wallgame/api/game_points";
StringRequest request=
new StringRequest(Request.Method.GET, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject object=new JSONObject(response);
JSONObject data=object.getJSONObject("data");
int points=Integer.parseInt(data.getString("game_points"));
textView.setText(points+"");
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(CounterActivity.this, "Error", Toast.LENGTH_SHORT).show();
}
}
);
RequestQueue queue= Volley.newRequestQueue(CounterActivity.this);
queue.add(request);
}
},1000);
}
Runnable runnable = new Runnable() {
#Override
public void run() {
final String URL="http://172.16.16.108:8080/wallgame/api/game_points";
StringRequest request=
new StringRequest(Request.Method.GET, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject object=new JSONObject(response);
JSONObject data=object.getJSONObject("data");
int points=Integer.parseInt(data.getString("game_points"));
textView.setText(points+"");
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(CounterActivity.this, "Error", Toast.LENGTH_SHORT).show();
}
}
);
RequestQueue queue= Volley.newRequestQueue(CounterActivity.this);
queue.add(request);
start();
}
};
public void onDestroy() {
super.onDestroy();
started = false;
handler.removeCallbacks(runnable);
if (wl.isHeld())
wl.release();
}
public void start(){
started = true;
handler.postDelayed(runnable, 1500);
}
}
Related
I am creating app that can run 2 process at the time (saving to database / sending to api) but , i was encountering issue from my treading.This is my code upon my threading:
this is my code:
public void timerToSaveSend() {
Thread t1 = new Thread() {
#Override
public void run() {
saving();
}
};
t1.start();
Thread t2 = new Thread(){
#Override
public void run() {
sending();
}
};
t2.start();
}
private void sending() {
//dataSendApi
handler10 = new Handler();
handler10.postDelayed(new Runnable() {
#Override
public void run() {
try {
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl("http://" + ADDRESS + ":" + PORT)
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
API locate = retrofit.create(API.class);
Call<MapDetails> call = locate.mapDetailLocation(data);
call.enqueue(new Callback<MapDetails>() {
#Override
public void onResponse(Call<MapDetails> call,
Response<MapDetails> response) {
String portString = String.valueOf(portss);
}
#Override
public void onFailure(Call call, Throwable t) {
Log.d("Message: ", "Data not sent, please check your
network connection.");
}
});
} catch (Exception e) {
Toast.makeText(NavDrawerFleet.this, "Disconnected from Internet, Please Configure Settings", Toast.LENGTH_SHORT).show();
restFailed();
}
}
}, 10000);
}
private void saving() {
//4SECOND
handler2 = new Handler();
handler2.postDelayed(new Runnable() {
#Override
public void run() {
DatabaseHelper databaseHelper = new DatabaseHelper(getApplicationContext());
SQLiteDatabase db = databaseHelper.getWritableDatabase();
well2 = String.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", java.util.Locale.getDefault()).format(new java.util.Date()));
boolean accepted = databaseHelper.saveLocationToLocalDatabase(gg, hidelat.getText().toString(), hidelon.getText().toString(), well2, "1", "9090", db);
failedCount.setText(String.valueOf(retryList.size()));
lat2 = hidelat.getText().toString();
lon2 = hidelon.getText().toString();
MapDetails mapDetails = new MapDetails(gg, hidelat.getText().toString(), hidelon.getText().toString(), well2, "1", 9090);
data.add(mapDetails);
retry2 = new NotSentModuleGetterSetter(hidelat.getText().toString(), hidelon.getText().toString(), well2);
retryList.add(retry2);
retrylist_adapter.notifyDataSetChanged();
if (accepted == true)
Log.w("Data Entered: ", "1st Copy");
}
}, 2000);
saving();
}
and this is my error encountered:
PS. I was wondering that my code is to totally not working though i want also other possible code implementation with this one, like asynctask to work with this multiple process + with threading in a single meathod.
For threading, please consider using RxJava. It would be as simple as this
Observable.fromCallable(new Callable<Object>() {
#Override public Object call() throws Exception {
saving();
return null;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Object>() {
#Override public void onSubscribe(Disposable d) {
}
#Override public void onNext(Object o) {
}
#Override public void onError(Throwable e) {
}
#Override public void onComplete() {
}
});
Check this link out on how to integrate RxJava into your project https://github.com/ReactiveX/RxAndroid
So I've run into a problem in my code, where I need to get a JSONString from my server with volley. And then I have to parse the String into a JSONObject and then continue doing stuff with that.
My problem here is, that Volley gives the response too late, meaning my string that I want to parse is always empty because its not initialised yet.
RequestFuture<String> future = RequestFuture.newFuture();
StringRequest stringRequest = new StringRequest(Request.Method.GET, searchURLBuilder, future, future);
// new Response.Listener<String>() {
// #Override
// public void onResponse(String response) {
// writeToSharedResponse(response_for_search, response);
// }
// },
// new Response.ErrorListener() {
// #Override
// public void onErrorResponse(VolleyError error) {
// Log.d("Error!!:" + error.getMessage(), "");
// }
// });
requestQueue.add(stringRequest);
String response = "";
try {
response = future.get(60, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
String responseString = m.getString(response_for_search, new String());
pieceDTOList = getPiecesDTOFromJSON(responseString);
Here is a snippet of my code. As you can see I already tried to make a "future" call to block and wait for the answer, but it just times out every time. The commented out bit, is the part I actually wanted to use from the beginning, but that returns the response to late. Since its asynchronous and accesses the server w/e it wants.
writeToSharedResponse just writes the answer into a sharedPreferences variable.
private SharedPreferences m;
private SharedPreferences.Editor editor;
private RequestQueue requestQueue;
public DbParser(Context c) {
m = PreferenceManager.getDefaultSharedPreferences(c);
editor = m.edit();
requestQueue = Volley.newRequestQueue(c);
}
My Question here is: Is there an easy way I can "wait" for the answer from volley so I can continue to work with the response that I get?
Edit 1:
I now added an interface and changed the code around to this:
getString(new VolleyCallback() {
#Override
public void onSuccess(String result) {
getPiecesDTOFromJSON(result);
}
}, searchURLBuilder);
return globalPieceDTOList;
}
private void getString(final VolleyCallback callback, String searchUrl){
StringRequest stringRequest = new StringRequest(Request.Method.GET, searchUrl,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
callback.onSuccess(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error!!:" + error.getMessage(), "");
}
});
requestQueue.add(stringRequest);
}
Since I cant get the values out of my inner classes, I did a nasty hack and created a global list for my DTO's. The problem now is that "return globalPieceDTOList" is always Null. And again - I would need to "wait" for the Volley response.
Volley requests are async, so when you try to return a value, the request is likely not done yet. If you want to return values from a Volley request use callback interfaces.
Example
public void getString(final VolleyCallback callback) {
StringRequest strReq = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// do some things here
callback.onSuccess(<PASS STRING RESULT HERE>);
}
});
}
public interface VolleyCallback{
void onSuccess(String result);
}
Example usage:
public void onResume(){
super.onResume();
getString(new VolleyCallback(){
#Override
public void onSuccess(String result){
//do stuff here with the result from the volley request
}
});
}
I am working on an application in which I have to hit the RESTful web service in every 5 min to check whether the new data is updated or not even if the application is closed by the user. I did this
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
RequestQueue requestQueue = Volley.newRequestQueue(this);
String url = "http://www.abcert.com/wp-json/wp/v2/posts";
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
boolean Str;
try {
JSONArray jsonArray =new JSONArray(response);
Log.i("JSON",""+jsonArray);
JSONObject jsonObject = jsonArray.getJSONObject(0);
int id = jsonObject.getInt("id");
Log.i("MyService is on the",""+id);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i("Hey","Something went wrong");
}
});
//add request to queue
requestQueue.add(stringRequest);
return START_STICKY;
}
But Didn't get success. START_STICKY is not working when I close the app service is also killed.
Many Apps use Service which is connected to their DB, for their specific tasks and Run in the background.
Like Facebook runs MessagingService, Instagram runs NotificationService. If you want you can use handler same time you can also choose Scheduler.
Example using Handler:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
String url = "http://www.abcert.com/wp-json/wp/v2/posts";
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
boolean Str;
try {
JSONArray jsonArray =new JSONArray(response);
Log.i("JSON",""+jsonArray);
JSONObject jsonObject = jsonArray.getJSONObject(0);
int id = jsonObject.getInt("id");
Log.i("MyService is on the",""+id);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i("Hey","Something went wrong");
}
});
//add request to queue
requestQueue.add(stringRequest);
handler.postDelayed(this, 1000 * 60 * 5); //Code runs every 5 minutes
}
}, 0); //Initial interval of 0 sec
return START_STICKY;
}
I am working on an application in which I have to hit the RESTful web service in every 5 min to check whether the new data is updated or not even if the application is closed by the user.
Running an indefinite service is not the ideal solution for it. Read this.
Use a background scheduler for this purpose, as it also takes care of efficient usage of the battery.
I have no idea whats going on here. My app works perfectly fine on the J5 and J6, but it stops working on the S6 (same android version on all phones)
And it only stops when I have the following code:
When I publish, android studio says 0 errors and 0 warnings
I'm still pretty new to android studio, and I've tried it with Thread myThread and without thread
public class IntroPage extends AppCompatActivity {
private ImageButton btnSkip;
private ImageButton btnUpdate;
// need this for post
RequestQueue requestQueue;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// full screen
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.intro_page);
requestQueue = Volley.newRequestQueue(getApplicationContext());
// outlets
btnSkip = (ImageButton) findViewById(R.id.btnSkip);
btnUpdate = (ImageButton) findViewById(R.id.btnUpdate);
// hide both on default
btnSkip.setVisibility(View.VISIBLE);
btnUpdate.setVisibility(View.GONE);
// when submit is clicked
btnSkip.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent startMainScreen = new Intent(getApplicationContext(), MainActivity.class);
startActivity(startMainScreen);
finish();
}
});
// update
btnUpdate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setData(Uri.parse("https://play.google.com/store/apps/details?id=ddddddddd"));
startActivity(intent);
}
});
// get app version
PackageInfo pInfo = null;
try {
pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
String version = pInfo.versionName;
final Integer versionCode = pInfo.versionCode;
// conn
Thread myThread = new Thread() {
#Override
public void run() {
StringRequest jsonObjectRequest = new StringRequest(Request.Method.POST,
"https://www.domain.com/appVersion.php", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject responseJson = new JSONObject(response);
Log.i("JSON RESPONSE", responseJson.toString());
// check if we are up to date
if (responseJson.getInt("version") > versionCode) {
btnSkip.setVisibility(View.GONE);
btnUpdate.setVisibility(View.VISIBLE);
} else {
btnSkip.setVisibility(View.VISIBLE);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
// This whole section can be deleted if we dont post vars
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> parameters = new HashMap<>();
parameters.put("club", "Murmur");
parameters.put("device", "Android");
return parameters;
}
};
jsonObjectRequest.setShouldCache(false);
// requestQueue.getCache().remove("https://www.domain.com/appVersion.php");
requestQueue.add(jsonObjectRequest);
}
};
myThread.start();
}
}
I want to send a POST request to my server, and there is no expected data for the result (just HTTP status code - standard behavior). How can I do that ?
(abstract base Request class (Volley) wants a result type)
try {
mRequest =
new XXXXXX(
Request.Method.POST,
url,
null, null,
new Response.Listener() {
#Override
public void onResponse() {
// ok
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError e) {
// ko
}
},
null
);
return mRestCoreVolley.addToRequestQueue(mRequest);
} catch (Exception e) {
// error
}
You could try something like in the code below for the response listener:
new Response.Listener<Void>() {
#Override
public void onResponse(Void response) {
}
}
I guess your code is right. You can use a String like:
RequestQueue rq = Volley.newRequestQueue(this);
StringRequest postReq = new StringRequest(Request.Method.POST,
your_url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// do nothing
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// Handle error
}
}) ;
Hope it helps you!