Android send HTTP PUT, but error: isDataScedulerEnabled():False - android

I'm trying to send a PUT request but failing bad in it.
Only the first time I'm trying to send data the following line follows up in the log (in further use no exceptions are thrown):
E/DataScheduler: isDataSchedulerEnabled():false
I tried to google out what could that possibly mean, but with no luck. And even that in the further attempts on sending data the mentioned exception wont raise anymore, still no data is being sent. I'm trying to send it on my own server and I can see no connections are received on that side. Using my Android's browser I can send a successful GET request however.
I've also set the permission for Internet already by:
<uses-permission android:name="android.permission.INTERNET" />
I'm not very familiar with Java or Android but as far as I know the request should be formed and sent the following way:
public void sendFilesWithPut(String address, String file) {
new AsyncTask<String,Void,Void>() {
#Override
protected Void doInBackground(String... params) {
try {
//Log.d("HTTP:","Address:"+params[0]+":"+params[1]+" file:"+params[2]);
URL url = new URL("http://" + params[0] + ":" + params[1]);
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
httpCon.setDoOutput(true);
httpCon.setRequestMethod("PUT");
OutputStreamWriter out = new OutputStreamWriter(httpCon.getOutputStream());
out.write(params[2]);
out.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}.execute(address, Integer.toString(port), file);
}
I can print a line to Log every time I attempt to send a PUT request and it's all correct: IP, port and the to-be-sent-String.
Any ideas how to make it work?

I suspect that params[0] and params[1] are actually the address and port for your url. If so then you may wish to refer to the following post:
Making PUT request with JSON data using HttpURLConnection is not working
Where the content will be sent if you start interaction with the response, so add the following:
System.err.println(httpCon.getResponseCode());
as per the post, and see if that works?

Related

JsonWriter POST not working in Android to WCF web service

I would like to know anyone has a sample code on how to use JsonWriter to post JSON data to WCF web service from Android?
I tested my WCF with Fiddler 4 (Composer with POST json data) and it gave me the correct return.
However, when I tested with my Android application which use JsonWriter, I didn't see any action on Fiddler (I set up Fiddler to check on my Android Emulator network traffic, by the way, I am testing on Android Emulator.).
With the same Android application, I can call GET with JsonReader to my WCF and get the correct reply.
Its just calling POST with JsonWriter got no response code or no action in Fiddler.
For JsonWriter (and Reader), I refer to Android developer >> JsonWriter
Here are my test results (Get and Post) with Emulator GET and POST.
Here are my test results with Fiddler direct POST.
First it gave me Result 307 then follow by 200.
And here is how I use JsonWriter to post (this block was from AsyncTask).
try
{
Log.d("TEST_JSON", "URL: " + params[0]);
URL url = new URL(params[0]);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept","application/json");
conn.setRequestProperty("Content-Type","application/json");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setAllowUserInteraction(false);
// conn.connect();
OutputStream out = conn.getOutputStream();
JsonWriter writer = new JsonWriter(new OutputStreamWriter(out, "UTF-8"));
try
{
writer.setIndent(" ");
if(params[1].trim() == "ARRAY")
{
// Write array to WCF.
}
else if(params[1].trim() == "OBJ")
{
// Write object to WCF. <<== I am testing with one object.
writer.beginObject();
writer.name("ShipNo").value("SI10101");
writer.name("DoNo").value("DO230401");
writer.name("PartNo").value("102931-1201");
writer.name("Qty").value(1);
writer.name("ShipIn").value(1);
writer.endObject();
}
}
finally
{
writer.close();
out.close();
}
// If I enable below blocks, I will see 307 response code in Fiddler.
/*
conn.connect();
int responseCode = conn.getResponseCode();
Log.d("TEST_JSON", "Code: " + String.valueOf(responseCode));
*/
Log.d("TEST_JSON", "Finish sending JSON.");
conn.disconnect();
}
catch (IOException e)
{
Log.e("TEST_JSON",e.getMessage()); // <<-- No error from this try catch block.
}
I tried and still cannot figure out why JsonWriter didn't trigger to my WCF (I attached my WCF to my localhost service, only Fiddler direct POST will hit the break point in my WCF project while Android App didn't reach to it). I follow the exact example from Android Developer site though. I google and didn't find any site on using JsonWriter with OutputStreamWriter (I saw some post using StringWriter).
May I know where did my code wrong ?
Based on this StackOverFlow post WCF has a 'Thing' about URI, I managed to solve this issue.
All I need is to make sure my POST web service has URI Template ends with "Slash".
Example: http://10.72.137.98/myWebSvc/posvctFun/
Instead of http://10.72.137.98/myWebSvc/postFun

Youtube Get uploaded video list. FileNotFound Error

I am trying to get list of videos uploaded on my YouTube channel using following
https://www.googleapis.com/youtube/v3/search?part=snippet&channelId{MY_CHANNEL_ID}&maxResults=50&key={MY_APP_ID}
I have created App in Google App Console and generate APP ID for the same. But when I trying to access it through my Android application getting java.io.FileNotFoundException error
I have given application identifier and SHA1 also, If I try to access through Web Browser key without any other constrains it works well and returns all the video list but in case of Android it is not working.
#Override
protected String doInBackground(Void... voids) {
HttpURLConnection urlConnection = null;
String urlString = "https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=UCrF362wkcVnjqqPRsSEzvgg&maxResults=50&key=AIzaSyAiAFjZb1eVdRxVWnymrhuAb1iDlmYupu8";
//urlString = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=PLTqSMwQKOhUhl7gm7h6YwX6XPYr0ViBtu&key=AIzaSyAiAFjZb1eVdRxVWnymrhuAb1iDlmYupu8";
String jsonString = new String();
URL url = null;
try {
url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setDoOutput(true);
urlConnection.connect();
BufferedReader br=new BufferedReader(new InputStreamReader(url.openStream()));
char[] buffer = new char[1024];
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
br.close();
jsonString = sb.toString();
System.out.println("JSON: " + jsonString);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return jsonString;
}
Error Log
BasicNetwork.performRequest: Unexpected response code 403 for https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=UCrF362wkcVnjqqPRsSEzvgg&maxResults=50&key=AIzaSyAiAFjZb1eVdRxVWnymrhuAb1iDlmYupu8
05-13 15:28:26.607 19118-19151/com.jeevanmulmantra W/System.err: java.io.FileNotFoundException: https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=UCrF362wkcVnjqqPRsSEzvgg&maxResults=50&key=AIzaSyAiAFjZb1eVdRxVWnymrhuAb1iDlmYupu8
Without looking at your API Console settings, I cannot say for sure. But from looking at the HTTP response, it looks like your IP address might be blocked by the Google authorization server. Hence, it is sending you back an unauthorized request HTTP status code 403.
Go to your API Console and select the None radio button from under the Key restrictions section. Then try again. It should work.
This is not exactly what you are asking but I will share my experience.
I had a similar situation a couple of months ago. Seaching on line I got to the conclusion that the YouTube api option for Android just doesn't work. I ended up with a more convenient solution for my development:
I got a YT api key for a website and bound it to the corresponding domain.
I Created a php file that gets the playlist from youtube twice a day using curl and cron job setup on the server. The playlist file in json format is then written to the web server (refreshed twice a day).
The Android app connects to my server intead of YTs and get the "cached" json play list from there.
This option drastically reduces the impact on the quota consumption because all the hits to the playlist go to the website.
If you are interested in this option I can share the php used for getting the play list.
I had the same problem, just regenerate another key and restrict it again with the package name and SHA1 from your Android Studio. It wasn't working with the old key regenerating the key and restricting it again worked for me.

How to Use Both HTTPS and HTTP to parse JSON data in Android?

I followed this to Parse Json In Android
I have Successfully Done it with HttpData handler..
Here I am Successfully Posting Data to server and Getting Response..
Now I want to Use this same in the Part of HTTPS..
Can Any one suggest me How to do this Without Major Changes in my code.. Because In my application I am doing this for more activities.. Please Suggest me to Use HTTPs in my code..
I will provide Additional Info... Depending Responses...
Update
In my code I have Changed HttpURLConnection to HttpsURLConnection
Please suggest me How to through this error In my code..
Update 1
I have Changed Certificate on server side.. Now its working On Https..
But Now,
I want to Use HTTP and HTTPS Both in one app Depending on Client Requirement So here now its worked with Https....
But I also need to work with Http
In my Code Can any any one suggest me...I want I should Work with Https and Http Both In one App.
to use both HTTP and HTTPS, you need to have the 2 methods (i think you already have them)
GetHTTPData(String urlString)
GetHTTPSData(String urlString)
now in HTTPDataHandler class (where you have both methods above)
you need to create a 3rd method GetDataFromUrl(), that will check URL and decide which method to use (http or https)
public String GetDataFromUrl(String url){
if(url.toLowerCase().startsWith("https")){
//HTTPS:
return GetHTTPSData(url);
}else{
//HTTP:
return GetHTTPData(url);
}
}
now in the AsyncTask class ProcessJSON
replace this line stream = hh.GetHTTPData(urlString);
with this one stream = hh.GetDataFromUrl(urlString);
if you don't want to add that 3rd method in HTTPDataHandler, just use the if-statement in ProcessJSON at doInBackground() to call either one of the 2 methods (http or https)
You can use HttpsURLConnection, replace HttpURLConnection by HttpsURLConnection .
public String GetHTTPData(String urlString){
try{
URL url = new URL(urlString);
HttpsURLConnection urlConnection =(HttpsURLConnection)url.openConnection();
// Check the connection status
if(urlConnection.getResponseCode() == 200)
{
// if response code = 200 ok
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
// Read the BufferedInputStream
BufferedReader r = new BufferedReader(new InputStreamReader(in));
StringBuilder sb = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
sb.append(line);
}
stream = sb.toString();
// End reading...............
// Disconnect the HttpURLConnection
urlConnection.disconnect();
}
else
{
// Do something
}
}catch (MalformedURLException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}finally {
}
// Return the data from specified url
return stream;
}
What I understand is in your server side, they used self signed SSL certificate. So you have to install that certificate in your android device also. Settings > Security > install form storage.But for production build you have to buy ssl certificate from CA Authorities.
Hope this will solve your problem.
Remove HttpDataHandler lines in doInBackground use HttpUrlConnection directly in doInBackground or use HttpUrlConnection in JSONparse class to post params to server follow this tutorial to post params Website

Handling session, network state and http request

In my application I am sending multiple http requests.
Since, the network may go down at any time. So, before sending each request should I use android ConnectionManager to check the network state? I am feeling that some other better way would be there to handler this.(Rather than using the android connection manager service each time when multiple request are sent on each fragment)
Take a look at this question. If you want to avoid use of the ConnectionManager, you could use a try-catch block and check for an exception while trying to make a connection (provided you are using the java.net.* library to do the HTTP requests). For example, something like this was used in that question:
URL url = ...
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setReadTimeout(15000);
try {
InputStream in = new BufferedInputStream(c.getInputStream());
httpResult = readStream(in);
} catch (IOException e) {
// Here is where an exception would be thrown if there is no internet.
// Would likely actually be an UnknownHostException
Log.e(TAG, "Error: ", e);
} finally {
c.disconnect();
}

Sometimes my app crashes with UnknownHostException

In my app i have access to web server. It works fine in Some phones but while testing in Samsung Galaxy
Model No - GT-S5830i
Android Version - 2.3.6
it keeps on showing Unknown host exception. I have checked the url from browser its working fine.
private void submitUploadData(String url ,Map<String, String> param) throws IOException
{
URL siteUrl;
try {
siteUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) siteUrl.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
Set getkey = param.keySet();
Iterator keyIter = getkey.iterator();
String content = "";
for(int i=0; keyIter.hasNext(); i++) {
Object key = keyIter.next();
if(i!=0) {
content += "&";
}
content += key + "=" + param.get(key);
}
out.writeBytes(content.trim());
out.flush();
out.close();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = "";
while((line=in.readLine())!=null) {
System.out.println(line);
}
in.close();
//Intent home = new Intent(SyncHttp.this,TimeAndExpensesSKActivity.class);
//startActivity(home);
db.updateTimeExported(1);
db.updateExpensesExported(1);
db.close();
db.close();
if(db.getLogCount()==0){
db.insertSyncDateDetails(getDateandTime());}
else{
db.updateSyncDateDetails(1, getDateandTime());}
} catch (MalformedURLException e) {
e.printStackTrace();
}
this.setResult(FINISH_RESULT);
db.close();
}
I have already added permissions
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
I am really confused why this exception occurring.
Thanks for your help guys.
My app did this too. This usually caused by unstable network connection. What I did was catching this UnknownHostException and modify the code in a way that if UnknownHostException happened, I try to re-fetch the URL again, after several miliseconds sleep.
The basic algorithm is something like this:
private void submitUploadData(String url ,Map<String, String> param) throws IOException
{
URL siteUrl;
boolean isDataSubmitted = false;
while(!isDataSubmitted){
try {
//do your complicated http process
isDataSubmitted = true;
} catch(UnknownHostException uhe){
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
I have also experienced some issues using URLConnections especially HTTPS on the Samsung Galaxy TAB, but i would imagine it probably occurs on other models as well since there are a ton of devices with the same name but made for different markets and mobile providers.
So far i haven't found a way around sorry, since i tend to avoid the URLConnection class due to a ton of other issues it has.
I suggest using the Apache HTTP Client to communicate with your API's. you can google a ton of examples of using it.
Also when looking at your code i would suggest reading a bit more into the try-catch-finally block statements in java. it is really important to properly close connections at the end or in case of errors.
Other possibilities are:
There is no connection of any sort active (mobile or wifi)
You are missing the "http://www." in your url.
I think calling close() on the DataOutputStream before you recieve your input might close the whole connection - try commenting out that line.
Have you checked the URL from the phone's browser?
Please log the URL you pass to the function and try it in your phone's browser. I would think of missing/incorrect protocol specifier and or URL string formation issues of which this particular phone is unforgiving.

Categories

Resources