Windows Azure Service Client - android

I'm trying the my Azure Mobile Service. Below is the code to make a new ToDo item entry. The sample Android code shows how to create a mobile client. I added it to the onCreate method as mentioned in the example.
But the insert always fails. I always get an exception which says com.microsoft.windowsazure.mobileservices.MobileServiceException: Error while processing request.
mClient does get initialized. But, mClient.mCurrentUser is null. Not sure if this is a problem.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
mClient = new MobileServiceClient("https://myservice.azure-mobile.net/",
"slkerjasfi234eSomePrivateKey", this);
Item item = new Item();
item.setText("Awesome item");
item.setComplete(false);
mClient.getTable(Item.class).insert(item,
new TableOperationCallback<Item>() {
public void onCompleted(Item entity,
Exception exception,
ServiceFilterResponse response) {
if (exception == null) {
ShowMessage("Success");
} else {
ShowMessage("Failed");
}
}
});
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

In my case, it looked like the key (parameter 2 in MobileServiceClient constructor) was incorrect. That is how I had downloaded it though. It happened again today and I manually fixed the key and it worked for another service. Believe it was the same issue here. To view your key, you go to your service in Azure and click Manage Keys at the bottom.

Related

Parse Android SDK nested saveInBackground not working

I'm working on an existing Android App with parse back-end (localDatastore is enabled but not used in this context) which has the following object structure:
Object A has an array of objects B
Object B has an array of objects C
I save this object structure using saveInBackground in calling the next saveInBackground in the done SaveCallback in reverse Order(C,B,A). For the inner two that works fine, but the top level object isn't saved.
Here's the code (frame, newStep and order are objects of classes inheriting from the ParseObject class)
frame.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.i("Info", "frame.save callback OK");
frames.add(frame);
newStep.setTimeFrames(frames);
newStep.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.i("Info", "newStep.save callback OK");
List<ProcessingStep> steps = order.getProcessingSteps();
steps.add(newStep);
order.setProcessingSteps(steps);
order.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null){
Log.i("Info", "order.save callback OK");
}else{
Log.i("Info", "order.save callback FAIL");
}
}});
} else {
Log.i("Info", "newStep.save callback FAIL");
e.printStackTrace();
}
}
});
} else {
Log.i("Info", "frame.save callback FAIL");
e.printStackTrace();
}
}
});
In the console log I see only "frame.save callback OK", the "newStep.saveInBackground()" seems to be executed too (object appears in backend) however I never get the log message in the callback.
If I save all objects before synchronously without references to each other first and then call the code here, it seems to work (worked at least once) but took for ever (minutes). Queries from the back-end are super fast and the frame object is also saved almost instantly but the done-callbacks seem to bugging. When it fails I do not get any exception, log anything it just seems to fail silently.
I'm looking for any insight why Parse behaves like that as well as how to fix it.
edit: The problem seems to be with the double relation (A to B and B to C). If I try with only A to B or B to C it works just fine. What remains mysterious to me, however, is why splitting the operation up with callbacks doesn't seem to work.
The problem was the enabled localdatastore. Without localdatastore enabled everything works as it should.

ParseInstallation.getCurrentInstallation().saveInBackground(); not working

I have created an app in iOS that uses Parse to store data and also uses Parse Push for messaging between users. I am now converting the app to Android and trying to use the same Parse backend for both. I am successfully uploading/downloading data and I can even send a message from an Android user to a iOS user, but I can't get my Android device to receive messages. The underlining problem seems to be that I can't get the installation to work. I am calling this block of code from my onCreate function:
Parse.enableLocalDatastore(this);
Parse.initialize(this, "id1", "id2");
ParsePush.subscribeInBackground("", new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.d("com.parse.push", "successfully subscribed to the broadcast channel.");
} else {
Log.e("com.parse.push", "failed to subscribe for push", e);
}
}
});
ParseInstallation.getCurrentInstallation().saveInBackground();
After calling this code I check for a new installation in the database, but nothing ever shows up. It seems as though ParseInstallation.getCurrentInstallation().saveInBackground(); is not doing anything. Am I missing something?
the object associated with the installation on the given device does not have a row in the parse installation table, this is why you are getting the error, there are 2 possible solutions to this problem :
uninstalling the app, and reinstalling it (which is an unacceptable
solution), or
manually clearing the app parse cache. see the answer for how to do
that
This method must be called before you call Parse.initialize...
public static boolean deleteInstallationCache(Context context) {
boolean deletedParseFolder = false;
File cacheDir = context.getCacheDir();
File parseApp = new File(cacheDir.getParent(),"app_Parse");
File installationId = new File(parseApp,"installationId");
File currentInstallation = new File(parseApp,"currentInstallation");
if(installationId.exists()) {
deletedParseFolder = deletedParseFolder || installationId.delete();
}
if(currentInstallation.exists()) {
deletedParseFolder = deletedParseFolder && currentInstallation.delete();
}
return deletedParseFolder;
}
Alternatively, you can use package-private method
ParseInstallation.clearCurrentInstallationFromDisk(Context context)
public static void clearParseInstallation(Context context) {
try {
Method method = ParseInstallation.class.getDeclaredMethod("clearCurrentInstallationFromDisk", Context.class);
method.setAccessible(true);
method.invoke(null, context);
} catch (Exception e) {
Log.e(e);
}
}
add "bolts-android-x.x.x" lib in libs folder.
You can find it in the Parse SDK zip file

android, Force Close in a NanoHTTPD project

