I’m new in android programming and for testing I have this code that download google home page.
The code works but I have a problem :
if I start app and internet is ok , code download without problem the page but if , for example , during download internet falls I have no way of knowing because no method will call.
How do I solve this problem?
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AsyncHttpClient client = new AsyncHttpClient();
client.get("https://www.google.com", new AsyncHttpResponseHandler() {
#Override
public void onStart() {
// called before request is started
Log.d ("info", "PRIMA DELLA CONNESSIONE");
}
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
// called when response HTTP status is "200 OK"
Log.d ("info", "DATI");
Log.d ("info", response.toString());
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
// called when response HTTP status is "4XX" (eg. 401, 403, 404)
Log.d ("info", "errore");
Log.d ("info", Integer.toString(statusCode));
}
#Override
public void onRetry(int retryNo) {
// called when request is retried
Log.d ("info", "RETRY");
}
});
}
thats rigth thats how it works, but i think there is a method called,
onFinish, and you can set the request time, for some error of network connection you can put your code inside a try-catch
try
{
//your code here
}
catch(Exceptio e) // you can try catch SocketException
{}
with try you can catch if there is some error in your connection
Related
I supposed to use MVVM pattern with Data Repository. Data Came from Web Api call. and based on The Data, The Application Start The Web Browser With Returned URL.
on user interaction The Activity calls ViewModel Which owns Data:
CheckOutActivity.java:
MaterialRippleLayout makeOrder = findViewById(R.id.btn_make_order);
makeOrder.setOnClickListener(view ->{
viewModel.makeOrder();
});
viewModel calls DataRepository with Appropriate Data (optionalShippingEntityIds) to call Web Api Async:
CheckOutViewModel.java
public void makeOrder(){
cartRepository.makeOrder(optionalShippingEntityIds.getValue());
}
The Repository has been instantiated before:
public CheckOutViewModel(#NonNull Application application) {
super(application);
cartRepository = new CartRepository(application);
}
in DataRepository Api Call performs:
CartRepository
public void makeOrder(ArrayList<Integer> optionalShippingEntityIds){
HashMap<String,String> map = new HashMap<String,String>();
String idsString=optionalShippingEntityIds.toString();
map.put("shipment_saleitem_id",idsString);
rest.httpRequest(RestAdapter.HttpVerb.POST,"order",map,new makeOrderHandler());
}
The CartRepository Constructor:
private RestAdapter rest;
private Context context;
public CartRepository(Context context) {
this.context = context;
rest = RestAdapter.getInstance(context);
version.setValue(0);
}
4.HttpResponseHandler Handle The Web Browser open URL or Toast fail message
CartRepository.java
class makeOrderHandler extends JsonHttpResponseHandler{
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
if(statusCode == 200){
try {
Toast.makeText(context,"order number "+response.getInt("order_id")+"has been created",Toast.LENGTH_SHORT).show();
String redirectUrl = response.getString("init_payment_url");
version.setValue(version.getValue() +1);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(redirectUrl));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
((Activity)context).finishAffinity();
//System.exit(0);
/*Intent chooserIntent = Intent.createChooser(intent, "Open With");
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(chooserIntent);*/
}
}, 2000);
} catch (JSONException e) {
Toast.makeText(context,"JSON parse error"+" : "+response.toString(), Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}else{
Log.e("server api changed ", "error in getting response using known api \n" + response.toString());
Toast.makeText(context,"api change",Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(int statusCode, Header[] headers, String res, Throwable t) {
// called when response HTTP status is "4XX" (eg. 401, 403, 404)
Log.e("server 500", "error in getting response using async-apache-http call"+" : "+res);
t.printStackTrace();
Toast.makeText(context, "خطا سرور ", Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(int statusCode, Header[] headers, Throwable t, JSONObject e) {
if(statusCode == 504){
Toast.makeText(context,"The Order hasnt been created duo to internal problem. please try again",Toast.LENGTH_SHORT).show();
}else{
Log.e("server api changed", "error in getting response using known api \n" + e.toString());
t.printStackTrace();
Toast.makeText(context,"Api is unknown",Toast.LENGTH_SHORT).show();
}
}
}
The Problem is after i launch The Application in some Devices, in The Line ((Activity)context).finishAffinity(); The Application Crashes because The context is an application context instance and not an activity context instance .
if i pass The Activity instance Through ViewModel, i had just violated The MVVM.
if i make an interface in The Activity and implement it. it violates The Activity Single Responsibility (Data Repository Response Handler Should Handle The startActivity)
so i dont know how to handle this perfectly.
if i eliminate The ViewModel makeOrder, and Construct The Repository With The Activity Context I think its ViewModel Responsibility to Handle The Data Manipulation Job.
....
So I am Confused With The Right Solution To Handling StartActivity and Toast in Response.
if anyone could help me With The Right Design Pattern i Would Appreciate.
Your viewmodel can extends from AndroidViewModel.
From documentation:
"Application context aware ViewModel.
Subclasses must have a constructor which accepts Application as the only parameter."
Trying to create a simple movie showtime mobile app. I've used the this method before in another class and it works fine but for some reason in this current class I get a 404 error.
client.get(String.format(VIDEO_URL, 209112), new JsonHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Headers headers, JSON json) {
try {
JSONArray results = json.jsonObject.getJSONArray("results");
if(results.length() == 0){
return;
}
String youtubeKey = results.getJSONObject(0).getString("key");
} catch (JSONException e) {
Log.e("DetailActivity", "Failed to parse JSON", e);
}
}
#Override
public void onFailure(int statusCode, Headers headers, String response, Throwable throwable) {
System.out.println("On failure again " +statusCode + " response: " + response);
}
});
I have the dependency line for it in my gradle file as well.
implementation 'com.codepath.libraries:asynchttpclient:0.0.9'
This is the onFailure message I get
On failure again 404 response: {"status_code":34,"status_message":"The resource you requested could not be found."}
HTTP 404 error is a server-side error.
404 not found
The problem should be irrelevant to your android code. You may check if the url you are requesting really exists.
EDIT:
You may log the url and check whether the format is correct
I've been searching the simplest way to get Html code to String for some time now. I just need to fetch it so i can move forward with my project.
I tried:
OkHttpClient client = new OkHttpClient();
String run(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.text);
String html= null;
try {
html = run("http://google.com");
} catch (IOException e) {
e.printStackTrace();
}
text.setText(html);
}
}
I got Error android.os.NetworkOnMainThreadException.
I just started developing in Android studio and I'm not an expert in Java either. I would like if someone would explain what i need to do, with examples preferably. thank you in advance
As #CommonsWare and #christian have already said, you need to make network operations in the background and for this aim Okhttp has a special method enqueue(). This will create a background thread for you and simplify your work.
In your case, change the lines inside run() method to these:
String run(String url) throws IOException {
String result = "";
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
// failure case
}
#Override
public void onResponse(Call call, Response response) throws IOException {
// success case
result = response.body().string();
}
});
}
You need to make network operations in background thread otherwise, you will get the exceptions. Android make it mandatory because network call takes a bit time and the UI-Thread will freeze.
Please refer https://github.com/square/okhttp/wiki/Recipes#asynchronous-get
and https://stackoverflow.com/a/6343299/1947419
I know for a fact the data I am sending in this is getting sent unlike my previous question where an exception was being thrown. I can successfully execute a request object using loopj async http client however i am unable to get my data from the php side and display it, the status code that gets displayed is 200 which means the request library is working. I have a felling it maybe a firewall issue but not sure how to bypass that? Any tips on how to resolve this from the php side would be much appreciated.
here is my code:
protected void PostData(final Integer Question_ID,Integer ResponseChosen_ID) throws IOException {
try{
AsyncHttpClient client = new AsyncHttpClient();
final RequestParams params1 = new RequestParams();
params1.put("Question_ID", Question_ID.toString());
params1.setUseJsonStreamer(true);
client.get("http://cce.swlgroup.com/SwlLogin.php/", params1, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
messageBox("Response Successful: ", "" + statusCode);
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
Log.d("Response",error.toString());
}
});
System.out.print(params1);
}
}
}
php code:
repo.php:
var_dump($_SERVER);
var_dump($_GET);
nothing is displayed here, im also not sure now what i am trying to do is even possible with the built in library and now a third party library.
I'm trying to connect means AsyncHttpClient to a php script on my website. The script do the html parsing of another page, and convert the result to json. it work well. But, when I try to take the json form java for using it on android, the method that have the only work of open a stream and return 'response', doesn't run onSuccess and onFailure both. can anyone help me?
Here the code:
private String getStream() {
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://jem88.net/eventsAroundYouParser.php", new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
System.out.println("response is here..."+response);
Log.d("eventstaker", "into response!!");
}
#Override
public void onFailure(Throwable e, String response) {
Log.d("eventstaker", "onFailure method is run... :(");
}
});
return "";
}`
I've set the internet and network_access permission in the manifest.
Thank you in advance
You can override more onFailure methods