Requirement of project: communication between windows azure Website and android device using azure mobile services
1)Website is build in VB.NET using Microsoft Windows Azure (server side)
2)Android Application is on Android Device (client side)
The client (Android user) should be able to send data from android device (client side) to Website (Server side) and vice-versa To make this possible i.e. Communcation Between client and sever I am using Mobile Services provided by Microsoft Windows Azure (server side) which use GCM (Google Cloud Messaging)
I have Followed all steps according to the documentation
http://www.windowsazure.com/en-us/develop/mobile/tutorials/get-started-with-push-android/
Also followed all steps as been provided in the above link documentation of Microsoft windows azure
but when I try to send message from Android device towards the website the following error occurs
Error: com.microsoft.windowsazure.mobileservices.MobileServiceException: Error while processing request
Note: GCM (Google Cloud Messaging) gives us an gcm.jar file which is used in the android app to send data towards Server i.e website
ONCREATE CODE
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_to_do);
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
mRegistationId = GCMRegistrar.getRegistrationId(this);
if (mRegistationId.equals("")) {
GCMRegistrar.register(this, SENDER_ID);
}
mProgressBar = (ProgressBar) findViewById(R.id.loadingProgressBar);
// Initialize the progress bar
mProgressBar.setVisibility(ProgressBar.GONE);
try {
// Create the Mobile Service Client instance, using the provided
// Mobile Service URL and key
mClient = new MobileServiceClient(
"url of website",
"POBHgxwAktyxUdeRRpcFyqEcsppwiS99",
this).withFilter(new ProgressFilter());
// Get the Mobile Service Table instance to use
mToDoTable = mClient.getTable(ToDoItem.class);
mTextNewToDo = (EditText) findViewById(R.id.textNewToDo);
// Create an adapter to bind the items with the view
mAdapter = new ToDoItemAdapter(this, R.layout.row_list_to_do);
ListView listViewToDo = (ListView) findViewById(R.id.listViewToDo);
listViewToDo.setAdapter(mAdapter);
// Load the items from the Mobile Service
refreshItemsFromTable();
}
catch (MalformedURLException e) {
createAndShowDialog(new Exception("There was an error creating the Mobile Service. Verify the URL"), "Error");
}
}
On BUTTON click event addItem() is called
public void addItem(View view) {
if (mClient == null) {
return;
}
try
{
// Create a new item
ToDoItem item = new ToDoItem();
item.setText(mTextNewToDo.getText().toString());
item.setComplete(false);
// Insert the new item
mToDoTable.insert(item, new TableOperationCallback<ToDoItem>() {
public void onCompleted(ToDoItem entity, Exception exception, ServiceFilterResponse response) {
if (exception == null) {
if (!entity.isComplete()) {
mAdapter.add(entity);
}
} else {
createAndShowDialog(exception, "Error");
}
}
});
item.setRegistrationId(mRegistationId.equals("") ?
GCMIntentService.getRegistrationId() : mRegistationId);
mTextNewToDo.setText("");
}
catch(Exception ex)
{
}
}
public void checkItem(ToDoItem item) {
if (mClient == null) {
return;
}
// Set the item as completed and update it in the table
item.setComplete(true);
mToDoTable.update(item, new TableOperationCallback<ToDoItem>() {
public void onCompleted(ToDoItem entity, Exception exception, ServiceFilterResponse response) {
if (exception == null) {
if (entity.isComplete()) {
mAdapter.remove(entity);
}
} else {
createAndShowDialog(exception, "Error");
}
}
});
}
private void refreshItemsFromTable() {
// Get the items that weren't marked as completed and add them in the
// adapter
mToDoTable.where().field("complete").eq(val(false)).execute(new TableQueryCallback<ToDoItem>() {
public void onCompleted(List<ToDoItem> result, int count, Exception exception, ServiceFilterResponse response) {
if (exception == null) {
mAdapter.clear();
for (ToDoItem item : result) {
mAdapter.add(item);
}
} else {
createAndShowDialog(exception, "Error");
}
}
});
}
private void createAndShowDialog(Exception exception, String title) {
createAndShowDialog(exception.toString(), title);
}
private void createAndShowDialog(String message, String title) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(message);
builder.setTitle(title);
builder.create().show();
}
private class ProgressFilter implements ServiceFilter {
#Override
public void handleRequest(ServiceFilterRequest request, NextServiceFilterCallback nextServiceFilterCallback,
final ServiceFilterResponseCallback responseCallback) {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (mProgressBar != null) mProgressBar.setVisibility(ProgressBar.VISIBLE);
}
});
nextServiceFilterCallback.onNext(request, new ServiceFilterResponseCallback() {
#Override
public void onResponse(ServiceFilterResponse response, Exception exception) {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (mProgressBar != null) mProgressBar.setVisibility(ProgressBar.GONE);
}
});
if (responseCallback != null) responseCallback.onResponse(response, exception);
}
});
}
}
Figured out that the tutorial is using ' instead of ", which in my case was the problem. The issue was in the Insert script on azure. Hope it helps you :-)
Related
I am using LiveData and RoomDB and my problem is that when I put the observe() on my LiveData and then make the request to fetch updates from the server, it first gives me the previous value that it had requested before and then once the request is done it gives me the new value that it got from the server.
When no previous request have been made it works like I want it to, meaning it will fetch the data straight from the server and then show it, but when a request was previously made and the LiveData already had a value then it will first show the old one and then the new one.
What I want is for it to show only the new one.
The variables (viewModel, repository, etc) are coming from dagger.
Main Activity:
viewModel.getPointGeoLocation(changedyPoints.get(0)).observe(this, new Observer<LatLng>() {
#Override
public void onChanged(#Nullable LatLng latLng) {
if (latLng != null) {...} else {...}}});
ViewModel Class:
public LiveData<LatLng> getPointGeoLocation(Point Point) {
repository.fetchGeoLocationCoordinates(Point);
return repository.getPointGeoLocationNetworkSource();
}
RepositoryImpl Class:
#Override
public void fetchGeoLocationCoordinates(Point Point) {
pointNetworkDataSource.fetchGeoLocations(point);
}
#Override
public LiveData<LatLng> getPointGeoLocationNetworkSource() {
return pointNetworkDataSource.getPointGeoLocationData();
}
NetworkDataSource Class:
public void fetchGeoLocations(Point point) {
executors().getNetworkIO().execute(new Runnable() {
#Override
public void run() {
AuthTokenUtil.waitForAuthToken(authTokenRepository);
AuthToken authToken = authTokenRepository.getAuthToken().getValue();
if (authToken.isValid()) {
pointBackendApi.getGeoLocations(authToken.getToken(), point,
new PointBackendApi.GeoLocationHandler() {
#Override
public void update(LatLng latLng) {
pointGeoLocationData.postValue(latLng);
}
});
} else {
Log.d(TAG, "invalid auth token");
}
}
});
}
public LiveData<LatLng> getPointGeoLocationData() {
return pointGeoLocationData;
}
And Finally the Backend API:
#Override
public void getGeoLocations(String token, Point point, GeoLocationHandler geoLocationHandler) {
http.getJson(POINT_GET_GEO_LOCATION_UPDATE, token, point.domesticAddress.formattedString, new Callback() {
#Override
public void onResponse(#NonNull Call call, #NonNull Response response) {
try (ResponseBody body = response.body()) {
if (body == null || body.contentLength() == 0) {
Log.d(TAG, "received no response");
return;
}
String res = body.string();
LatLng result = new Gson().fromJson(res, LatLng.class);
if (result != null && (result.latitude != 0 && result.longitude != 0)) {
Log.i(TAG, "received" + " points" + result.toString());
geoLocationHandler.update(result);
} else {
geoLocationHandler.update(null);
Log.d(TAG, "Received 0, 0 coordinates");
}
} catch (Exception ex) {
Log.e(TAG, ex.getMessage() != null ? ex.getMessage() : "HTTP problem");
}
}
#Override
public void onFailure(#NonNull Call call, #NonNull IOException e) {
Log.w(TAG, "get failed");
}
});
}
So basically If I have had a response with value null before and then call this API again it will first return null and then return the correct response.
The first method viewModel.getPointGeoLocation() is called multiple times so that might be the issue but for me it seems that it needs to be inside of the method and act when the button is clicked because the method it is in contains a lot of data that the onChanged() should use.
I'm new to android and I tried to create a chat app using Smack 4.1 and Ejabberd.
I have implemented a group chat using MultiUserChat. I have added Messagelistener to listen every new incoming message and add into adapter.
When I enter into chat room and start chat list works very well.
But the problem is when I back to the any other intent and then go back into chat room then when someone messages me, it is received multiple times.
Maybe I set messagelistner multiple times.
Here is my code Activity Class -
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chatiing);
user2 = getIntent().getExtras().getString("JID");
msg_edittext = (EditText)findViewById(R.id.messageEditText);
msgListView = (ListView)findViewById(R.id.msgListView);
msgListView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
chatlist = new ArrayList<ChatMessage>();
chatlist.clear();
chatAdapter = new ChatAdapter(ChattingGroup.this,chatlist);
msgListView.setAdapter(chatAdapter);
autoJoinRoom(user1,room_name,new View(getApplicationContext()));
ImageButton sendButton = (ImageButton)findViewById(R.id.sendMessageButton);
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendTextMessage(view);
}
});
}
public void autoJoinRoom(String user, String room, View view){
LoginActivity activity = new LoginActivity();
XMPPTCPConnection connection = activity.getmService().xmpp.connection;
MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
MultiUserChat multiUserChat = manager.getMultiUserChat(room);
try {
multiUserChat.join(user,"12345");
chatlist.clear();
multiUserChat.addMessageListener(new MessageListener() {
#Override
public void processMessage(Message message) {
if(message.getBody() != null){
Log.d("New Message Received",message.getBody());
chatlist.add(message.getBody());
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
/* Change adapter */
((BaseAdapter) msgListView.getAdapter()).notifyDataSetChanged();
}
});
}
}
});
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException e) {
e.printStackTrace();
}
}
How can I solve this problem ?
I have attached the trigger point code for Facebook App invite dialog.I get callback for onActivityResult but the callback will not be received for the app invite callbacks registered using facebook callback registers. I have tried the same code in native working perfectly fine.But when i develop cordova plugin for android platform facing issue with the callback.PLEASE HELP
if (AppInviteDialog.canShow()) {
AppInviteContent.Builder builder = new AppInviteContent.Builder();
builder.setApplinkUrl(url);
if (picture != null) {
builder.setPreviewImageUrl(picture);
}
showDialogContext = callbackContext;
PluginResult pr = new PluginResult(PluginResult.Status.NO_RESULT);
pr.setKeepCallback(true);
showDialogContext.sendPluginResult(pr);
cordova.setActivityResultCallback(this);
AppInviteDialog appInviteDialog = new AppInviteDialog(cordova.getActivity());
appInviteDialog.show(builder.build());
appInviteDialog.registerCallback(callbackManager, new FacebookCallback<AppInviteDialog.Result>() {
#Override
public void onSuccess(AppInviteDialog.Result result) {
if (showDialogContext != null) {
try {
JSONObject json = new JSONObject();
Bundle bundle = result.getData();
for (String key : bundle.keySet()) {
json.put(key, wrapObject(bundle.get(key)));
}
showDialogContext.success(json);
showDialogContext = null;
} catch (JSONException e) {
showDialogContext.success();
showDialogContext = null;
}
}
}
#Override
public void onCancel() {
FacebookOperationCanceledException e = new FacebookOperationCanceledException();
handleError(e, showDialogContext);
}
#Override
public void onError(FacebookException error) {
Log.e("Activity", String.format("Error: %s", error.toString()));
handleError(error, showDialogContext);
}
});
} else {
callbackContext.error("Unable to show dialog");
}
I am making a network call through volley. On Response success I am trying to store data through SnappyDb which shows that it has stored successfully. But while reading any data is not present. But if I have data outside of response than it saves and reads too. Below is my code. I am struggling in this from last 2 days. Your help will be highly appreciated. Thanks
private void makeApiCall(String key) {
if (Utility.isNetworkAvailable(AddCustomerActivity.this)) {
final String finalKey = key;
showProgressDailog("Adding...");
NetworkEb.apiCallAddUser(customerEb, (key != null && !key.contains(":"))? true : false, new OnJsonResponse() {
#Override
public void onSuccess(JSONObject response) {
try {
int serverId = response.getInt("id");
customerEb.setKey(serverId + "");
customerEb.setSync(true);
snappyDbUtil.saveObjectFromKey("customer", DbName.CUSTOMER.name(), customerEb);
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onError(String response) {
Utility.showToast("Upload failed! Try Again");
progressDialog.dismiss();
}
});
} else {
if (key == null) {
key = snappyDbUtil.getNewKey(DbName.CUSTOMER.name());
customerEb.setKey(key);
customerEb.setSync(false);
Utility.showToast("Saved locally");
}
snappyDbUtil.saveObjectFromKey(key, DbName.CUSTOMER.name(), customerEb);
}
}
I found a solution for this. You need to save the data in UI thread by calling this
runOnUiThread(new Runnable() {
#Override
public void run() {
itemDataModel.setKey("ITEMS:" + key);
itemDataModel.setSync(true);
snappyDbUtil.saveObjectFromKey(itemDataModel.getKey(), DbName.ITEMS.name(), itemDataModel);
}
});
Here you have to also care for the keys to store with which only saves if we provide a db name as shown in the above code.
I am trying to develop a chat application but instead of Google message service I tried writing xmmp node server.
I am able to login in to server.But getting message saying feature not implemented.
<iq to='359648069251166#10.10.25.126/Smack' id='cu03M-5' type='error'><error type='cancel'><feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></iq>
android code
final TelephonyManager mngr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
.setServiceName(IPADRESS)
.setHost(IPADRESS)
.setPort(5222)
.build();
AbstractXMPPConnection conn2 = new XMPPTCPConnection(config);
conn2.setPacketReplyTimeout(1000);
SmackConfiguration.DEBUG = true;
conn2.connect();
conn2.addConnectionListener(new ConnectionListener() {
#Override
public void connected(XMPPConnection connection) {
}
#Override
public void authenticated(XMPPConnection connection, boolean resumed) {
}
#Override
public void connectionClosed() {
}
#Override
public void connectionClosedOnError(Exception e) {
}
#Override
public void reconnectionSuccessful() {
}
#Override
public void reconnectingIn(int seconds) {
}
#Override
public void reconnectionFailed(Exception e) {
}
});
conn2.addAsyncPacketListener(new PacketListener() {
#Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
if (packet != null) {
Log.d("stanza", "received" + packet.toXML());
Toast.makeText(getApplicationContext(), packet.toXML(), Toast.LENGTH_LONG).show();
}
}
}, new PacketFilter() {
#Override
public boolean accept(Stanza packet) {
return true;
}
});
Roster roster = Roster.getInstanceFor(conn2);
//Get all rosters
Collection<RosterEntry> entries = roster.getEntries();
//loop through
for (RosterEntry entry : entries) {
//example: get presence, type, mode, status
Presence entryPresence = roster.getPresence(entry.getUser());
Presence.Type userType = entryPresence.getType();
Presence.Mode mode = entryPresence.getMode();
String status = entryPresence.getStatus();
Log.d("stanza",userType+" "+status);
}
roster.addRosterListener(new RosterListener() {
#Override
public void presenceChanged(Presence presence) {
//Called when the presence of a roster entry is changed
}
#Override
public void entriesUpdated(Collection<String> arg0) {
// Called when a roster entries are updated.
}
#Override
public void entriesDeleted(Collection<String> arg0) {
// Called when a roster entries are removed.
}
#Override
public void entriesAdded(Collection<String> arg0) {
// Called when a roster entries are added.
}
});
conn2.login(mngr.getDeviceId(), "secret");
Presence presence = new Presence(Presence.Type.available);
presence.setStatus("I’m available");
conn2.sendPacket(presence);
ChatManager chatManager = ChatManager.getInstanceFor(conn2);
Chat chat = chatManager.createChat(mngr.getDeviceId(), new ChatMessageListener() {
#Override
public void processMessage(final org.jivesoftware.smack.chat.Chat chat,
final Message message) {
Log.i("MyXMPP_MESSAGE_LISTENER", "Xmpp message received: '"
+ message);
if (message.getType() == Message.Type.chat
&& message.getBody() != null) {
Log.d("stanza", message.toString());
// processMessage(chatMessage);
}
}
});
// Add a packet listener to get messages sent to us
Message message = new Message();
message.setFrom(mngr.getDeviceId());
message.setTo(mngr.getDeviceId());
message.setType(Message.Type.chat);
message.setSubject("jhelloworld");
chat.sendMessage(message);
}catch (Exception e){
Log.d("error",e.getMessage());
}
I took server from here.
server side code.
var startServer = function (done) {
// Sets up the server.
server = new xmpp.C2S.TCPServer({
port: 5222,
domain: 'localhost'
})
server.on('connection', function (client) {
// That's the way you add mods to a given server.
// Allows the developer to register the jid against anything they want
client.on('register', function (opts, cb) {
console.log('REGISTER')
cb(true)
})
// Allows the developer to authenticate users against anything they want.
client.on('authenticate', function (opts, cb) {
console.log('server:', opts.username, opts.password, 'AUTHENTICATING')
if (opts.password === 'secret') {
console.log('server:', opts.username, 'AUTH OK')
cb(null, opts)
} else {
console.log('server:', opts.username, 'AUTH FAIL')
cb(false)
}
})
client.on('online', function () {
console.log('server:', client.jid.local, 'ONLINE')
client.send("")
})
// Stanza handling
client.on('stanza', function (stanza) {
console.log('server:', client.jid.local, 'stanza', stanza.toString())
var from = stanza.attrs.from
stanza.attrs.from = stanza.attrs.to
stanza.attrs.to = from
client.send(stanza)
})
// Stanza handling
client.on('chat', function (stanza) {
console.log('server:', client.jid.local, 'chat', stanza.toString())
client.send(stanza)
});
// On Disconnect event. When a client disconnects
client.on('disconnect', function () {
console.log('server:', client.jid.local, 'DISCONNECT')
})
})
server.on('listening', done)
}
startServer(function (){
console.log("server localhost started at 5222 localport");
});
I tried many solution from stackoverflow and smack community but didnt.
help will be appreciated.