I'm implementing a custom web server by using NanoHTTPD.
I have BaseServer class that extends NanoHTTPD:
public class BaseServer extends NanoHTTPD {
public BaseServer(int port) {
super(port);
// TODO Auto-generated constructor stub
}
#Override
public Response serve(String uri, Method method,
Map<String, String> header, Map<String, String> parms,
Map<String, String> files) {
StringBuilder sb = new StringBuilder();
sb.append("<html>");
sb.append("<head><title>Debug Server</title></head>");
sb.append("<body>");
sb.append("<h1>Response</h1>");
sb.append("<p><blockquote><b>URI -</b> ").append(uri).append("<br />");
sb.append("<b>Method -</b> ").append(method)
.append("</blockquote></p>");
sb.append("<h3>Headers</h3><p><blockquote>").append(header)
.append("</blockquote></p>");
sb.append("<h3>Parms</h3><p><blockquote>").append(parms)
.append("</blockquote></p>");
sb.append("<h3>Files</h3><p><blockquote>").append(files)
.append("</blockquote></p>");
sb.append("</body>");
sb.append("</html>");
return new Response(sb.toString());
}
}
and an activity that use this class by this code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
bs.start();
Toast.makeText(this, "Server Started", 1).show();
} catch (IOException e) {
// TODO Auto-generated catch block
Toast.makeText(this, e.getMessage(), 3).show();
}
}
My server start correctly, but when I send a request from my browser, I have force close in my app !
when below code was executed(it is in try block), pointer go to final block!!! (Not cache) and I send a Force Close to my phone !!
ByteBuffer fbuf = f.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, f.length());
f is null (no file sent!) and this code should handle this condition !, dosn't it?!
When you run on Android, and write temp files, you need to add a permission to your application. Without the permission, opening the file will throw an exception and bad things will result. Off the top of my head, I think the permission you need to add to your AndroidManifest.xml is
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Try it and see!
From your code, and without the stacktrace, several possibilities :
bs is null
bs.start() is a blocking operation, so you can't call it in the ui thread.
you lack a permission to listen on a restricted port.

android: how to make sure i posted correctly using httppost

I have a web address www.abc.com/check ... I have created a web service on this address for receiving data. Through an android app i send some data to this address using following code:
public class TestappActivity extends Activity {
EditText ch;
Button btn;
InputStream is;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ch=(EditText)findViewById(R.id.ch);
btn=(Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
sendData();
}
});
}
private void sendData() {
Log.i(getClass().getSimpleName(), "send task - start");
HttpParams p=new BasicHttpParams();
p.setParameter("name", ch.getText());
HttpClient client = new DefaultHttpClient(p);
try {
HttpResponse response=client.execute(new HttpPost("http://www.abc.com/check"));
is=response.getEntity().getContent();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i(getClass().getSimpleName(), "send task - end");
}
}
How can i find if my post was successful ? What do i get back when i post something. ?
[update]Simple solution, you can just check the status code
response.getStatusLine().getStatusCode();
It's a integer(200 means OK, 500 means error on server) , Reference Here
Or a completely check by using the response body
response.getEntity().getContent();
It is generated on the server by your service, so if you want to assure the invocation is really successful, you can return something to client. e.g. a XML string
"<status>OK</status>"
in the response body would be enough. You will get it on client and then do whatever you want to do.
I recommend the simpler solution. Thanks shraddha
I guess baoz is right, but there is one simple alternative to this.
response.getStatusLine.getstatuscode(); //200-successful
It will return numeric response code for success as well as error. Moreover, if the response is negative, it will return you relevant error code so that you can track and catch those errors.
Regards.

logOut from Facebook in Android Phonegap

I have successfully setup the Facebook Plugin by Jos located (https://github.com/jos3000/phonegap-plugins/tree/master/Android/Facebook) - but I can't seem to figure out a way to log the user out. Sure I could tell them to delete the App access on the website then try to login again and click on "Not you?" but I would really rather have a JS Function that does it for me.
Can anyone help provide some guidance on how to do this? I've looked through the files and it looks like there is a way to do it in the facebook.java but I just need to hack something together to connect it to webview. I'm not capable of doing so :) can anyone please help?
This solution is to disable the single sign on feature in the Facebook plugin
in FaceBook.java file
replace DEFAULT_AUTH_ACTIVITY_CODE in the Authorize method [2 overloads] by FORCE_DIALOG_AUTH
in FacebookAuth.Java file
append this to execute method [in the switch case section]
else if (action.equals("performLogout")){
this.performLogout(first);}
//Add this method to FacebookAuth.java class
public void performLogout(final String appid) {
Log.d("PhoneGapLog", "LOGOUT");
final FacebookAuth fba = this;
Runnable runnable = new Runnable() {
public void run() {
fba.mFb = new Facebook(appid);
fba.mFb.setPlugin(fba);
try {
fba.mFb.logout((Activity) fba.ctx);
fba.success(new PluginResult(PluginResult.Status.OK, ""), fba.callback);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
};
this.ctx.runOnUiThread(runnable);
}
//in facebook.js file add the following section
Facebook.prototype.Logout = function(app_id,callback){
PhoneGap.exec(callback,null, "FacebookAuth", "performLogout", [app_id]); };
// in your page add the following code
function LogoutClick() //on logout click
{
appId = "123" ; //your app Id
window.plugins.facebook.Logout(appId,CompleteLogout);
}
function CompleteLogout() //call back function
{
//do some logic for callback
}
//Enjoy..!!

Categories

Resources