I am writing a Native Android App in which i am using PHP MYSQL to get data from server
In this [Appointment List] i am allowing user to Reschedule an Appointment, but whenever i do tap on item getting blank form, in short not getting data for that particular appointment which i have clicked in a List.
Question
How to show data in a form using AppointmentID ?
Below i am showing all required code written by me [Client & Server Side both]
UpcomingActivity.java:
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
int menuItemIndex = item.getItemId();
String[] menuItems = Cmd;
String CmdName = menuItems[menuItemIndex];
// Check Event Command
if ("Cancel".equals(CmdName))
{
Toast.makeText(UpcomingActivity.this,"Selected Cancel",Toast.LENGTH_LONG).show();
}
else if ("Reschedule".equals(CmdName))
{
Toast.makeText(UpcomingActivity.this,"Selected Update",Toast.LENGTH_LONG).show();
String sAppointmentID = MyArrList.get(info.position).get("UserID").toString();
Log.d(tag, "sAppointmentID :: " + sAppointmentID);
Intent newActivity = new Intent(UpcomingActivity.this, UpdateActivity.class);
newActivity.putExtra("UserID", sAppointmentID);
startActivity(newActivity);
}
return true;
}
UpdateActivity.java:
public void showInfo()
{
final TextView tAppointmentID = (TextView)findViewById(R.id.txtUsername);
final TextView tType = (TextView)findViewById(R.id.txtName);
final TextView tDate = (TextView)findViewById(R.id.txtEmail);
final TextView tTime = (TextView)findViewById(R.id.txtTel);
Button btnSave = (Button) findViewById(R.id.btnSave);
Button btnCancel = (Button) findViewById(R.id.btnCancel);
String url = "http://10.0.2.2/appointments/getByMemberID.php";
Intent intent= getIntent();
final String AppointmentID = intent.getStringExtra("AppointmentID");
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("sAppointmentID", AppointmentID));
String resultServer = getHttpPost(url,params);
String strAppointmentID = "";
String strType = "";
String strDate = "";
String strTime = "";
JSONObject c;
try {
c = new JSONObject(resultServer);
strAppointmentID = c.getString("UserID");
Log.d(TAG, "String strAppointmentID" + strAppointmentID);
strType = c.getString("Type");
Log.d(TAG, "String strType" + strType);
strDate = c.getString("Date");
Log.d(TAG, "String strDate" + strDate);
strTime = c.getString("Time");
Log.d(TAG, "String strTime" + strTime);
if(!strAppointmentID.equals(""))
{
tAppointmentID.setText(strAppointmentID);
tType.setText(strType);
tDate.setText(strDate);
tTime.setText(strTime);
}
else
{
tAppointmentID.setText("-");
tType.setText("-");
tDate.setText("-");
tTime.setText("-");
btnSave.setEnabled(false);
btnCancel.requestFocus();
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
first of all make sure that you have valid AppointmentID and UserIdand
in UpcomingActivity.java at method onContextItemSelected you are not providing AppointmentID instead you are only providing UserID to the Intend
List but in Updateactivity at method showData you are requesting intent.getStringExtra("AppointmentID") which is invaild.
so your update your UpcomingActivity.java should look like this
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
int menuItemIndex = item.getItemId();
String[] menuItems = Cmd;
String CmdName = menuItems[menuItemIndex];
// Check Event Command
if ("Cancel".equals(CmdName))
{
Toast.makeText(UpcomingActivity.this,"Selected Cancel",Toast.LENGTH_LONG).show();
}
else if ("Reschedule".equals(CmdName))
{
Toast.makeText(UpcomingActivity.this,"Selected Update",Toast.LENGTH_LONG).show();
String sAppointmentID = MyArrList.get(info.position).get("UserID").toString();
Log.d(tag, "sAppointmentID :: " + sAppointmentID);
Intent newActivity = new Intent(UpcomingActivity.this, UpdateActivity.class);
newActivity.putExtra("UserID", sAppointmentID);
newActivity.putExtra("AppointmentID", MyArrList.get(info.position).get("AppointmentID").toString());// <== here
startActivity(newActivity);
}
return true;
}
I noticed a couple of issues (might be typos, but I prefer to ask anyway):
You are calling a getByMemberID.php, but you have not included its source code in the question - you do have such service, right? :)
In the onContextItemSelected you are starting the UpdateActivity and pass UserID as extra. But in the showInfo method of that activity you are trying to get AppointmentID from the intent's extras, so it is not processing any data.
1) Try weather your PHP code is working fine or not...
You can do that by running directly on server and passing UserId and appoinmentId as a parameter by ?
For eg.... www.abc.com?sUserId=123?sAppointmentID=456
See weather it's showing you proper output.
2) you are calling getByMemberID.php but you have specified code of it but you are not passing "AppointmentID" for that also check with php code weather you are retriving it ??
3) On call of updateData.php in UpdateActivity.java: you are not providing "AppointmentID" but you are retriving it in php code it will get null value by default which will be an error ofcourse
Related
I am using the following php code to send a push notification to Android application using Azure Notification Hub.
$hub = new NotificationHub("Endpoint=sb://ServiceName.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SharedAccessKey", "ServiceNameNotification");
$message = '{"data":{"message":"This is a sample notification","title":"Sample Notification","action":"Test","action_id":"60"}}';
$notification = new AzureNotification("gcm", $message);
$hub->sendNotification($notification, null);
But unfortunately most of the times the notification is not getting delivered, although I am getting a 201 as the response. Whenever it does get delivered, the results are unpredictable, sometimes the contents of old notifications end up getting shown.
The following code is used to show the notifications in Android app (Xamarin.Android) :
using System;
using Android.App;
using Android.Content;
using Gcm.Client;
using Microsoft.WindowsAzure.MobileServices;
using Newtonsoft.Json.Linq;
using ServiceName.Helpers;
[assembly: Permission(Name = "#PACKAGE_NAME#.permission.C2D_MESSAGE")]
[assembly: UsesPermission(Name = "#PACKAGE_NAME#.permission.C2D_MESSAGE")]
[assembly: UsesPermission(Name = "com.google.android.c2dm.permission.RECEIVE")]
//GET_ACCOUNTS is needed only for Android versions 4.0.3 and below
[assembly: UsesPermission(Name = "android.permission.GET_ACCOUNTS")]
[assembly: UsesPermission(Name = "android.permission.INTERNET")]
[assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")]
namespace ServiceName.Droid
{
[BroadcastReceiver(Permission = Gcm.Client.Constants.PERMISSION_GCM_INTENTS)]
[IntentFilter(new string[] { Gcm.Client.Constants.INTENT_FROM_GCM_MESSAGE },
Categories = new string[] { "#PACKAGE_NAME#" })]
[IntentFilter(new string[] { Gcm.Client.Constants.INTENT_FROM_GCM_REGISTRATION_CALLBACK },
Categories = new string[] { "#PACKAGE_NAME#" })]
[IntentFilter(new string[] { Gcm.Client.Constants.INTENT_FROM_GCM_LIBRARY_RETRY },
Categories = new string[] { "#PACKAGE_NAME#" })]
public class ServiceNameBroadcastReceiver : GcmBroadcastReceiverBase<PushHandlerService>
{
public static string[] senderIDs = new string[] { Constants.SenderID };
public const string TAG = "MyBroadcastReceiver-GCM";
}
// The ServiceAttribute must be applied to the class.
[Service]
public class PushHandlerService : GcmServiceBase
{
public static string RegistrationID { get; private set; }
public PushHandlerService() : base(ServiceNameBroadcastReceiver.senderIDs) { }
protected override void OnMessage(Context context, Intent intent)
{
string message = string.Empty;
string title = string.Empty;
string action = string.Empty;
string action_id = string.Empty;
if (intent.Extras.ContainsKey("title"))
{
title = intent.Extras.Get("title").ToString();
}
if (intent.Extras.ContainsKey("message"))
{
message = intent.Extras.Get("message").ToString();
}
if (intent.Extras.ContainsKey("action"))
{
action = intent.Extras.Get("action").ToString();
}
if (intent.Extras.ContainsKey("action_id"))
{
action_id = intent.Extras.Get("action_id").ToString();
}
// Extract the push notification message from the intent.
if (!string.IsNullOrWhiteSpace(message) || !string.IsNullOrWhiteSpace(title))
{
// Create a notification manager to send the notification.
var notificationManager =
GetSystemService(Context.NotificationService) as NotificationManager;
// Create a new intent to show the notification in the UI.
PendingIntent contentIntent =
PendingIntent.GetActivity(context, 0,
new Intent(this, typeof(MainActivity)), 0);
// Create the notification using the builder.
var builder = new Notification.Builder(context);
builder.SetAutoCancel(false);
if (!string.IsNullOrWhiteSpace(title))
{
builder.SetContentTitle(title);
}
else
{
builder.SetContentTitle("Notification from ServiceName");
}
if (!string.IsNullOrWhiteSpace(message))
{
builder.SetContentText(message);
}
else
{
builder.SetContentText("Hello ServiceName User");
}
builder.SetSmallIcon(Resource.Drawable.ic_stat_icon);
builder.SetContentIntent(contentIntent);
var notification = builder.Build();
// Display the notification in the Notifications Area.
notificationManager.Notify(1, notification);
}
}
protected override void OnError(Context context, string errorId)
{
System.Diagnostics.Debug.WriteLine(
string.Format("Error occurred in the notification: {0}.", errorId));
}
protected override async void OnRegistered(Context context, string registrationId)
{
System.Diagnostics.Debug.WriteLine("The device has been registered with GCM.", "Success!");
// Get the MobileServiceClient from the current activity instance.
MobileServiceClient client = MainActivity.CurrentActivity.CurrentClient;
var push = client.GetPush();
// Define a message body for GCM.
const string templateBodyGCM = "{\"data\":{\"message\":\"$(messageParam)\", \"title\": \"$(titleParam)\", \"action\":\"$(actionParam)\",\"action_id\":\"$(action_idParam)\"}}";
// Define the template registration as JSON.
JObject templates = new JObject();
templates["genericMessage"] = new JObject
{
{"body", templateBodyGCM }
};
try
{
// Make sure we run the registration on the same thread as the activity,
// to avoid threading errors.
MainActivity.CurrentActivity.RunOnUiThread(
// Register the template with Notification Hubs.
async () => {
try
{
await push.RegisterAsync(registrationId, templates);
System.Diagnostics.Debug.WriteLine(
string.Format("Push Installation Id " + push.InstallationId.ToString()));
var res = await MiscServices.RegisterDevice(Settings.UserID, Settings.AccessToken, push.InstallationId.ToString(), "gcm");
if ((bool)res.data)
{
System.Diagnostics.Debug.WriteLine("Registered InstallationId in Server");
}
else
{
System.Diagnostics.Debug.WriteLine("Cannot register with Server" + " " + res.status.StatusCode);
}
}
catch (Exception e)
{
}
});
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(
string.Format("Error with Azure push registration: {0}", ex.Message));
}
}
protected override void OnUnRegistered(Context context, string registrationId)
{
System.Diagnostics.Debug.WriteLine("Unregistered with Azure push registration");
}
}
}
Even test notifications fail to get delivered at times, but mostly test notifications work fine. We can't really figure out where the issue is occurring, any help is much appreciated.
As you successfully sent messages to Azure NH, and got 201 responses. When you send a notification via Notification Hubs, initially it just gets queued up for NH to do processing to figure out all its targets and then eventually NH sends it to the PNS.
This means that when you are using REST API or any of the client SDK, the successful return of your send call only means that the message has been successfully queued up with Notification Hub.
It doesn’t give an insight into what happened when NH eventually got to send the message to PNS. If your notification is not arriving at the client device, there is a possibility that when NH tried to deliver the message to PNS, there was an error e.g. the payload size exceeded the maximum allowed by the PNS or the credentials configured in NH are invalid etc.
To get an insight into the PNS errors, we have introduced a property called EnableTestSend feature. This property is automatically enabled when you send test messages from the portal or Visual Studio client and therefore allows you to see detailed debugging information.
Or you can try to call via RESTful APIs for troubleshooting:
https://mynamespace.servicebus.windows.net/mynotificationhub/messages?api-version=2013-10&test
Please refer to Azure Notification Hubs - Diagnosis guidelines for more info.
I am new to android and got entangle in problem. what i want is to pass an array object or say an arraylist to a php page so that the same can be inserted into the mysql database.To be more precise i would like to develop an app to sync my contacts with phone numbers to my own server.
thanks in advance.
Try like this.
Map<String,Object> productimages = new HashMap<String, Object>();
List<String> datas = new ArrayList<String>();
datas.add("image");
datas.add("small_image");
datas.add("thumbnail");
productimages.put("types",datas);
If your using nemevalue pair use like this.
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("colors[]","red"));
nameValuePairs.add(new BasicNameValuePair("colors[]","white"));
nameValuePairs.add(new BasicNameValuePair("colors[]","black"));
nameValuePairs.add(new BasicNameValuePair("colors[]","green"));
You should be using an API for ex.Rest API. This API will grant the information from your app by an POST action (from you're android app). (transfer data-objects like an array with JSON) Php can decode the JSON and you analyze you're array in php. You can now send specific data into your tables using MYSQL, PDO,..
If the data you transfer needs to be protected, you should use SSL encryption on you're api acces url
Try this
ArrayList <NameValuePair> postparametersSend = new ArrayList <NameValuePair> ();
//This is your file php
String URL = "www.yourserver.com/file.php";
postparameters2send.add (new BasicNameValuePair ("param1", nameParam1));
postparameters2send.add (new BasicNameValuePair ("param2", nameParam2));
postparameters2send.add (new BasicNameValuePair ("param3", nameParam3));
// perform a request and response obtenes JSON array
JSONArray jdata = con.getserverdata (postparametersSend, URL);
//since we are working locally on return will almost immediately
//To give a little realism we say that the process is stopped for a few seconds to
//Observe progressdialog
// We can remove if we
// if what we got is not null
if (jdata! = null && jdata.length ()> 0) {
JSONObject json_data; // create a JSON object
try {
jdata.getJSONObject json_data = (0); // read the first segment in our case the only
System.out.println (json_data);
logstatus = json_data.getInt ("logstatus"); // access the value
Log.e ("LoginStatus", "logstatus =" + logstatus) // show by log we obtained
} Catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace ();
}
// validate the value obtained
if (logstatus == 0) {// [{"logstatus": "0"}]
Log.e ("logStatus", "invalid");
return false;
}
else {// [{"logstatus": "1"}]
Log.e ("logStatus", "valid");
return true;
}
//} else {invalid json obtained WEB verify part.
Log.e ("JSON", "ERROR");
return false;
}
To make the variables you should put this in the php file
<? php
$nameParam1 = $_POST ["nameParam1"];
$nameParam2 = $_POST ["nameParam2"];
$nameParam3 = $_POST ["nameParam3"];
<- Put your code here ->
?>
I would like to parse a string such as p1=6&p2=7&p3=8 into a NameValueCollection.
What is the most elegant way of doing this when you don't have access to the Page.Request object?
There's a built-in .NET utility for this: HttpUtility.ParseQueryString
// C#
NameValueCollection qscoll = HttpUtility.ParseQueryString(querystring);
' VB.NET
Dim qscoll As NameValueCollection = HttpUtility.ParseQueryString(querystring)
You may need to replace querystring with new Uri(fullUrl).Query.
HttpUtility.ParseQueryString will work as long as you are in a web app or don't mind including a dependency on System.Web. Another way to do this is:
NameValueCollection queryParameters = new NameValueCollection();
string[] querySegments = queryString.Split('&');
foreach(string segment in querySegments)
{
string[] parts = segment.Split('=');
if (parts.Length > 0)
{
string key = parts[0].Trim(new char[] { '?', ' ' });
string val = parts[1].Trim();
queryParameters.Add(key, val);
}
}
A lot of the answers are providing custom examples because of the accepted answer's dependency on System.Web. From the Microsoft.AspNet.WebApi.Client NuGet package there is a UriExtensions.ParseQueryString, method that can also be used:
var uri = new Uri("https://stackoverflow.com/a/22167748?p1=6&p2=7&p3=8");
NameValueCollection query = uri.ParseQueryString();
So if you want to avoid the System.Web dependency and don't want to roll your own, this is a good option.
I wanted to remove the dependency on System.Web so that I could parse the query string of a ClickOnce deployment, while having the prerequisites limited to the "Client-only Framework Subset".
I liked rp's answer. I added some additional logic.
public static NameValueCollection ParseQueryString(string s)
{
NameValueCollection nvc = new NameValueCollection();
// remove anything other than query string from url
if(s.Contains("?"))
{
s = s.Substring(s.IndexOf('?') + 1);
}
foreach (string vp in Regex.Split(s, "&"))
{
string[] singlePair = Regex.Split(vp, "=");
if (singlePair.Length == 2)
{
nvc.Add(singlePair[0], singlePair[1]);
}
else
{
// only one key with no value specified in query string
nvc.Add(singlePair[0], string.Empty);
}
}
return nvc;
}
To do this without System.Web, without writing it yourself, and without additional NuGet packages:
Add a reference to System.Net.Http.Formatting
Add using System.Net.Http;
Use this code:
new Uri(uri).ParseQueryString()
https://msdn.microsoft.com/en-us/library/system.net.http.uriextensions(v=vs.118).aspx
I needed a function that is a little more versatile than what was provided already when working with OLSC queries.
Values may contain multiple equal signs
Decode encoded characters in both name and value
Capable of running on Client Framework
Capable of running on Mobile Framework.
Here is my solution:
Public Shared Function ParseQueryString(ByVal uri As Uri) As System.Collections.Specialized.NameValueCollection
Dim result = New System.Collections.Specialized.NameValueCollection(4)
Dim query = uri.Query
If Not String.IsNullOrEmpty(query) Then
Dim pairs = query.Substring(1).Split("&"c)
For Each pair In pairs
Dim parts = pair.Split({"="c}, 2)
Dim name = System.Uri.UnescapeDataString(parts(0))
Dim value = If(parts.Length = 1, String.Empty,
System.Uri.UnescapeDataString(parts(1)))
result.Add(name, value)
Next
End If
Return result
End Function
It may not be a bad idea to tack <Extension()> on that too to add the capability to Uri itself.
If you don't want the System.Web dependency, just paste this source code from HttpUtility class.
I just whipped this together from the source code of Mono. It contains the HttpUtility and all it's dependencies (like IHtmlString, Helpers, HttpEncoder, HttpQSCollection).
Then use HttpUtility.ParseQueryString.
https://gist.github.com/bjorn-ali-goransson/b04a7c44808bb2de8cca3fc9a3762f9c
If you want to avoid the dependency on System.Web that is required to use HttpUtility.ParseQueryString, you could use the Uri extension method ParseQueryString found in System.Net.Http.
Make sure to add a reference (if you haven't already) to System.Net.Http in your project.
Note that you have to convert the response body to a valid Uri so that ParseQueryString (in System.Net.Http)works.
string body = "value1=randomvalue1&value2=randomValue2";
// "http://localhost/query?" is added to the string "body" in order to create a valid Uri.
string urlBody = "http://localhost/query?" + body;
NameValueCollection coll = new Uri(urlBody).ParseQueryString();
I just realized that Web API Client has a ParseQueryString extension method that works on a Uri and returns a HttpValueCollection:
var parameters = uri.ParseQueryString();
string foo = parameters["foo"];
private void button1_Click( object sender, EventArgs e )
{
string s = #"p1=6&p2=7&p3=8";
NameValueCollection nvc = new NameValueCollection();
foreach ( string vp in Regex.Split( s, "&" ) )
{
string[] singlePair = Regex.Split( vp, "=" );
if ( singlePair.Length == 2 )
{
nvc.Add( singlePair[ 0 ], singlePair[ 1 ] );
}
}
}
Just access Request.QueryString. AllKeys mentioned as another answer just gets you an array of keys.
HttpUtility.ParseQueryString(Request.Url.Query) return is HttpValueCollection (internal class). It inherits from NameValueCollection.
var qs = HttpUtility.ParseQueryString(Request.Url.Query);
qs.Remove("foo");
string url = "~/Default.aspx";
if (qs.Count > 0)
url = url + "?" + qs.ToString();
Response.Redirect(url);
Since everyone seems to be pasting his solution.. here's mine :-)
I needed this from within a class library without System.Web to fetch id parameters from stored hyperlinks.
Thought I'd share because I find this solution faster and better looking.
public static class Statics
public static Dictionary<string, string> QueryParse(string url)
{
Dictionary<string, string> qDict = new Dictionary<string, string>();
foreach (string qPair in url.Substring(url.IndexOf('?') + 1).Split('&'))
{
string[] qVal = qPair.Split('=');
qDict.Add(qVal[0], Uri.UnescapeDataString(qVal[1]));
}
return qDict;
}
public static string QueryGet(string url, string param)
{
var qDict = QueryParse(url);
return qDict[param];
}
}
Usage:
Statics.QueryGet(url, "id")
Hit up Request.QueryString.Keys for a NameValueCollection of all query string parameters.
To get all Querystring values try this:
Dim qscoll As NameValueCollection = HttpUtility.ParseQueryString(querystring)
Dim sb As New StringBuilder("<br />")
For Each s As String In qscoll.AllKeys
Response.Write(s & " - " & qscoll(s) & "<br />")
Next s
var q = Request.QueryString;
NameValueCollection qscoll = HttpUtility.ParseQueryString(q.ToString());
I translate to C# version of josh-brown in VB
private System.Collections.Specialized.NameValueCollection ParseQueryString(Uri uri)
{
var result = new System.Collections.Specialized.NameValueCollection(4);
var query = uri.Query;
if (!String.IsNullOrEmpty(query))
{
var pairs = query.Substring(1).Split("&".ToCharArray());
foreach (var pair in pairs)
{
var parts = pair.Split("=".ToCharArray(), 2);
var name = System.Uri.UnescapeDataString(parts[0]);
var value = (parts.Length == 1) ? String.Empty : System.Uri.UnescapeDataString(parts[1]);
result.Add(name, value);
}
}
return result;
}
let search = window.location.search;
console.log(search);
let qString = search.substring(1);
while(qString.indexOf("+") !== -1)
qString = qString.replace("+", "");
let qArray = qString.split("&");
let values = [];
for(let i = 0; i < qArray.length; i++){
let pos = qArray[i].search("=");
let keyVal = qArray[i].substring(0, pos);
let dataVal = qArray[i].substring(pos + 1);
dataVal = decodeURIComponent(dataVal);
values[keyVal] = dataVal;
}
This is my code, I think it's very useful:
public String GetQueryString(string ItemToRemoveOrInsert = null, string InsertValue = null )
{
System.Collections.Specialized.NameValueCollection filtered = new System.Collections.Specialized.NameValueCollection(Request.QueryString);
if (ItemToRemoveOrInsert != null)
{
filtered.Remove(ItemToRemoveOrInsert);
if (!string.IsNullOrWhiteSpace(InsertValue))
{
filtered.Add(ItemToRemoveOrInsert, InsertValue);
}
}
string StrQr = string.Join("&", filtered.AllKeys.Select(key => key + "=" + filtered[key]).ToArray());
if (!string.IsNullOrWhiteSpace(StrQr)){
StrQr="?" + StrQr;
}
return StrQr;
}
I have a url site.com/test.php which has the following code
<?php
$num1 = $_REQUEST['num1'] ;
$num2 = $_REQUEST['num2'] ;
$tot = $num1 + $num2 ;
?>
From an android application using POST/GET num1 and num2 parameters are passed to www.site.com/test.php
How can I make the response in such a way that the android application will be able to get the response from this request.
I tried this
header('Content-Type: application/json');
echo json_encode($response);
but all it does is echo it in the web view and im not able to get the response.Is there someway I can get the response as standard json response,which is not displayed but get it as soon as I hit the url as a response ?
** UPDATE **
#Override
public boolean shouldOverrideUrlLoading (WebView view, String url) {
if(flag) {
URL aURL = new URL(url);
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
// read inputstream to get the json..
...
...
return true;
}
return false
}
#override
public void onPageFinished (WebView view, String url) {
if (url contains "form.html") {
flag = true;
}
}
this is the java code I got from SO , which Im planning to use in the android appication
Seems to be a problem in the handling of the response, not the generation of the JSON. Are you clicking a link to the JSON on a page that is has "form.html" in it? Because that is what seems to be assumed in the code you posted.
It seems to be better to just overload the shouldOverrideUrlLoading and check if the url matches your json page. Something like this:
#Override
public boolean shouldOverrideUrlLoading (WebView view, String url) {
if(url.toLowerCase().contains("www.site.com/test.php")) {
URL aURL = new URL(url);
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
// read inputstream to get the json..
...
...
return true;
}
return false;
}
It might be a good idea to start an activity and load the JSON in that activity using, for example, an AsyncTask (network operations aren't allowed on the UI thread in the latest android APIs), instead of doing URL.openConnection immediately.
I have the registration id and auth token for c2dm. And then I pass store these values in db. and using php, i could send one message to c2dm server. But my problem is I dont know how to receive the message in the application. I am not sure whether my way of getting the message is correct or not. Anyway i will give it below.
I have one activity which registers to the c2dm using registration intent. and one receiver to receive the reg_id and notification message. it is registering with c2dm and not to receive message.
manifest
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION"></action>
<category android:name="my.android.c2dm"></category>
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE"></action>
<category android:name="my.android.c2dm"></category>
</intent-filter>
</receiver>
</application>
C2dmRegistration.class (activity)
Intent objRegIntnet=new Intent("com.google.android.c2dm.intent.REGISTER");
objRegIntnet.putExtra("app",PendingIntent.getBroadcast(this,0,new Intent(),0));
objRegIntnet.putExtra("sender","mymail#gmail.com");
startService(objRegIntnet);
c2dmReceiver
public class c2dmReceiver extends BroadcastReceiver
{
private static String KEY = "c2dmPref";
private static String REGISTRATION_KEY = "registrationKey";
private Context context;
#Override
public void onReceive(Context context, Intent intent)
{
this.context = context;
if (intent.getAction().equals("com.google.android.c2dm.intent.REGISTRATION"))
{
handleRegistration(context, intent);
}
else if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE"))
{
handleMessage(context, intent);
}
}
private void handleRegistration(Context context, Intent intent)
{
//handles registeration
}
private void handleMessage(Context context, Intent intent)
{
String title= intent.getStringExtra("title");
String message= intent.getStringExtra("msg");
Toast.makeText(context,"title : "+title+"\n message : "+message,1).show();
//Do whatever you want with the message
}
please tell what is the mistake i have done...
UPDATE
Hi all, the same code is woring for me today. The mistake i have done is with php code. instaed of passing the values as POST, i sent it was as GET. When I changed it to POST, the toast message is showing. but yet some problems are there.
The title, and msg values are null here.
my php code is :
function sendMessageToPhone($authCode, $deviceRegistrationId, $msgType, $messageText)
{
//$messageText="have a nice day";
//$msgtype="important";
$headers = array('Authorization: GoogleLogin auth=' . $authCode);
$data = array(
'registration_id' => $deviceRegistrationId,
'collapse_key' => $msgType,
'data.message' => $messageText
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://android.apis.google.com/c2dm/send");
if ($headers)
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
Actually i am not sure what type of values should use for collapse_key, and data.message variables.
Please help me...
Thank you...
Finally I found the way of giving collapse_key and and data..
collapse_key should be a string which is a name for a group of messages or a a parthicular type of messages. If we send more than one message with same collapse_key, the latest message will be sent to the device from c2dm server.
Example : $collapse_key = "important";
And the data. is the important thing. This will contain the message that we want to send.
Ex: if we want to send a message "Have a nice day", then i should give a key name to it.
data.="Have a nice day";
here 'wishes' is the key. And in receiver, i should retreive the message with the same key name.
private void handleMessage(Context context, Intent intent)
{
String mywish= intent.getStringExtra("wishes");
Toast.makeText(context,"my wishes : "+mywish,1).show();
}
Sorry to all..
This is my code I have use it for receiving notification form C2DM server, it also shows the notification on notification bar. It is running find you can compare your code with my code and correct the error if any .
I hope this is help.
/**
* Base class for C2D message receiver. Includes constants for the strings used
* in the protocol.
*/
public abstract class C2DMBaseReceiver extends IntentService {
private static final String C2DM_RETRY = "com.google.android.c2dm.intent.RETRY";
public static final String REGISTRATION_CALLBACK_INTENT = "com.google.android.c2dm.intent.REGISTRATION";
private static final String C2DM_INTENT = "com.google.android.c2dm.intent.RECEIVE";
// Logging tag
private static final String TAG = "C2DM";
// Extras in the registration callback intents.
public static final String EXTRA_UNREGISTERED = "unregistered";
public static final String EXTRA_ERROR = "error";
public static final String EXTRA_REGISTRATION_ID = "registration_id";
public static final String ERR_SERVICE_NOT_AVAILABLE = "SERVICE_NOT_AVAILABLE";
public static final String ERR_ACCOUNT_MISSING = "ACCOUNT_MISSING";
public static final String ERR_AUTHENTICATION_FAILED = "AUTHENTICATION_FAILED";
public static final String ERR_TOO_MANY_REGISTRATIONS = "TOO_MANY_REGISTRATIONS";
public static final String ERR_INVALID_PARAMETERS = "INVALID_PARAMETERS";
public static final String ERR_INVALID_SENDER = "INVALID_SENDER";
public static final String ERR_PHONE_REGISTRATION_ERROR = "PHONE_REGISTRATION_ERROR";
// wakelock
private static final String WAKELOCK_KEY = "C2DM_LIB";
private static PowerManager.WakeLock mWakeLock;
private final String senderId;
/**
* The C2DMReceiver class must create a no-arg constructor and pass the
* sender id to be used for registration.
*/
public C2DMBaseReceiver(String senderId) {
// senderId is used as base name for threads, etc.
super(senderId);
this.senderId = senderId;
}
/**
* Called when a cloud message has been received.
*/
protected abstract void onMessage(Context context, Intent intent);
/**
* Called on registration error. Override to provide better error messages.
*
* This is called in the context of a Service - no dialog or UI.
*/
public abstract void onError(Context context, String errorId);
/**
* Called when a registration token has been received.
*/
public void onRegistrered(Context context, String registrationId)
throws IOException {
}
/**
* Called when the device has been unregistered.
*/
public void onUnregistered(Context context) {
}
#Override
public final void onHandleIntent(Intent intent) {
try {
Context context = getApplicationContext();
if (intent.getAction().equals(REGISTRATION_CALLBACK_INTENT)) {
handleRegistration(context, intent);
} else if (intent.getAction().equals(C2DM_INTENT)) {
//**C2DM Start
Bundle extras = intent.getExtras();
String pushNo =extras != null ? extras.getString("pushNo"):"";
String scoreId =extras != null ? extras.getString("scoreId"):"";
String notfId =extras != null ? extras.getString("notfId"):"";
String fromId =extras != null ? extras.getString("fromId"):"";
String toId =extras != null ? extras.getString("toId"):"";
String matchId =extras != null ? extras.getString("matchId"):"";
String msg =extras != null ? extras.getString("msg"):"";
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
int icon = R.drawable.icon;
CharSequence tickerText = "Notification Receive";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
Context context1 = context;
//*****************
final int CUSTOM_VIEW_ID = 1;
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.custom_notification_layout);
contentView.setImageViewResource(R.id.image, R.drawable.icon);
contentView.setTextViewText(R.id.text, "Racquetime \n"+msg);
notification.contentView = contentView;
notification.defaults=Notification.FLAG_ONLY_ALERT_ONCE+Notification.FLAG_AUTO_CANCEL;
Intent notificationIntent;
if(GUIStatics.boolLoginStatus)
{
notificationIntent = new Intent(this,ShowAllNotificationActiviry.class);
}
else{
notificationIntent = new Intent(this, HomeActivity.class);
}
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults |= Notification.DEFAULT_SOUND;
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
notificationIntent.putExtra("Tag", "C2DMBaseReceiver");
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.contentIntent = contentIntent;
mNotificationManager.notify(CUSTOM_VIEW_ID, notification);
//**C2DM End
// onMessage(context, intent);
} else if (intent.getAction().equals(C2DM_RETRY)) {
C2DMessaging.register(context, senderId);
}
} finally {
// Release the power lock, so phone can get back to sleep.
// The lock is reference counted by default, so multiple
// messages are ok.
// If the onMessage() needs to spawn a thread or do something else,
// it should use it's own lock.
mWakeLock.release();
}
}
/**
* Called from the broadcast receiver. Will process the received intent,
* call handleMessage(), registered(), etc. in background threads, with a
* wake lock, while keeping the service alive.
*/
static void runIntentInService(Context context, Intent intent) {
if (mWakeLock == null) {
// This is called from BroadcastReceiver, there is no init.
PowerManager pm = (PowerManager) context
.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
WAKELOCK_KEY);
}
mWakeLock.acquire();
// Use a naming convention, similar with how permissions and intents are
// used. Alternatives are introspection or an ugly use of statics.
String receiver ="com.commonsware.android.c2dm.C2DMReceiver";
intent.setClassName(context, receiver);
context.startService(intent);
}
private void handleRegistration(final Context context, Intent intent) {
final String registrationId = intent
.getStringExtra(EXTRA_REGISTRATION_ID);
String error = intent.getStringExtra(EXTRA_ERROR);
String removed = intent.getStringExtra(EXTRA_UNREGISTERED);
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "dmControl: registrationId = " + registrationId
+ ", error = " + error + ", removed = " + removed);
}
if (removed != null) {
// Remember we are unregistered
C2DMessaging.clearRegistrationId(context);
onUnregistered(context);
return;
} else if (error != null) {
// we are not registered, can try again
C2DMessaging.clearRegistrationId(context);
// Registration failed
Log.e(TAG, "Registration error " + error);
onError(context, error);
if ("SERVICE_NOT_AVAILABLE".equals(error)) {
long backoffTimeMs = C2DMessaging.getBackoff(context);
Log.d(TAG, "Scheduling registration retry, backoff = "
+ backoffTimeMs);
Intent retryIntent = new Intent(C2DM_RETRY);
PendingIntent retryPIntent = PendingIntent
.getBroadcast(context, 0 /* requestCode */, retryIntent,
0 /* flags */);
AlarmManager am = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.ELAPSED_REALTIME, backoffTimeMs,
retryPIntent);
// Next retry should wait longer.
backoffTimeMs *= 2;
C2DMessaging.setBackoff(context, backoffTimeMs);
}
} else {
try {
onRegistrered(context, registrationId);
C2DMessaging.setRegistrationId(context, registrationId);
GUIStatics.registrationID=registrationId;
} catch (IOException ex) {
Log.e(TAG, "Registration error " + ex.getMessage());
}
}
}
My messages only made it through when i started using:
Bundle extras = intent.getExtras();
String message = (String)extras.get("message");
Log.d("Tag", "msg:" + message);