My actual code blocks calls perfectly but now I want to identify an incoming SMS number ID and do stuff, like mark as read or whatever ( like Medium and this one ).
I've read a couple articles and threads but it's not even getting the intent, note again that this code works perfectly blocking calls so I'll paste the SMS related information
Manifest.xml
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<service android:name=".CallReceiverService" />
Service with Broadcast receiver
#Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new Notification.Builder(this, SERVICE_CHANNEL_ID)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentText(this.getResources().getString(R.string.stg_ServiceRunning))
.setContentIntent(pendingIntent)
.setCategory(Notification.CATEGORY_CALL)
.build();
startForeground(44332255, notification);
}
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.intent.action.PHONE_STATE"); // related to call feature, ignore
intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
intentFilter.addAction("Telephony.Sms.Intents.SMS_RECEIVED_ACTION");
intentFilter.setPriority(1000);
registerReceiver(callCheckReceiver, intentFilter);
}
private BroadcastReceiver callCheckReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
try {
if (intent.getAction().equals(Telephony.Sms.Intents.SMS_RECEIVED_ACTION)) {
Log.d("Call", "SMS received");
String smsSender = "";
if (intent.getAction().equals(Telephony.Sms.Intents.SMS_RECEIVED_ACTION)) {
Log.d("Call", "SMS received");
String smsSender = "";
for (SmsMessage smsMessage : Telephony.Sms.Intents.getMessagesFromIntent(intent)) {
smsSender = smsMessage.getDisplayOriginatingAddress();
}
if (!isValidPhoneNumber(smsSender)) {
Log.d("Call", "Invalid SMS detected: From " + smsSender);
}
}
if (!isValidPhoneNumber(smsSender)) {
Log.d("Call", "Invalid SMS detected: From " + smsSender);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
public static boolean isValidPhoneNumber(String phoneNumber) {
return android.util.Patterns.PHONE.matcher(phoneNumber).matches();
}
Basically I'm asking the permission in MainActivity, setting them in Manifest and passing the FilterIntent in the Service that IS properly called in Oreo or lower versions of Android. Target API >=19
I don't want to build an app to manage SMS, I just want to intercept the number ID and do things. Can someone advise?
What you need is SMS Retriever API
If you want to detect the SMS, you can simply use
SmsRetrieverClient client = SmsRetriever.getClient(this /* context */);
Task<Void> task = client.startSmsRetriever();
task.addOnSuccessListener(new OnSuccessListener<Void>()
{
#Override
public void onSuccess(Void aVoid)
{
// Successfully started retriever, expect broadcast intent
// ...
}
});
task.addOnFailureListener(new OnFailureListener()
{
#Override
public void onFailure(#NonNull Exception e)
{
// Failed to start retriever, inspect Exception for more details
// ...
}
});
In AndroidManifest.xml simply add receiver
<receiver
android:name=".custom.SMSBroadcastReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED" />
</intent-filter>
</receiver>
Within receiver you can do whatever you want with detected message
public class SMSBroadcastReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction()))
{
Bundle extras = intent.getExtras();
Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS);
switch (status.getStatusCode())
{
case CommonStatusCodes.SUCCESS:
// Get SMS message contents
String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
// Extract one-time code from the message and complete verification
// by sending the code back to your server for SMS authenticity.
break;
case CommonStatusCodes.TIMEOUT:
// Waiting for SMS timed out (5 minutes)
// Handle the error ...
break;
}
}
}
}
It should be noted that SMSRetrieverClient default timeout is 5 minutes.
For creating detectable SMS please follow SMS Creator for Google
Related
I am trying to run a simple multiplication with a remote service. I have AIDL server file declaring and defining methods. In AIDL, i have copied the same AIDL file as server under the server's package name.
I have given the action for the intent filter of server's service.
Still my AIDL client code is not connecting to the service.
AIDLServer:
Manifest
<service
android:name=".CalService"
android:enabled="true"
android:exported="true"
android:process=":remote">
<intent-filter>
<action android:name="mutliply"/>
</intent-filter>
</service>
ICalService.aidl
interface ICalService {
String getMessage(String name);
int getResult(int val1, int val2);
}
CalService.java
public class CalService extends Service {
public CalService() {
}
private final ICalService.Stub binder = new ICalService.Stub() {
#Override
public String getMessage(String name) throws RemoteException {
return "Hello " + name + ". The result is: ";
}
#Override
public int getResult(int val1, int val2) throws RemoteException {
return val1 * val2;
}
};
#Nullable
#Override
public IBinder onBind(Intent intent) {
return binder;
}
}
AIDLCLient:
MainActivity.java
#Override
protected void onStart() {
super.onStart();
editName = (EditText) findViewById(R.id.editName);
editVal1 = (EditText) findViewById(R.id.editVal1);
editVal2 = (EditText) findViewById(R.id.editVal2);
resultView = (TextView) findViewById(R.id.resultView);
if(calService == null) {
Log.v("CALSERVICE", "cal service null");
Intent it = new Intent("multiply");
it.setPackage("com.example.aidlserver");
if(getBaseContext().getApplicationContext().bindService(
it, connection, Context.BIND_AUTO_CREATE
) == true){
Log.v("Bind", "Bind service Succeeded");
} else {
Log.v("Bind", "Bind service failed");
}
} else {
Log.v("Cal", "Cal Service not null");
}
}
#Override
protected void onDestroy() {
super.onDestroy();
unbindService(connection);
}
public void mutiply(View v) {
switch (v.getId()) {
case R.id.btnCal:
int num1 = Integer.parseInt(editVal1.getText().toString());
int num2 = Integer.parseInt(editVal2.getText().toString());
try {
int result = calService.getResult(num1, num2);
String msg = calService.getMessage(editName.getText().toString());
resultView.setText(msg + result);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
private ServiceConnection connection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d("onServiceConnected", "Connected");
calService = ICalService.Stub.asInterface(service);
Toast.makeText(getApplicationContext(), "Service Connected",
Toast.LENGTH_SHORT).show();
}
#Override
public void onServiceDisconnected(ComponentName name) {
Log.d("onServiceDisconnected", "Disconnected");
calService = null;
Toast.makeText(getApplicationContext(), "Service Disconnected",
Toast.LENGTH_SHORT).show();
}
};
The code shows its an implicit intent used while bindService call.
Intent it = new Intent("multiply");
it.setPackage("com.example.aidlserver");
If you are above API level 21, you must update your code with an explicit intent. Please update your code with setClassName() API to make the bind service call with an explicit intent.
Intent it = new Intent("multiply");
it.setClassName("com.example.aidlserver","com.example.aidlserver.CalService");
if(getBaseContext().getApplicationContext().bindService(it, connection, Context.BIND_AUTO_CREATE) == true){
Log.v("Bind", "Bind service Succeeded");
} else {
Log.v("Bind", "Bind service failed");
}
Please note the following:
Caution: To ensure that your app is secure, always use an explicit
intent when starting a Service and don't declare intent filters for
your services. Using an implicit intent to start a service is a
security hazard because you cannot be certain of the service that
responds to the intent, and the user cannot see which service starts.
Beginning with Android 5.0 (API level 21), the system throws an
exception if you call bindService() with an implicit intent.
Ref: https://developer.android.com/guide/components/services
Also check this too,
"To receive implicit intents, you must include the CATEGORY_DEFAULT category in the intent filter"
<category android:name="android.intent.category.DEFAULT"/>
https://developer.android.com/guide/components/intents-filters#Receiving
All you need is to add in client app Manifest, where you want tu bind 3rd party app Service. With the same package name you set in the Intent:
val intent = Intent("example_action")
intent.`package` = "your package name"
bindService(intent, connection, Context.BIND_AUTO_CREATE)
Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.github.asvid.services.client">
<queries>
<package android:name="io.github.asvid.services.server" />
</queries>
...
</manifest>
Alternatively you can stay with compileSdk 29 but I don’t recommend that :)
I am trying to send automatic reply when receiving sms using BroadcastReceiver to listen to sms and SmsManager to send reply but the auto reply is not working.
Note: If I call smsManager.sendTextMessage(phoneNo, null, msg, null, null); from onCreate, it indeed sends a message but the problem is when I am trying to call it from messageReceived.
I have also tried to use registerReceiver instead bindListener but the same happened.
When running on emulator all Toasts are showing (but I can't really check that a message is sent on emulator).
When running on device connected via USB cable, "sending the message" Toast is not showing.
I will really appreciate your help.
Thank you
public class MainActivity extends AppCompatActivity implements SmsListener, View.OnClickListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED){
requestSMSPermission();
}
else{
SmsReceiver.bindListener(this);
Toast.makeText(this, "listening", Toast.LENGTH_SHORT).show();
}
}
#Override
public void messageReceived(String messageText, String sender) {
Toast.makeText(getBaseContext(), "sending the message", Toast.LENGTH_SHORT).show();
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(sender, null, messageText, null, null);
}
private void requestSMSPermission(){
if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.SEND_SMS)){
new AlertDialog.Builder(this)
.setTitle("Permission needed").setMessage("This permission is needed in order to send automatic reply")
.setPositiveButton("ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.SEND_SMS},READ_SMS_PERMISSION_CODE);
}
})
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
}).create().show();
}
else{
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.SEND_SMS},READ_SMS_PERMISSION_CODE);
}
}
}
Receiver class:
public class SmsReceiver extends BroadcastReceiver {
private static SmsListener mListener;
#Override
public void onReceive(Context context, Intent intent) {
Bundle data = intent.getExtras();
Object[] pdus = (Object[]) data.get("pdus");
String sender = null;
for(int i=0; i<pdus.length; i++){
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdus[i]);
sender = smsMessage.getOriginatingAddress();
String messageBody = smsMessage.getMessageBody();
mListener.messageReceived(messageBody,sender);
}
}
public static void bindListener(SmsListener listener) {
mListener = listener;
}
}
Listener interface:
public interface SmsListener {
public void messageReceived(String messageText, String sender);
}
Manifest:
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<receiver android:name=".SmsReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
Ok, I figured out the problem;
This issue happens on api > 26 (maybe even 25).
On api 24 this code above worked just fine and an automatic reply was sent.
The problem is that I requested permission for SEND_SMS (in Manifest I have READ,RECEIVE,SEND) and apparently on api 26 it doesn't really give permission for RECEIVE_SMS so In my code onReceive was never called.
Solution: I have changed the permission above to RECEIVE_SMS and added to onCreate this:
if(ActivityCompat.checkSelfPermission(this,Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.SEND_SMS},111);
}
To conclude: If you want two (or more) permissions from the same family (e.g READ_SMS/SEND_SMS), you need to request for all needed permissions even thought eventually you will see a dialog only once allowing all permissions together.
In API <= 24 it is enough to request only for one permission from the same family (e.g READ_SMS) and you receive the rest
I am using geofence in my app and based on geofence events (Enter or Exit) I want to perform some action. Geofence documentation says that once you set geofence it will trigger events automatically and you can catch this events with IntentService. For that I have made intentservice as below:
GeofenceTransitionsIntentService.java
public class GeofenceTransitionsIntentService extends IntentService {
Handler mHandler;
public GeofenceTransitionsIntentService() {
super("GeofenceTransitionsIntentService");
mHandler = new Handler();
}
#Override
public void onCreate() {
super.onCreate();
Log.e("JK-->>","service started!");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.e("JK-->>","onHandel--->>");
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
if (geofencingEvent.hasError()) {
Log.e("JK-->>","geofenceEvent has error!");
return;
}
int geofenceTransitionType = geofencingEvent.getGeofenceTransition();
if (geofenceTransitionType == Geofence.GEOFENCE_TRANSITION_ENTER) {
Log.e("JK-->>","enter!");
mHandler.post(new DisplayToast(this,"Enter"));
} else if (geofenceTransitionType == Geofence.GEOFENCE_TRANSITION_EXIT) {
mHandler.post(new DisplayToast(this,"Exit"));
Log.e("JK-->>","exit");
}
}
public class DisplayToast implements Runnable {
private final Context mContext;
String mText;
public DisplayToast(Context mContext, String text){
this.mContext = mContext;
mText = text;
}
public void run(){
Toast.makeText(mContext, mText, Toast.LENGTH_SHORT).show();
}
}
}
Now, problem is that when app is open(No matter foreground or background) and I enter or exit in geofence it works fine and show me a toast message and logcat shows log but when I remove app from recent apps there is no toast message showing to me or no log is showing in logcat.
I have tried to find solution on google but mostly all answers suggests to use the service but if i am not wrong then IntentService stops itself automatically after work is done and start itself when any intent received. So, I think it's more efficient to use IntentService to do this task.
UPDATE
I am registering geofence using following line of code.
geofencingClient.addGeofences(getGeofencingRequest(),getGeofencePendingIntent());
and in getGeofencePendingIntent() i am starting intent service using following line of code.
private PendingIntent getGeofencePendingIntent() {
if(geofencePendingIntent != null)
return geofencePendingIntent;
Intent in = new Intent(SetProfileOnlineActivity.this,GeofenceTransitionsIntentService.class);
geofencePendingIntent = PendingIntent.getService(SetProfileOnlineActivity.this,111451,in,PendingIntent.FLAG_UPDATE_CURRENT);
return geofencePendingIntent;
}
This Service will run always :
Goto project java -> right click->New->service->service
name it watchman
watchman.java
public class watchman extends Service
{
NotificationManager mNotifyManager;
NotificationCompat.Builder mBuilder;
NotificationChannel notificationChannel;
String NOTIFICATION_CHANNEL_ID = "1";
public watchman() { }
#Override
public void onCreate()
{
try
{
mNotifyManager = (NotificationManager) getApplicationContext().getSystemService(NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(this, null);
mBuilder.setContentTitle("Insta Promo")
.setContentText("We are ready to help you.")
.setSmallIcon(R.drawable.ic_launcher_background);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "My Notifications", NotificationManager.IMPORTANCE_HIGH);
// Configure the notification channel.
notificationChannel.setDescription("Channel description");
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
notificationChannel.enableVibration(true);
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
mNotifyManager.createNotificationChannel(notificationChannel);
}
else
{
mBuilder.setContentTitle("Insta Promo")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setColor(ContextCompat.getColor(this, R.color.colorAccent))
.setVibrate(new long[]{100, 250})
.setLights(Color.YELLOW, 500, 5000)
.setAutoCancel(true);
}
mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
mNotifyManager.notify(1, mBuilder.build());
startForeground(1, mBuilder.build());
}
catch(Exception e)
{
Log.d(TAG, "EXCEPTION IN SHOWING NOTIFICATION xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...\n");
Log.e("MY_APP", "exception", e);
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
new Thread(new Runnable()
{
public void run()
{
while (true)
{
try
{
Log.d(TAG, "Thread : Running again...\n");
Thread.sleep(10000);
}
catch (InterruptedException e)
{
Log.d(TAG, "Thread : InterruptedException Error in service...\n");
}
}
}
}).start();
return START_STICKY;
}
#Override
public void onDestroy()
{
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent)
{
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
It will get automatically registered in manifest file as you created it as service, no need to update manifest file.
From main activity or from wherever you want to start it call it like
Log.d(TAG, " Good to Go \n");
Log.d(TAG, "Starting Service from main...\n");
Intent intent = new Intent(MainActivity.this, watchman.class);
startService(intent);
Log.d(TAG, "Main has started the service...\n");
Now you even if removed it from recents..., It will be there in memory running always for you, To check it keep eye on logcat. Hope it helps. Its working in project from 4.1 onwards upto latest 8.0 oreo
for showing notifications i am using vibration permission so also making manifest file available for you.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.rushi.oreo">
<uses-permission android:name="android.permission.VIBRATE"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".watchman"
android:enabled="true"
android:exported="true" />
</application>
</manifest>
Hope it really helps you or someone else.
IntentService will stop automatically when the work assigned to it is finished.
If you want a service to run in background with very less chances of getting stopped, it has to be a Foreground Service. Please make sure to start your Service in a background worker thread because by default a Service runs on the main thread.
More details are here - https://developer.android.com/reference/android/app/Service.html#startForeground(int, android.app.Notification)
But please note that making a Service as foreground impacts your phone's battery life too much. And a making a Service as Foreground is also annoying to the user since it shows a notification always and cannot be closed.
You can better use a JobScheduler or Firebase JobDispatcher to schedule background works.
I had found an answer... there was no problem in my code and IntentService was also working perfectly but the mistake was in the testing. I was testing my application on android Oreo running device.
In android oreo google has updated their policy that in foreground they will send location updates any number of times but in background they will send location updates only few times in hour.
The main reason behind it to save the bettery life of device.
For more information about android oreo location updates you can check out this documentation.
Please see edits before answering!
I have an app which contains a BackgroundService class:
public class BackgroundService extends Service {
#Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter();
filter.addAction("com.spotify.music.playbackstatechanged");
filter.addAction("com.spotify.music.metadatachanged");
filter.addAction("com.spotify.music.queuechanged");
registerReceiver(receiver, filter);
Log.e("Playing:", "APP IS PLAYING");
Notification notification = new Notification();
startForeground(1, notification);
}
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
long timeSentInMs = intent.getLongExtra("timeSent", 0L);
String action = intent.getAction();
if (action.equals(BroadcastTypes.METADATA_CHANGED)) {
String trackId = intent.getStringExtra("id");
String artistName = intent.getStringExtra("artist");
String albumName = intent.getStringExtra("album");
String trackName = intent.getStringExtra("track");
int trackLengthInSec = intent.getIntExtra("length", 0);
// Do something with extracted information...
} else if (action.equals(BroadcastTypes.PLAYBACK_STATE_CHANGED)) {
boolean playing = intent.getBooleanExtra("playing", false);
Log.e("Playing:","TRUE");
}
}
};
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
static final class BroadcastTypes {
static final String SPOTIFY_PACKAGE = "com.spotify.music";
static final String PLAYBACK_STATE_CHANGED = SPOTIFY_PACKAGE + ".playbackstatechanged";
static final String METADATA_CHANGED = SPOTIFY_PACKAGE + ".metadatachanged";
}
}
and this is declared in my manifest:
<service
android:name=".BackgroundService"
android:enabled="true" >
<intent-filter>
<action android:name="com.spotify.music.playbackstatechanged" />
<action android:name="com.spotify.music.metadatachanged" />
<action android:name="com.spotify.music.queuechanged" />
</intent-filter>
</service>
So essentially my objective is to have my BackgroundService initialized when my app is opened, and to have it continue to run in the Background doing whatever I need it to do. As of now, I am using logs to determine whether my "setup" is working, but when I run my app, I am unable to see an logs even after I tested all actions that should have triggered my BroadCastReceiver. Furthermore, my persistent notification should have changed had my service been running, but it does not...
Edit::
So, I added logs to my BackgroundService's onCreate() and onReceive() methods, however, neither seem to be appearing. Im wondering, do I need to do something in my launcher activity to initialize the service? Furthermore, no notification is shown so I assume the Service is not being started for some reason...
Latest Edit:
So I added the following code to my Main activity to see if it would make a difference:
startService(new Intent(this,BackgroundService.class));
And after debugging my app, I began to see the following error:
java.lang.RuntimeException: Unable to create service com.aurum.mutify.BackgroundService: java.lang.SecurityException: Isolated process not allowed to call registerReceiver
pointing to my BroadCast Receiver class.
Intent services are designed for short tasks. And your intent handling method is empty.
If you need long running task in the background use standard service and call start foreground. This will minimize chance of system destroying your service.
To learn more go here
EDIT
Try overriding onStartCommand method. this method is called when service is started and usually you do all stuff here. Remember that there are 3 options to return.
Edit 2:
try something like this
in on create
PendingIntent pi;
BroadcastReceiver br;
Intent myIntent;
#Override
public void onCreate()
{
super.onCreate();
myIntent = new Intent("something")
if(Build.Version.SDK_INT >= 16) //The flag we used here was only added at API 16
myIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
//use myIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); if you want to add more than one flag to this intent;
pi = PendingIntent.getBroadcast(context, 1, myIntent, 0);
br = new BroadcastReceiver ()
{
public void onReceive (Context context, Intent i) {
new thread(new Runnable()
{
public void run()
{
//do something
}
}).start();
}
};
And then in on start command
this.registerReceiver(br, new IntentFilter("something"));
My application starts when the device boots (Nexus 7). When my device boots if(action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED)) becomes true. Then the code inside the if crashes because the intent was not really a ACTION_NDEF_DISCOVERED but a boot.
I can put a try catch and then it won't crash. However then NFC won't work. To get NFC to work the application must be closed and reopened.
Is there a way to check the if(action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED)) but have it ignore the booting? It is really annoying because the if is checking for NFC not boot.
#Override
public void onResume()
{
super.onResume();
// NFC code.
Intent intent = getIntent();
String action = intent.getAction();
PendingIntent pi = this.createPendingResult(0x00A, new Intent(), 0);
nfcAdapter.enableForegroundDispatch(this, pi, null, null);
try
{
// NFC transfer. Receiving message here.
if(action != null && action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED))
{
Parcelable[] parcelables = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage inNdefMessage = (NdefMessage) parcelables[0];
NdefRecord[] inNdefRecords = inNdefMessage.getRecords();
NdefRecord NdefRecord_0 = inNdefRecords[0];
String inMsg = new String(NdefRecord_0.getPayload());
Toast.makeText(getApplicationContext(), "Toasty: "+inMsg + action.toString(), Toast.LENGTH_LONG).show();
textInfo.setText(inMsg);
}
}
catch(Exception e)
{
Log.e("NFC", e.getMessage());
}
}
This is the code that checks for BOOTING.
public class BootManager extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED))
{
Intent i = new Intent(context, Login_Activity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
}
In the Login_Activity, Could this be altering the intent?
#Override
protected void onNewIntent(Intent intent)
{
setIntent(intent);
}