I've found an example of how NFC works. But when I'm attaching the NFC card onResume/OnPause calls. Why?
the function: onNewIntent hasn't called.
The code of Activity:
public class AMain extends Activity {
public static final String MIME_TEXT_PLAIN = "text/plain";
public static final String TAG = "NfcDemo";
private TextView mTextView;
private NfcAdapter mNfcAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.amain);
mTextView = (TextView) findViewById(R.id.tv);
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (mNfcAdapter == null) {
// Stop here, we definitely need NFC
Toast.makeText(this, "This device doesn't support NFC.", Toast.LENGTH_LONG).show();
finish();
return;
}
if (!mNfcAdapter.isEnabled()) {
mTextView.setText("NFC is disabled.");
} else {
mTextView.setText("NFC is enabled.");
}
handleIntent(getIntent());
}
#Override
protected void onResume() {
super.onResume();
/*
* It's important, that the activity is in the foreground (resumed). Otherwise
* an IllegalStateException is thrown.
*/
setupForegroundDispatch(this, mNfcAdapter);
}
#Override
protected void onPause() {
/*
* Call this before onPause, otherwise an IllegalArgumentException is thrown as well.
*/
stopForegroundDispatch(this, mNfcAdapter);
super.onPause();
}
#Override
protected void onNewIntent(Intent intent) {
/*
* This method gets called, when a new Intent gets associated with the current activity instance.
* Instead of creating a new activity, onNewIntent will be called. For more information have a look
* at the documentation.
*
* In our case this method gets called, when the user attaches a Tag to the device.
*/
handleIntent(intent);
}
private void handleIntent(Intent intent) {
String action = intent.getAction();
Log.d(TAG,action);
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
String type = intent.getType();
if (MIME_TEXT_PLAIN.equals(type)) {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
new NdefReaderTask().execute(tag);
} else {
Log.d(TAG, "Wrong mime type: " + type);
}
} else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
// In case we would still use the Tech Discovered Intent
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String[] techList = tag.getTechList();
String searchedTech = Ndef.class.getName();
for (String tech : techList) {
if (searchedTech.equals(tech)) {
new NdefReaderTask().execute(tag);
break;
}
}
}
}
/**
* #param activity The corresponding {#link Activity} requesting the foreground dispatch.
* #param adapter The {#link NfcAdapter} used for the foreground dispatch.
*/
public static void setupForegroundDispatch(final Activity activity, NfcAdapter adapter) {
final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass());
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
final PendingIntent pendingIntent = PendingIntent.getActivity(activity.getApplicationContext(), 0, intent, 0);
IntentFilter[] filters = new IntentFilter[1];
String[][] techList = new String[][]{};
// Notice that this is the same filter as in our manifest.
filters[0] = new IntentFilter();
filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
filters[0].addCategory(Intent.CATEGORY_DEFAULT);
try {
filters[0].addDataType(MIME_TEXT_PLAIN);
} catch (MalformedMimeTypeException e) {
throw new RuntimeException("Check your mime type.");
}
adapter.enableForegroundDispatch(activity, pendingIntent, filters, techList);
}
/**
* #param activity The corresponding {#link BaseActivity} requesting to stop the foreground dispatch.
* #param adapter The {#link NfcAdapter} used for the foreground dispatch.
*/
public static void stopForegroundDispatch(final Activity activity, NfcAdapter adapter) {
adapter.disableForegroundDispatch(activity);
}
/**
* Background task for reading the data. Do not block the UI thread while reading.
*
* #author Ralf Wondratschek
*
*/
private class NdefReaderTask extends AsyncTask<Tag, Void, String> {
#Override
protected String doInBackground(Tag... params) {
Tag tag = params[0];
Ndef ndef = Ndef.get(tag);
if (ndef == null) {
// NDEF is not supported by this Tag.
return null;
}
NdefMessage ndefMessage = ndef.getCachedNdefMessage();
NdefRecord[] records = ndefMessage.getRecords();
for (NdefRecord ndefRecord : records) {
if (ndefRecord.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT)) {
try {
return readText(ndefRecord);
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Unsupported Encoding", e);
}
}
}
return null;
}
private String readText(NdefRecord record) throws UnsupportedEncodingException {
/*
* See NFC forum specification for "Text Record Type Definition" at 3.2.1
*
* http://www.nfc-forum.org/specs/
*
* bit_7 defines encoding
* bit_6 reserved for future use, must be 0
* bit_5..0 length of IANA language code
*/
byte[] payload = record.getPayload();
// Get the Text Encoding
String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16";
// Get the Language Code
int languageCodeLength = payload[0] & 0063;
// String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII");
// e.g. "en"
// Get the Text
return new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
}
#Override
protected void onPostExecute(String result) {
if (result != null) {
mTextView.setText("Read content: " + result);
}
}
}
}
Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.nfc"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.NFC" />
<uses-feature
android:name="android.hardware.nfc"
android:required="true" />
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.nfc.AMain"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED"/>
</intent-filter>
<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="#xml/nfc_tech_filter" />
</activity>
</application>
</manifest>
You should add NfcAdapter.ACTION_TAG_DISCOVERED to your intent filter. Your current intent filter( filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);) only catches NFC tag containin NDEF messages.
by changing your filter to
filters[0].addAction(NfcAdapter.ACTION_TAG_DISCOVERED);
you should get what you want.
Hi have you set the <uses-permission android:name="android.permission.NFC" /> in your ,manifest?
Related
I'm very new to android studio and in my first app I want to build an sos app, my sos app specifically sends a message via sms with the current location. When I first built it, it only works on android 5.0 and down, it will not work in 6.0 and up and now I've tried to look at the logcat and the logcat says it needs a permission to send sms so I gave it a permission using the code below this paragraph and now it runs in android 6.0 but it's not sending messages... {if(checkselfpermission(Manifest.permission.SEND_SMS)==PackageManager.PERMISSION GRANTED);}
can you help me here is my manifest my file
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.ACCESS_COURSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/sos"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--
ATTENTION: This was auto-generated to add Google Play services to your project for
App Indexing. See https://g.co/AppIndexing/AndroidStudio for more information.
-->
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name=".DisplayContactActivity"
android:label="#string/title_activity_display_contact"
android:parentActivityName=".MainActivity"
android:theme="#style/AppTheme.NoActionBar" />
<activity
android:name=".EditContactActivity"
android:label="#string/title_activity_edit_contact"
android:parentActivityName=".DisplayContactActivity"
android:theme="#style/AppTheme.NoActionBar" />
<activity
android:name=".DisplayMessageActivity"
android:label="#string/title_activity_display_message"
android:parentActivityName=".MainActivity"
android:theme="#style/AppTheme.NoActionBar" />
<activity
android:name=".LogInActivity"
android:label="#string/title_activity_log_in"
android:parentActivityName=".MainActivity"
android:theme="#style/AppTheme.NoActionBar"></activity>
</application>
and here is my main activity.
public class MainActivity extends AppCompatActivity {
private static final int PERMISSION_SEND_SMS = 1;
ContactDbAdapter contactDbAdapter;
private GoogleApiClient client;
EditText messageText;
UserDbAdapter userDbAdapter;
Cursor cursor;
TextView locationText;
#Override
public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
return super.checkUriPermission(uri, pid, uid, modeFlags);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
userDbAdapter = new UserDbAdapter(this);
messageText = (EditText) findViewById(R.id.messageText);
locationText = (TextView) findViewById(R.id.locationTextView);
try {
userDbAdapter.open();
} catch (SQLException error) {
Log.e("mytag", "Error open userDbAdapter\n");
}
contactDbAdapter = new ContactDbAdapter(this);
try {
contactDbAdapter.open();
} catch (SQLException error) {
Log.e("mytag", "Error open contactDbAdapter\n");
}
cursor = contactDbAdapter.getContacts();
final Button sos = (Button) findViewById(R.id.redbutton);
final Button finish = (Button) findViewById(R.id.greenbutton);
final CountDownTimer timer = new CountDownTimer(3999, 100) {
public void onTick(long millisUntilFinished) {
assert sos != null;
sos.setText("" + ((int) (millisUntilFinished) / 1000));
}
#TargetApi(Build.VERSION_CODES.M)
public void onFinish() {
sos.setVisibility(View.GONE);
finish.setVisibility(View.VISIBLE);
finish.setText("finish");
SmsManager smsManager = SmsManager.getDefault();
cursor = contactDbAdapter.getContacts();
String msg = messageText.getText().toString() + "#" + locationText.getText().toString();
Log.e("mytag", msg);
if(cursor.moveToFirst()){
do{
if (checkSelfPermission(Manifest.permission.SEND_SMS)==PackageManager.PERMISSION_GRANTED);
String number=cursor.getString(cursor.getColumnIndex(contactDbAdapter.PHONE_NUM));
smsManager.sendTextMessage(number, null, msg, null, null);
}while(cursor.moveToNext());
}
}
};
sos.setTag(1);
sos.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
final int status = (Integer) v.getTag();
if (status != 1) {
sos.setText("sos");
sos.setTag(1);
timer.cancel();
} else {
sos.setTag(0);
timer.start();
}
}
}
);
finish.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
sos.setVisibility(View.VISIBLE);
finish.setVisibility(View.GONE);
sos.callOnClick();
}
}
);
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
switch (id) {
case R.id.contact:
Intent contactIntent = new Intent(getApplicationContext(), LogInActivity.class);
startActivity(contactIntent);
return true;
case R.id.message:
Intent messageIntent = new Intent(getApplicationContext(), DisplayMessageActivity.class);
startActivity(messageIntent);
default:
break;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onStart() {
super.onStart();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client.connect();
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Main Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app deep link URI is correct.
Uri.parse("android-app://com.cse4471.osu.sos_osu/http/host/path")
);
AppIndex.AppIndexApi.start(client, viewAction);
}
#Override
public void onResume() {
super.onResume();
// refresh user message
cursor = userDbAdapter.getUsers();
if (cursor.moveToFirst()) {
messageText.setText(cursor.getString(cursor.getColumnIndex(userDbAdapter.MESSAGE)));
}
// Acquire a reference to the system Location Manager
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.INTERNET}, 10);
return;
}
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
locationText.setText("Latitude:" + location.getLatitude() + ", Longitude:" + location.getLongitude());
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
public void onProviderEnabled(String provider) {
}
public void onProviderDisabled(String provider) {
}
};
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 0, locationListener);
Location loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(loc != null) {
// messageText.setText("Latitude:" + loc.getLatitude() + ", Longitude:" + loc.getLongitude());
locationText.setText("Latitude:" + loc.getLatitude() + ", Longitude:" + loc.getLongitude());
}
}
#Override
public void onStop() {
super.onStop();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Main Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app deep link URI is correct.
Uri.parse("android-app://com.cse4471.osu.sos_osu/http/host/path")
);
AppIndex.AppIndexApi.end(client, viewAction);
client.disconnect();
}
#Override
public void onDestroy() {
super.onDestroy();
if (cursor != null) {
cursor.close();
}
}
this is also the logcat that appeared before I gave the permission to run it on android 6.0
Process: com.cse4471.osu.sos_osu, PID: 23011
java.lang.SecurityException: Sending SMS message: uid 10179 does not have android.permission.SEND_SMS.
at android.os.Parcel.readException(Parcel.java:1620)
at android.os.Parcel.readException(Parcel.java:1573)
at com.android.internal.telephony.ISms$Stub$Proxy.sendTextForSubscriber(ISms.java:842)
at android.telephony.SmsManager.sendTextMessageInternal(SmsManager.java:317)
at android.telephony.SmsManager.sendTextMessage(SmsManager.java:300)
at com.cse4471.osu.sos_osu.MainActivity$1.onFinish(MainActivity.java:119)
at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:127)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5628)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:853)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:737)
I hope you can help me with this.
You can try this :-
Add it in Manifest -
<uses-permission android:name="android.permission.SEND_SMS" />
And use this runtime permission in your activity
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.SEND_SMS},1);
So here is my problem, what I'm trying to do is the following:
I have a simple ListView class that gets the item info (name of the item) from a MySql DB via PHP script and that works fine.
The other part of the ListView item is a ImageView. It represents 3 states the item can be in. A picture of a green "traffic light" means 'its OK', a red one, its 'not OK' and a grey one means 'service not available'. The state change trigger comes from an other app (via gcm) and the message contains a value of -1, 0 or 1 which I want to use to trigger the ImageView changes.
Here is my onCreate method for my Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_channel_list);
mRegistrationProgressBar = (ProgressBar) findViewById(R.id.registrationProgressBar);
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
mRegistrationProgressBar.setVisibility(ProgressBar.GONE);
SharedPreferences sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(context);
boolean sentToken = sharedPreferences
.getBoolean(SENT_TOKEN_TO_SERVER, false);
if (sentToken) {
Log.i(TAG, getString(R.string.gcm_send_message));
} else {
Log.i(TAG, getString(R.string.token_error_message));
}
}
};
// Registering broadcast receiver
registerReceiver();
if (checkPlayServices()) {
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
/*----------------------------------------------------------------------------------------*/
/*---------------------------------AsyncTask that makes the ListView ---------------------*/
/*----------------------------------------------------------------------------------------*/
PostResponseAsyncTask taskRead = new PostResponseAsyncTask(ChannelList.this, this);
taskRead.execute(SERVER_ADDRESS + "Script.php");
BindDictionary<Channel> dict = new BindDictionary<Channel>();
dict.addStringField(R.id.tvName, new StringExtractor<Channel>() {
#Override
public String getStringValue(Channel channel, int position) {
return channel.channel_name;
}
});
FunDapter<Channel> adapter = new FunDapter<>(
ChannelList.this, channelList, R.layout.layout_list, dict);
lvChannel = (ListView) findViewById(R.id.lvChannels);
lvChannel.setAdapter(adapter);
/*----------------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------------*/
}
Then I have the GcmListenerService class:
public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
/**
* Called when message is received.
*
* #param from SenderID of the sender.
* #param data Data bundle containing message data as key/value pairs.
* For Set of keys use data.keySet().
*/
// [START receive_message]
#Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
String commercial = data.getString("commercial");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
Log.d(TAG, "Commercial: " + commercial);
if (from.startsWith("/topics/")) {
// message received from some topic.
} else {
// normal downstream message.
}
// [START_EXCLUDE]
/**
* Production applications would usually process the message here.
* Eg: - Syncing with server.
* - Store message in local database.
* - Update UI.
*/
/**
* In some cases it may be useful to show a notification indicating to the user
* that a message was received.
*/
sendNotification(message);
// [END_EXCLUDE]
}
// [END receive_message]
/**
* Create and show a simple notification containing the received GCM message.
*
* #param message GCM message received.
*/
private void sendNotification(String message) {
Intent intent = new Intent(this, ChannelList.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 , intent, // 0 => Request code
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("GCM Message")
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 , notificationBuilder.build()); // 0 => ID of notification
}
}
Then I have the RegistrationIntentService class:
public class RegistrationIntentService extends IntentService {
private static final String TAG = "RegIntentService";
private static final String[] TOPICS = {"global"};
public static final String SENT_TOKEN_TO_SERVER = "sentTokenToServer";
public static final String REGISTRATION_COMPLETE = "registrationComplete";
public RegistrationIntentService() {
super(TAG);
}
#Override
protected void onHandleIntent(Intent intent) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
try {
// [START register_for_gcm]
// Initially this call goes out to the network to retrieve the token, subsequent calls
// are local.
// R.string.gcm_defaultSenderId (the Sender ID) is typically derived from google-services.json.
// See https://developers.google.com/cloud-messaging/android/start for details on this file.
// [START get_token]
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
// [END get_token]
Log.i(TAG, "GCM Registration Token: " + token);
// TODO: Implement this method to send any registration to your app's servers.
sendRegistrationToServer(token);
// Subscribe to topic channels
subscribeTopics(token);
// You should store a boolean that indicates whether the generated token has been
// sent to your server. If the boolean is false, send the token to your server,
// otherwise your server should have already received the token.
sharedPreferences.edit().putBoolean(SENT_TOKEN_TO_SERVER, true).apply();
// [END register_for_gcm]
} catch (Exception e) {
Log.d(TAG, "Failed to complete token refresh", e);
// If an exception happens while fetching the new token or updating our registration data
// on a third-party server, this ensures that we'll attempt the update at a later time.
sharedPreferences.edit().putBoolean(SENT_TOKEN_TO_SERVER, false).apply();
}
// Notify UI that registration has completed, so the progress indicator can be hidden.
Intent registrationComplete = new Intent(REGISTRATION_COMPLETE);
LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
}
/**
* Persist registration to third-party servers.
*
* Modify this method to associate the user's GCM registration token with any server-side account
* maintained by your application.
*
* #param token The new token.
*/
private void sendRegistrationToServer(String token) {
// Add custom implementation, as needed.
}
/**
* Subscribe to any GCM topics of interest, as defined by the TOPICS constant.
*
* #param token GCM token
* #throws IOException if unable to reach the GCM PubSub service
*/
// [START subscribe_topics]
private void subscribeTopics(String token) throws IOException {
GcmPubSub pubSub = GcmPubSub.getInstance(this);
for (String topic : TOPICS) {
pubSub.subscribe(token, "/topics/" + topic, null);
}
}
// [END subscribe_topics]
}
The InstanceIDListenerService:
public class MyInstanceIDListenerService extends InstanceIDListenerService {
private static final String TAG = "MyInstanceIDLS";
/**
* Called if InstanceID token is updated. This may occur if the security of
* the previous token had been compromised. This call is initiated by the
* InstanceID provider.
*/
// [START refresh_token]
#Override
public void onTokenRefresh() {
// Fetch updated Instance ID token and notify our app's server of any changes (if applicable).
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
// [END refresh_token]
}
And the AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tumex.useralpha"
xmlns:tools="http://schemas.android.com/tools"
>
<uses-permission android:name="android.permission.INTERNET"/>
<!-- [START gcm_permission] -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- [END gcm_permission] -->
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme"
tools:replace="#android:icon"
>
<activity android:name=".Login">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ChannelList"></activity>
<!-- [START gcm_receiver] -->
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="gcm.play.android.samples.com.gcmquickstart" />
</intent-filter>
</receiver>
<!-- [END gcm_receiver] -->
<!-- [START gcm_listener] -->
<service
android:name="com.tumex.useralpha.MyGcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<!-- [END gcm_listener] -->
<!-- [START instanceId_listener] -->
<service
android:name="com.tumex.useralpha.MyInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
<!-- [END instanceId_listener] -->
<service
android:name="com.tumex.useralpha.RegistrationIntentService"
android:exported="false">
</service>
</application>
So how do I go about this, make a ImageView react to values received from gcm message? If I have forgotten anything that can be helpful in solving my problem please let me know. Thank you
I suppose you want to update ImageView in ListView only if Activity with this ListView is showing.
In that case use LocalBroadcastManager:
YourActivity.java
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//int for List, String for Dictionary
String item_id_or_name = intent.getExtra("ITEM_ID_OR_NAME");
int status_for_item = intent.getExtra("ITEM_STATUS");
//find this item in you List or Dictionary
//and set new Status for this item
yourAdapter.notifyDataSetChanged();
}
};
#Override
public void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(YourActivity.this).registerReceiver(receiver,
new IntentFilter("FILTER_NAME"));
}
#Override
public void onPause() {
LocalBroadcastManager.getInstance(YourActivity.this).unregisterReceiver(receiver);
super.onPause();
}
YourGcmListenerService.java:
#Override
public void onMessageReceived(String from, Bundle data) {
//...parse received data
Intent updateStatus = new Intent("FILTER_NAME");
updateStatus.putExtra("ITEM_ID_OR_NAME", id_or_name);
updateStatus.putExtra("ITEM_STATUS", item_status);//-1, 0, 1
LocalBroadcastManager.getInstance(this).sendBroadcast(updateStatus);
//...
}
I am currently working with ActivityRecognitionClient , but unfortunately that Google has announced that the class had been deprecated and to use GoogleApiClient instead.
Not sure if I am doing it wrong or not, I am getting confused with the new API file. I have imported the Google Play Libraries, setup the API v2 key. I followed an online source on coding up the ActivityRecognitionClient version.
Below are the codes of the different files, whenever I switch tab to the actRecog it crashes and points the error to this line with a null pointer exception.
mActivityRecognitionPendingIntent = PendingIntent.getService(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Full source code below : (API v2 keys are intentionally hidden for privacy purposes.)
MainActivity.java
package com.example.healthgps;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.app.Activity;
import android.app.TabActivity;
import android.content.Context;
import android.content.Intent;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
public class MainActivity extends TabActivity {
TabHost mTabHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTabHost = getTabHost();
TabSpec firstSpec = mTabHost.newTabSpec("Stats");
firstSpec.setIndicator("Stats");
Intent firstIntent = new Intent(this, FirstActivity.class);
firstSpec.setContent(firstIntent);
TabSpec thirdSpec = mTabHost.newTabSpec("ActRecog");
thirdSpec.setIndicator("ActRecog");
Intent thirdIntent = new Intent(this, activityrecignition.class);
thirdSpec.setContent(thirdIntent);
mTabHost.addTab(firstSpec);
mTabHost.addTab(thirdSpec);
}
}
Manifest XML File :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.healthgps"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="17" />
<permission
android:name="com.example.healthgps.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"/>
<uses-permission android:name="com.example.healthgps.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" />
<activity
android:name="com.example.healthgps.MainActivity"
android:label="Health Kit"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".FirstActivity"
android:label="Health Kit" >
</activity>
<activity
android:name=".activityrecignition"
android:label="Health Kit" >
</activity>
<service
android:name="com.example.healthgps.ActivityRecognitionIntentService"
android:label="#string/app_name"
android:exported="false">
</service>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
</manifest>
activityrecignition.java (purposely typo for the name)
package com.example.healthgps;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.ActivityRecognition;
import com.google.android.gms.location.ActivityRecognitionResult;
import com.google.android.gms.location.DetectedActivity;
public class activityrecignition extends FragmentActivity implements ConnectionCallbacks,OnConnectionFailedListener {
public static final int MILLISECONDS_PER_SECOND = 1000;
public static final int DETECTION_INTERVAL_SECONDS = 20;
public static final int DETECTION_INTERVAL_MILLISECONDS =
MILLISECONDS_PER_SECOND * DETECTION_INTERVAL_SECONDS;
private final static int
CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private PendingIntent mActivityRecognitionPendingIntent;
// Store the current activity recognition client
private GoogleApiClient mGoogleApiClient;
private Context mContext;
private Intent intent;
TextView tv;
ActivityRecognitionIntentService ar;
private boolean mInProgress;
public enum REQUEST_TYPE {START, STOP}
private REQUEST_TYPE mRequestType;
Intent i;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.third);
mActivityRecognitionPendingIntent = PendingIntent.getService(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
tv=(TextView) findViewById(R.id.activityname);
mInProgress=false;
ar.onHandleIntent(i);
}
#SuppressLint("NewApi") public static class ErrorDialogFragment extends DialogFragment {
private Dialog mDialog;
#SuppressLint("NewApi") public ErrorDialogFragment() {
super();
mDialog = null;
}
public void setDialog(Dialog dialog) {
mDialog = dialog;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return mDialog;
}
public void show(FragmentManager supportFragmentManager, String tag) {
}
}
#Override
protected void onActivityResult(
int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case CONNECTION_FAILURE_RESOLUTION_REQUEST :
switch (resultCode) {
case Activity.RESULT_OK :
break;
}
}
}
private boolean servicesConnected() {
int resultCode =
GooglePlayServicesUtil.
isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == resultCode) {
Log.d("Activity Recognition", "Google Play services is available.");
return true;
} else {
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
resultCode,
this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
if (errorDialog != null) {
// Create a new DialogFragment for the error dialog
ErrorDialogFragment errorFragment = new ErrorDialogFragment();
// Set the dialog in the DialogFragment
errorFragment.setDialog(errorDialog);
// Show the error dialog in the DialogFragment
errorFragment.show(
getSupportFragmentManager(),
"Activity Recognition");
}
return false;
}
}
public class ActivityRecognitionIntentService extends IntentService {
public ActivityRecognitionIntentService(String name) {
super(name);
// TODO Auto-generated constructor stub
}
private String getNameFromType(int activityType) {
switch(activityType) {
case DetectedActivity.IN_VEHICLE:
return "in_vehicle";
case DetectedActivity.ON_BICYCLE:
return "on_bicycle";
case DetectedActivity.ON_FOOT:
return "on_foot";
case DetectedActivity.STILL:
return "still";
case DetectedActivity.UNKNOWN:
return "unknown";
case DetectedActivity.TILTING:
return "tilting";
}
return "unknown";
}
#Override
protected void onHandleIntent(Intent intent) {
// If the incoming intent contains an update
if (ActivityRecognitionResult.hasResult(intent)) {
// Get the update
ActivityRecognitionResult result =
ActivityRecognitionResult.extractResult(intent);
// Get the most probable activity
DetectedActivity mostProbableActivity =
result.getMostProbableActivity();
/*
* Get the probability that this activity is the
* the user's actual activity
*/
int confidence = mostProbableActivity.getConfidence();
/*
* Get an integer describing the type of activity
*/
int activityType = mostProbableActivity.getType();
String activityName = getNameFromType(activityType);
tv.setText(activityName);
/*
* At this point, you have retrieved all the information
* for the current update. You can display this
* information to the user in a notification, or
* send it to an Activity or Service in a broadcast
* Intent.
*/
} else {
/*
* This implementation ignores intents that don't contain
* an activity update. If you wish, you can report them as
* errors.
*/
tv.setText("There are no updates!!!");
}
}
}
public void onClick(View v){
if(v.getId()==R.id.Start){
startUpdates();
}
if(v.getId()==R.id.Stop){
stopUpdates();
}
}
public void startUpdates() {
// Check for Google Play services
mRequestType = REQUEST_TYPE.START;
if (!servicesConnected()) {
return;
}
// If a request is not already underway
if (!mInProgress) {
// Indicate that a request is in progress
mInProgress = true;
// Request a connection to Location Services
mGoogleApiClient.connect();
//
} else {
/*
* A request is already underway. You can handle
* this situation by disconnecting the client,
* re-setting the flag, and then re-trying the
* request.
*/
mInProgress = true;
mGoogleApiClient.disconnect();
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(mGoogleApiClient, DETECTION_INTERVAL_MILLISECONDS, mActivityRecognitionPendingIntent);
}
}
#Override
public void onConnected(Bundle dataBundle) {
// TODO Auto-generated method stub
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(mGoogleApiClient, DETECTION_INTERVAL_MILLISECONDS, mActivityRecognitionPendingIntent);
/*
* Since the preceding call is synchronous, turn off the
* in progress flag and disconnect the client
*/
mInProgress = false;
mGoogleApiClient.disconnect();
switch (mRequestType) {
case START :
/*
* Request activity recognition updates using the
* preset detection interval and PendingIntent.
* This call is synchronous.
*/
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(mGoogleApiClient, DETECTION_INTERVAL_MILLISECONDS, mActivityRecognitionPendingIntent);
break;
case STOP :
ActivityRecognition.ActivityRecognitionApi.removeActivityUpdates(mGoogleApiClient, mActivityRecognitionPendingIntent);
/*
* An enum was added to the definition of REQUEST_TYPE,
* but it doesn't match a known case. Throw an exception.
*/
default :
try {
throw new Exception("Unknown request type in onConnected().");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
#Override
public void onDisconnected() {
// TODO Auto-generated method stub
mInProgress = false;
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// Turn off the request flag
mInProgress = false;
/*
* If the error has a resolution, start a Google Play services
* activity to resolve it.
*/
if (connectionResult.hasResolution()) {
try {
connectionResult.startResolutionForResult(
this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
} catch (SendIntentException e) {
// Log the error
e.printStackTrace();
}
// If no resolution is available, display an error dialog
} else {
// Get the error code
int errorCode = connectionResult.getErrorCode();
// Get the error dialog from Google Play services
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
errorCode,
this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
// If Google Play services can provide an error dialog
if (errorDialog != null) {
// Create a new DialogFragment for the error dialog
ErrorDialogFragment errorFragment =
new ErrorDialogFragment();
// Set the dialog in the DialogFragment
errorFragment.setDialog(errorDialog);
// Show the error dialog in the DialogFragment
errorFragment.show(
getSupportFragmentManager(),
"Activity Recognition");
}
}
}
public void stopUpdates() {
// Set the request type to STOP
mRequestType = REQUEST_TYPE.STOP;
/*
* Test for Google Play services after setting the request type.
* If Google Play services isn't present, the request can be
* restarted.
*/
if (!servicesConnected()) {
return;
}
// If a request is not already underway
if (!mInProgress) {
// Indicate that a request is in progress
mInProgress = true;
// Request a connection to Location Services
mGoogleApiClient.connect();
//
} else {
/*
* A request is already underway. You can handle
* this situation by disconnecting the client,
* re-setting the flag, and then re-trying the
* request.
*/
}
}
}
In the old code, it contains a part where the ActivityRecognitionClient requires an instantiation, but GoogleApiClient doesn't have.
Is there anyone who manage to switch over to the new API already ? I need some guide to get it there.
Thanks.
you must use GoogleApiClient.Builder in the following way
GoogleApiClient.Builder builder = new GoogleApiClient.Builder(<context>)
.addApi(<some api, i.e LocationServices.API>)
.addConnectionCallbacks(new ConnectionCallbacks() {
#Override
public void onConnectionSuspended(int arg) {}
#Override
public void onConnected(Bundle arg0) {
Intent intent = new Intent(getApplicationContext(), ActivityRecognitionService.class); // your custom ARS class
mPendingIntent = PendingIntent.getService(getApplicationContext(), 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
ActivityRecognition.ActivityRecognitionApi
.requestActivityUpdates(mGoogleApiClient, ACTIVITY_RECOGNITION_INTERVAL, mPendingIntent);}
}
.addOnConnectionFailedListener(new OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult arg0) {
}
});
mGoogleApiClient = builder.build();
mGoogleApiClient.connect();
I'm creating an nfc reader.
I followed the tutorial and it work well.
The result will show the value in the nfc tag eg; 123456 in a Textview.
How can I change the result to put in the Editview?
I already try but still, not luck.
MainActivity.java
package net.vrallev.android.nfc.demo;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
/**
* Activity for reading data from an NDEF Tag.
*
* #author Ralf Wondratschek
*
*/
public class MainActivity extends Activity {
public static final String MIME_TEXT_PLAIN = "text/plain";
public static final String TAG = "NfcDemo";
private TextView mTextView;
private NfcAdapter mNfcAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.textView_explanation);
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (mNfcAdapter == null) {
// Stop here, we definitely need NFC
Toast.makeText(this, "This device doesn't support NFC.", Toast.LENGTH_LONG).show();
finish();
return;
}
if (!mNfcAdapter.isEnabled()) {
mTextView.setText("NFC is disabled.");
} else {
mTextView.setText(R.string.explanation);
}
handleIntent(getIntent());
}
#Override
protected void onResume() {
super.onResume();
/*
* It's important, that the activity is in the foreground (resumed). Otherwise
* an IllegalStateException is thrown.
*/
setupForegroundDispatch(this, mNfcAdapter);
}
#Override
protected void onPause() {
/*
* Call this before onPause, otherwise an IllegalArgumentException is thrown as well.
*/
stopForegroundDispatch(this, mNfcAdapter);
super.onPause();
}
#Override
protected void onNewIntent(Intent intent) {
/*
* This method gets called, when a new Intent gets associated with the current activity instance.
* Instead of creating a new activity, onNewIntent will be called. For more information have a look
* at the documentation.
*
* In our case this method gets called, when the user attaches a Tag to the device.
*/
handleIntent(intent);
}
private void handleIntent(Intent intent) {
String action = intent.getAction();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
String type = intent.getType();
if (MIME_TEXT_PLAIN.equals(type)) {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
new NdefReaderTask().execute(tag);
} else {
Log.d(TAG, "Wrong mime type: " + type);
}
} else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
// In case we would still use the Tech Discovered Intent
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String[] techList = tag.getTechList();
String searchedTech = Ndef.class.getName();
for (String tech : techList) {
if (searchedTech.equals(tech)) {
new NdefReaderTask().execute(tag);
break;
}
}
}
}
/**
* #param activity The corresponding {#link Activity} requesting the foreground dispatch.
* #param adapter The {#link NfcAdapter} used for the foreground dispatch.
*/
public static void setupForegroundDispatch(final Activity activity, NfcAdapter adapter) {
final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass());
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
final PendingIntent pendingIntent = PendingIntent.getActivity(activity.getApplicationContext(), 0, intent, 0);
IntentFilter[] filters = new IntentFilter[1];
String[][] techList = new String[][]{};
// Notice that this is the same filter as in our manifest.
filters[0] = new IntentFilter();
filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
filters[0].addCategory(Intent.CATEGORY_DEFAULT);
try {
filters[0].addDataType(MIME_TEXT_PLAIN);
} catch (MalformedMimeTypeException e) {
throw new RuntimeException("Check your mime type.");
}
adapter.enableForegroundDispatch(activity, pendingIntent, filters, techList);
}
/**
* #param activity The corresponding {#link BaseActivity} requesting to stop the foreground dispatch.
* #param adapter The {#link NfcAdapter} used for the foreground dispatch.
*/
public static void stopForegroundDispatch(final Activity activity, NfcAdapter adapter) {
adapter.disableForegroundDispatch(activity);
}
/**
* Background task for reading the data. Do not block the UI thread while reading.
*
* #author Ralf Wondratschek
*
*/
private class NdefReaderTask extends AsyncTask<Tag, Void, String> {
#Override
protected String doInBackground(Tag... params) {
Tag tag = params[0];
Ndef ndef = Ndef.get(tag);
if (ndef == null) {
// NDEF is not supported by this Tag.
return null;
}
NdefMessage ndefMessage = ndef.getCachedNdefMessage();
NdefRecord[] records = ndefMessage.getRecords();
for (NdefRecord ndefRecord : records) {
if (ndefRecord.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT)) {
try {
return readText(ndefRecord);
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Unsupported Encoding", e);
}
}
}
return null;
}
private String readText(NdefRecord record) throws UnsupportedEncodingException {
/*
* See NFC forum specification for "Text Record Type Definition" at 3.2.1
*
* http://www.nfc-forum.org/specs/
*
* bit_7 defines encoding
* bit_6 reserved for future use, must be 0
* bit_5..0 length of IANA language code
*/
byte[] payload = record.getPayload();
// Get the Text Encoding
String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16";
// Get the Language Code
int languageCodeLength = payload[0] & 0063;
// String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII");
// e.g. "en"
// Get the Text
return new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
}
#Override
protected void onPostExecute(String result) {
if (result != null) {
mTextView.setText("Read content: " + result);
}
}
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="#+id/textView_explanation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/explanation" />
</RelativeLayout>
androidmanifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.vrallev.android.nfc.demo"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.NFC" />
<uses-feature
android:name="android.hardware.nfc"
android:required="true" />
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="net.vrallev.android.nfc.demo.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
</application>
</manifest>
Add an EditText to your layout:
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
And now add this code to MainActivity class:
...
public class MainActivity extends Activity {
public static final String MIME_TEXT_PLAIN = "text/plain";
public static final String TAG = "NfcDemo";
private TextView mTextView;
private NfcAdapter mNfcAdapter;
private EditText mEditText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.textView_explanation);
mEditText = (EditText) findViewById(R.id.editText1);
//Set Text View value in Edit Text
mEditText.setText(mTextView.getText().toString());
...
}
...
The only change you should need to declare the explanation field as an EditText in your XML:
<EditText
android:id="#+id/textView_explanation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/explanation" />
Since EditText subclasses TextView, you don't even need to modify your code, unless of course you want to call a function that is only in EditText.
Is this the problem you were having, or did I misunderstand?
I am very new in android and web services. I am trying to login into my android app where the data is coming from web service and at the same time I want to register the Id of android device using GCM in web server database. Until now I have done so far. If possible please give me your time to assets me.
Config.Java
public class Config {
static final String SERVER_URL = "http://example/stich/wsTest/?c=profile&func=login";
static final String GOOGLE_SENDER_ID = "499319758496";
static final String TAG = "GCM";
static final String DISPLAY_MESSAGE_ACTION = "com.google.android.gcm.demo.app.DISPLAY_MESSAGE";
static final String EXTRA_MESSAGE = "message";
}
Controller.java
public class Controller extends Application {
private final int MAX_ATTEMPTS = 5;
private final int BACKOFF_MILLI_SECONDS = 2000;
private final Random random = new Random();
/**
* Creating post request and store GCM RegistrationID, email and password in
* database on our web server for later use.
*
* #param context
* #param email
* #param password
* #param RegistrationID
*/
void register(final Context context, String email, String password,
final String RegistrationID) {
Log.i(Config.TAG, "registering device (RegistrationID = "
+ RegistrationID + ")");
String serverUrl = Config.SERVER_URL;
Map<String, String> params = new HashMap<String, String>();
params.put("androidToken", RegistrationID);
params.put("email", email);
params.put("password", password);
long backoff = BACKOFF_MILLI_SECONDS + random.nextInt(1000);
// Once GCM returns a RegistrationID, we need to register on our server.
// As the server might be down, we will retry it a couple of times.
for (int i = 1; i <= MAX_ATTEMPTS; i++) {
Log.d(Config.TAG, "Attempt #" + i + "to register");
try {
// Send Broadcast to Show message on screen
displayMessageOnScreen(context, context.getString(
R.string.server_registering, i, MAX_ATTEMPTS));
// Post registration values to web server
post(serverUrl, params);
GCMRegistrar.setRegisteredOnServer(context, true);
// Send Broadcast to Show message on screen
String message = context.getString(R.string.server_registered);
displayMessageOnScreen(context, message);
return;
} catch (IOException e) {
// Here we are simplifying and retrying on any error; in a real
// application, it should retry only on unrecoverable errors
// (like HTTP error code 503).
Log.e(Config.TAG, "Failed to register on attempt " + i + ":"
+ e);
if (i == MAX_ATTEMPTS) {
break;
}
try {
Log.d(Config.TAG, "Sleeping for " + backoff
+ " ms before retry");
Thread.sleep(backoff);
} catch (InterruptedException e1) {
// Activity finished before we complete - exit.
Log.d(Config.TAG,
"Thread interrupted: abort remaining retries!");
Thread.currentThread().interrupt();
return;
}
// increase backoff exponentially
backoff *= 2;
}
}
String message = context.getString(R.string.server_register_error,
MAX_ATTEMPTS);
// Send Broadcast to show message on screen
displayMessageOnScreen(context, message);
}
/**
* Unregister device from GCM server and also creating a post request on
* server to delete stored RegistrationID from database on our web server.
*
* #param context
* #param RegistrationID
*/
void unregister(final Context context, final String RegistrationID) {
Log.i(Config.TAG, "unregistering device (regId =" + RegistrationID
+ ")");
String serverUrl = Config.CLIPME_SERVER_URL + "/unregister";
Map<String, String> params = new HashMap<String, String>();
params.put("regId", RegistrationID);
try {
post(serverUrl, params);
GCMRegistrar.setRegisteredOnServer(context, false);
String message = context.getString(R.string.server_unregistered);
displayMessageOnScreen(context, message);
} catch (IOException e) {
// At this point the device is unregistered from GCM, but still
// registered in the our server.
// We could try to unregister again, but it is not necessary:
// if the server tries to send a message to the device, it will get
// a "NotRegistered" error message and should unregister the device.
String message = context.getString(
R.string.server_unregister_error, e.getMessage());
displayMessageOnScreen(context, message);
}
}
/**
* Create HTTP Post request to server, requested url is defined in
* Config.java.
*
* #param endpoint
* #param params
* #throws IOException
*/
private void post(String endpoint, Map<String, String> params) throws IOException {
URL url;
try {
url = new URL(endpoint);
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Invalid url: " + endpoint);
}
StringBuilder bodyBuilder = new StringBuilder();
Iterator<Entry<String, String>> iterator = params.entrySet().iterator();
// constructs the POST body using the parameters
while (iterator.hasNext()) {
Entry<String, String> param = iterator.next();
bodyBuilder.append(param.getKey()).append('=')
.append(param.getValue());
if(iterator.hasNext()){
bodyBuilder.append('&');
}
}
String body = bodyBuilder.toString();
Log.v(Config.TAG, "Posting'" +body + "'to"+url);
byte[] bytes = body.getBytes();
HttpURLConnection conn = null;
try{
Log.e("URL",">" + url);
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setFixedLengthStreamingMode(bytes.length);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
//Post the request
OutputStream out = conn.getOutputStream();
out.write(bytes);
out.close();
//handle the response
int status = conn.getResponseCode();
//If response is not success
if(status != 200){
throw new IOException("Get failed with error code" + status);
}
}finally{
if (conn != null){
conn.disconnect();
}
}
}
/**
* Checks internet connectivity.
* #return false
*/
public boolean isConnectingToInternet(){
ConnectivityManager connectivity = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if(connectivity != null){
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if(info != null){
for(int i = 0; i < info.length; i++)
if(info[i].getState() == NetworkInfo.State.CONNECTED);
{
return true;
}
}
}
return false;
}
/**
* Send broadcast to show message on activity, broadcast receiver mHandleMessageReceiver
* defined in Login.java.
* #param context
* #param message
*/
void displayMessageOnScreen(Context context, String message) {
Intent intent = new Intent(Config.DISPLAY_MESSAGE_ACTION);
intent.putExtra(Config.EXTRA_MESSAGE, message);
// Send Broadcast to Broadcast receiver with message
context.sendBroadcast(intent);
}
/**
* It displays the simple Alert dialog
* #param context
* #param title
* #param message
* #param status
*/
#SuppressWarnings("deprecation")
public void showAlertDialog(Context context, String title, String message,
Boolean status) {
AlertDialog alertDialog = new AlertDialog.Builder(context).create();
//Set Dialog Title
alertDialog.setTitle(title);
//Set Dialog Message
alertDialog.setMessage(message);
if(status != null)
//set alert dialog icon
alertDialog.setIcon((status) ? R.drawable
.ic_launcher : R.drawable.ic_launcher);
//Set OK button
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(final DialogInterface dialog, final int which) {
}
});
alertDialog.show();
}
private PowerManager.WakeLock wakeLock;
/**
* Device wakeup when any push notification reveived.
* #param context
*/
#SuppressWarnings("deprecation")
#SuppressLint("Wakelock")
public void acquireWakeLock (Context context){
if (wakeLock != null) wakeLock.release();
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.ON_AFTER_RELEASE, "WakeLock");
wakeLock.acquire();
}
public void releaseWakeLock(){
if (wakeLock != null) wakeLock.release();
wakeLock =null;
}
}
LoginActivity.java
public class LoginActivity extends Activity {
EditText inputEmail;
EditText inputPassword;
Button loginBtn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
final Controller controller = (Controller) getApplicationContext();
// Check if the internet coneection is present
if (!controller.isConnectingToInternet()) {
// Internet connection is not present
controller.showAlertDialog(LoginActivity.this,
"Internet Connection Error!!", "Please connect your"
+ "device to internet.", false);
// Stop executing code by return
return;
}
// Check if GCM configuration is set
if (Config.SERVER_URL == null || Config.GOOGLE_SENDER_ID == null
|| Config.SERVER_URL.length() == 0
|| Config.GOOGLE_SENDER_ID.length() == 0) {
// GCM sender id / server url is missing
controller.showAlertDialog(LoginActivity.this,
"Configuration Error!",
"Please set your Server URL and GCM Sender Id", false);
// Stop executing code by return
return;
}
inputEmail = (EditText) findViewById(R.id.email);
inputPassword = (EditText) findViewById(R.id.password);
loginBtn = (Button) findViewById(R.id.btnLogin);
loginBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Get data from EditText
String email = inputEmail.getText().toString();
String password = inputPassword.getText().toString();
// Check if the user filled the form
if (email.trim().length() > 0 && password.trim().length() > 0) {
// Launch MainActivity
Intent i = new Intent(getApplicationContext(), MainActivity.class);
// Registering user to our server
// Sending registration details to MainActivity
i.putExtra("email", email);
startActivity(i);
finish();
} else {
// User donĀ“t filled that data
controller.showAlertDialog(LoginActivity.this,
"Login Error",
"Please enter your full details", false);
}
}
});
}
}
GCMIntentService.java
public class GCMIntentService extends GCMBaseIntentService {
private static final String TAG = "GCMIntentService";
private Controller controller = null;
public GCMIntentService() {
// Call extended class Constructor GCMBaseIntentService
super(Config.GOOGLE_SENDER_ID);
}
/**
* Method called on Error
**/
#Override
protected void onError(Context context, String errorId) {
if(controller == null)
controller = (Controller) getApplicationContext();
Log.i(TAG, "Received error: " + errorId);
controller.displayMessageOnScreen(context,
getString(R.string.gcm_error, errorId));
}
/**
* Method called on Receiving a new message from GCM server
**/
#Override
protected void onMessage(Context context, Intent intent) {
if(controller == null)
controller = (Controller) getApplicationContext();
Log.i(TAG, "Received message");
String message = intent.getExtras().getString("price");
controller.displayMessageOnScreen(context, message);
// notifies user
generateNotification(context, message);
}
#Override
protected boolean onRecoverableError(Context context, String errorId) {
if(controller == null)
controller = (Controller) getApplicationContext();
// log message
Log.i(TAG, "Received recoverable error: " + errorId);
controller.displayMessageOnScreen(context,
getString(R.string.gcm_recoverable_error,
errorId));
return super.onRecoverableError(context, errorId);
}
/**
* Create a notification to inform the user that server has sent a message.
*/
#SuppressWarnings("deprecation")
private void generateNotification(Context context, String message) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
String title = context.getString(R.string.app_name);
Intent notificationIntent = new Intent(context, MainActivity.class);
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent =
PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
//notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Play default notification sound
// notification.defaults |= Notification.DEFAULT_SOUND;
//notification.sound = Uri.parse(
// "android.resource://"
// + context.getPackageName()
// + "your_sound_file_name.mp3");
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
/**
* Method called on device registered
**/
#Override
protected void onRegistered(Context context, String RegistrationID) {
// Get Global Controller Class object (see application tag in
// AndroidManifest.xml)
if (controller == null)
controller = (Controller) getApplicationContext();
Log.i(TAG, "Device registered: regId = " + RegistrationID);
controller.displayMessageOnScreen(context,
"Your device registred with GCM");
Log.d("NAME", MainActivity.email);
controller.register(context, MainActivity.password, MainActivity.email,
RegistrationID);
}
/**
* Method called on device unregistred
**/
#Override
protected void onUnregistered(Context context, String RegistrationID) {
if (controller == null)
controller = (Controller) getApplicationContext();
Log.i(TAG, "Device unregistered");
controller.displayMessageOnScreen(context,
getString(R.string.gcm_unregistered));
controller.unregister(context, RegistrationID);
}
}
MainActivity.java
public class MainActivity extends Activity {
// label to display gcm message
TextView lblMessage;
Controller controller;
// Asyntask
AsyncTask<Void, Void, Void> mRegisterTask;
static String email;
static String password;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
controller = (Controller) getApplicationContext();
// Check if Internet present
if (!controller.isConnectingToInternet()) {
// Internet Connection is not present
controller.showAlertDialog(MainActivity.this,
"Internet Connection Error",
"Please connect to Internet connection", false);
// stop executing code by return
return;
}
// Getting email from intent
Intent i = getIntent();
email = i.getStringExtra("email");
password = i.getStringExtra("password");
// Make sure the device has the proper dependencies.
GCMRegistrar.checkDevice(this);
// Make sure the manifest permissions was properly set
GCMRegistrar.checkManifest(this);
lblMessage = (TextView) findViewById(R.id.lblMessage);
// Register custom Broadcast receiver to show messages on activity
registerReceiver(mHandleMessageReceiver, new IntentFilter(
Config.DISPLAY_MESSAGE_ACTION));
// Get GCM registration id
final String regId = GCMRegistrar.getRegistrationId(this);
// Check if regid already presents
if (regId.equals("")) {
// Register with GCM
GCMRegistrar.register(this, Config.GOOGLE_SENDER_ID);
} else {
// Device is already registered on GCM Server
if (GCMRegistrar.isRegisteredOnServer(this)) {
// Skips registration.
Toast.makeText(getApplicationContext(),
"Already registered with GCM Server", Toast.LENGTH_LONG)
.show();
} else {
// Try to register again, but not in the UI thread.
// It's also necessary to cancel the thread onDestroy(),
// hence the use of AsyncTask instead of a raw thread.
final Context context = this;
mRegisterTask = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
// Register on our server
// On server creates a new user
controller.register(context, email, regId, regId);
return null;
}
#Override
protected void onPostExecute(Void result) {
mRegisterTask = null;
}
};
// execute AsyncTask
mRegisterTask.execute(null, null, null);
}
}
}
private BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String newMessage = intent.getExtras().getString(
Config.EXTRA_MESSAGE);
// Waking up mobile if it is sleeping
controller.acquireWakeLock(getApplicationContext());
// Display message on the screen
lblMessage.append(newMessage + "");
Toast.makeText(getApplicationContext(),
"Got Message: " + newMessage, Toast.LENGTH_LONG).show();
// Releasing wake lock
controller.releaseWakeLock();
}
};
#Override
protected void onDestroy() {
// Cancel AsyncTask
if (mRegisterTask != null) {
mRegisterTask.cancel(true);
}
try {
// Unregister Broadcast Receiver
unregisterReceiver(mHandleMessageReceiver);
// Clear internal resources.
GCMRegistrar.onDestroy(this);
} catch (Exception e) {
Log.e("UnRegister Receiver Error", "> " + e.getMessage());
}
super.onDestroy();
}
}
Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.appname"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19" />
<!-- GCM connects to Internet Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!--
Creates a custom permission so only this app can receive its messages.
NOTE: the permission *must* be called PACKAGE.permission.C2D_MESSAGE,
where PACKAGE is the application's package name.
-->
<permission
android:name="com.example.appname.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.appname.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive data message. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- Network State Permissions to detect Internet status -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Permission to vibrate -->
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:name ="com.example.appname.Controller"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.appname.LoginActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.DELETE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="com.idrivecare.familypro" />
</intent-filter>
</activity>
<activity android:name="com.example.appname.MainActivity" />
<!--
BroadcastReceiver that will receive intents from GCM
services and handle them to the custom IntentService.
The com.google.android.c2dm.permission.SEND permission is necessary
so only GCM services can send data messages for the app.
-->
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<!-- <category android:name="com.google.android.gcm.demo.app" /> -->
<category android:name="com.example.appname" />
</intent-filter>
</receiver>
<service android:name="com.example.appname.gcm.GCMIntentService" />
</application>
After I login I get this in LogCat;
05-03 12:02:06.386: D/GCMRegistrar(20407): resetting backoff for com.example.appname
05-03 12:02:06.386: V/GCMRegistrar(20407): Registering app com.example.appname of senders 499319758496
05-03 12:02:06.456: V/GCMBroadcastReceiver(20407): onReceive: com.google.android.c2dm.intent.REGISTRATION
05-03 12:02:06.456: V/GCMBroadcastReceiver(20407): GCM IntentService class: com.example.appname.GCMIntentService
05-03 12:02:06.456: V/GCMBaseIntentService(20407): Acquiring wakelock
Help me if you find any problems in the code.
You are using the old way of registering to GCM, which is deprecated. The new way of registering simply requires calling GoogleCloudMessaing.register method, which is blocking, and therefore you don't have to get the result in the intent service.
You can follow the official GCM demo app if you wish to use the new way.
If you wish to stick with the old way, it can still work, but you'll have to make some fixes :
If your app's package name is com.example.appname, the manifest should use it consistently. Therefore, instead of :
<permission
android:name="com.example.clipme.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.appname.permission.C2D_MESSAGE" />
you should have
<permission
android:name="com.example.appname.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.appname.permission.C2D_MESSAGE" />
In addition, your intent service class com.example.appname.gcm.GCMIntentService is in the package com.example.appname.gcm, but the broadcast receiver you are using - com.google.android.gcm.GCMBroadcastReceiver - looks for it by default in the main package (com.example.appname.GCMIntentService). Therefore it doesn't find it. You shuold either move the service class to the main package or override the broadcast receiver class to change where it expects to find the intent service class.