i have a background service which is working in background and looking for new SMS and creating notification and showing SMS
public class SmsBoradcast extends BroadcastReceiver {
private static final String SMS = "android.provider.Telephony.SMS_RECEIVED";
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(SMS)){
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[])bundle.get("pdus");
final SmsMessage[] messages = new SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
}
// i want to save message some where befor showing notification
Notification notification = new Notification(context);
notification.sendNotification(context , "new message" , messages[0].getMessageBody());
}
}
}
}
everything is working and I'm receiving notification any time even if application is killed and its in background
now the question is that , how can I save those notifications when app is in background?
I tried room database and shared preferences in my service but not worked !!
**Please do not suggest using other methods. I just want to save data in background service , if its possible
You can create a Interface :
SmsListener
public interface SmsListener {
void onMessageReceived(String message);
}
add a Constructor to the SmsBoradcast and call it you recieve your add, then you can save your data from wherever you have started this broadcast.
Related
I am trying to code APK to identify the received calls are in sim 1 or sim 2. I have tried below solutions but in all devices, it is not working. Samsung and MI devices the below solution is not working. can you please suggest universal solutions. thanks
I tried below solutions
URL1
URL2
public class IncomingCallInterceptor extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String callingSIM = "";
Bundle bundle = intent.getExtras();
callingSIM =String.valueOf(bundle.getInt("simId", -1));
if(callingSIM == "0"){
// Incoming call from SIM1
}
else if(callingSIM =="1"){
// Incoming call from SIM2
}
}
}
I have a class that extends BroadcastReceiver and reads code from an SMS and pastes it automatically in an EditText , this works perfectly on Samsung and Nexus Emulator, but now it's not working on Huawei , it does copy the text.. but then user needs to paste it manually..
This is my code:
public class SimpleSmsReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle pudsBundle = intent.getExtras();
Object[] pdus = (Object[]) Objects.requireNonNull(pudsBundle).get("pdus");
String format = pudsBundle.getString("format");
SmsMessage messages =SmsMessage.createFromPdu((byte[]) Objects.requireNonNull(pdus)[0],format);
// check if sender is specificSender
if(messages.getOriginatingAddress().equalsIgnoreCase("specificSender")) {
// get only the numbers from the sms
String number = messages.getMessageBody().replaceAll("[^0-9]", "");
// place the code in the edit text
if(VerifyActivity.isVerifyRunning) {
VerifyActivity.et_code.setText(number);
} else if(BaseActivity.isChangeNumberOn)
{
EditText et = BaseActivity.changeNumber.findViewById(R.id.et_code);
et.setText(number);
}
}
}
}
Do you have any idea what might cause this?
is it related to Huawei devices or is there something I should add to my
code?
Thank You.
I have a working application that uses a BroadcastReceiver to process incoming SMS messages. My question is what is the best way to do work on an incoming SMS? Currently I am launching a new thread to do the work, as shown below in the onReceive() method of my BroadcastReceiver.
#Override
public void onReceive(final Context ctx, Intent intent) {
if(intent.getAction().equals(ANDROID_SMS_DELIVER)) {
Bundle bundle = intent.getExtras();
if (bundle != null){
try{
Object[] pdus = (Object[]) bundle.get("pdus");
SmsMessage[] msgs = new SmsMessage[pdus.length];
for(int i=0; i<msgs.length; i++){
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
final String smsFrom = msgs[i].getOriginatingAddress();
final String smsBody = msgs[i].getMessageBody();
// Launch a thread to do work on the SMS
new Thread() {
public void run() {
// Work..
}
}.start();
}
} catch(Exception e){}
}
}
}
Is this the best way? Alternatively, should I be sending a broadcast to some other IntentService to do the work, or will this work just as well?
Thanks.
This is not the way to do it! The BroadcastReceiver will only be alive for 10 seconds (give or take). I have no clue what will happen with your thread.
The best way to do is use a IntentService. This Service is launched/started via an Intent and will shutdown itself when done.
My application has the following modules,
To collect users CB location code.
To save that in a database of user's choice, say for example my CB code is 465783 and I can save that as 'College' in my database.
To provide alarm feature, in this module I can give a text input say I give it as 'College' and when the Cell Broadcast is updated if the value college matches alarm is given out.
Now, in my below code I've achieved first 2 modules and also the required database entries, databases search etc, I'm not able to read the updated CB location value.
public class Alarm extends MainActivity {
public String str;
public void onReceive(Context context, Intent intent) {
//---get the CB message passed in---
Bundle bundle = intent.getExtras();
SmsCbMessage[] msgs = null;
str = "";
if (bundle != null) {
//---retrieve the SMS message received---
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsCbMessage[pdus.length];
for (int i=0; i<msgs.length; i++) {
msgs[i] = SmsCbMessage.createFromPdu((byte[])pdus[i]);
str += "CB " + msgs[i].getGeographicalScope() + msgs[i].getMessageCode() + msgs[i].getMessageIdentifier() + msgs[i].getUpdateNumber();
str += " :";
str += "\n";
}
}
}
EditText user_value;
Button startalarm;
Button stopalarm;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.third);
startalarm = (Button) findViewById(R.id.startalarm);
stopalarm = (Button) findViewById(R.id.stopalarm);
user_value = (EditText) findViewById(R.id.user_value);
final Ringtone ringtone;
ringtone = RingtoneManager.getRingtone(getBaseContext(), RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE));
startalarm.setOnClickListener(new View.OnClickListener()
{
public void onClick(View arg0)
{
// TODO Auto-generated method stub
if(user_value.length()==0)
{
Toast.makeText(getBaseContext(), "Please enter a value.", Toast.LENGTH_LONG).show();
}
Toast.makeText(getApplicationContext(), "alarm set", Toast.LENGTH_LONG).show();
//I want my alarm event to be started from here whenever a new CB sms arrives.
SQLiteDatabase aa = openOrCreateDatabase("MLIdata", MODE_WORLD_READABLE, null);
Cursor c = aa.rawQuery("SELECT CblocationName FROM MLITable WHERE CblocationCode = '"+str+"'", null);
c.moveToFirst();
c.getString(c.getColumnIndex("CblocationName"));
String sas = user_value.getText().toString();
if(sas.equals(c.getString(c.getColumnIndex("CblocationName"))))
{
//here comes the alarm code
if(ringtone == null)
{
Log.d("Debug", "ringtone is null");
}
else
{
ringtone.play();
}
}
}
});
stopalarm.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
ringtone.stop();
}
});
}
}
Detailed Explanation : whenever a user enters a new tower location he gets the updated Cell Broadcast message from the tower, so when this cbsms arrives I need to start my event of retrieving the CB area code and compare it with my database of area codes (which obviously have corresponding area code names set by the user) and when there is a match between the user given area name's corresponding area code with my current area code an alarm needs to be started, here I'm not able to do detect the arrival of updated location.
If further explanation is required of my problem statement, please comment.
From the comments received below, I've deduced that I'd need a receiver class, I've created one for my widget which does the same function (Displays the Cb location code on the widget), Now I do not how to activate that in my app.
My WidgetReceiver.java
public class CbReceiver extends BroadcastReceiver
{
public void onReceive(Context context, Intent intent) {
//---get the CB message passed in---
Bundle bundle = intent.getExtras();
SmsCbMessage[] msgs = null;
String str = "";
if (bundle != null) {
//---retrieve the SMS message received---
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsCbMessage[pdus.length];
for (int i=0; i<msgs.length; i++) {
msgs[i] = SmsCbMessage.createFromPdu((byte[])pdus[i]);
str += "CB " + msgs[i].getGeographicalScope() + msgs[i].getMessageCode() + msgs[i].getMessageIdentifier() + msgs[i].getUpdateNumber();
str += " :";
str += msgs[i].getMessageBody().toString();
str += "\n";
abortBroadcast();
Toast.makeText(context, str, Toast.LENGTH_LONG).show();
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget);
ComponentName thisWidget = new ComponentName(context,MyWidget.class);
remoteViews.setTextViewText(R.id.update,str);
appWidgetManager.updateAppWidget(thisWidget, remoteViews);
}
}}
}
Help required.
Thank you.
Start your activity from your receiver on tower change. Use Intents to start your activity from receivers.
Ex: Refer this alarm example for above point, Alarm Example
Register your receiver in Android Manifest.xml.
Send a broadcast message from your receiver class also update your DB inside your receiver.
Catch the same in your activity. You can use Custom Broadcast for this.
Now activate your alarm in activity.
Hope these steps will help you. Refer the example I have mentioned.
I have an app that listens to incoming messages, and if the originating sender is the one specified by the user, it then reacts accordingly, showing a special alert and aborting the broadcast, preventing it from reaching the inbox. On Verizon, it works perfectly. I've sent over 300 without any issue, as have a few other testers.
On any other carrier though, it's a mess.
On AT&T, the broadcast is never aborted and it shows up in the sms inbox.
On Sprint, the broadcast is aborted, but it never gets beyond that. The AlertActivity intent is never called, nor either of the toast messages I put to check.
On T-Mobile, the broadcast is never aborted and it shows up in the sms inbox.
I have the receiver done in java rather than registered in the Manifest because I register it in a service which is started on app launch and on BOOT_COMPLETED.
Service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
public void startService() {
IntentFilter SMSfilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
this.registerReceiver(Receiver.br, SMSfilter);
}
Receiver
static public BroadcastReceiver br = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
final SmsMessage[] messages = new SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
if (messages[i].getOriginatingAddress().equals(Test.SENDER)) {
abortBroadcast();
String[] body = messages[i].getDisplayMessageBody().split(" ", 7);
if (body[0].equals("test")) {
test = true;
}
cat = body[1];
level = body[2];
urgency = body[3];
certainty = body[4];
carrier = body[5];
message = body[6];
intent = new Intent(context, AlertActivity.class);
Bundle b = new Bundle();
b.putString("title", cat);
b.putString("certainty", certainty);
b.putString("urgency", urgency);
b.putString("level", level);
b.putString("message", message);
b.putBoolean("test", test);
intent.putExtras(b);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
carrierName = manager.getNetworkOperatorName();
if (carrierName.replaceAll(" ", "").equals(carrier)) {
context.startActivity(intent);
} else {
//testing
toast(carrierName.replaceAll(" ", ""), context);
}
}
}
}
}
};
I use these imports in the app,
import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;
I know that there is a gsm version of these as well, which I don't use. Could this be why the app isn't detecting the incoming messages on the gsm carriers?
UPDATE 1
According to http://developer.android.com/reference/android/telephony/gsm/package-summary.html its not due to not using the gsm specific imports.
ANSWER
Got it.
It has to do with how the incoming message senders number is read.
On the verizon device it would register as xxxxxxx on others, +1xxxxxxx. Added an option to acces Test.SENDER or Test.SENDER_LAME which is +1xxxxxxx
Got it. It has to do with how the incoming message senders number is read. On the verizon device it would register as xxxxxxx on others, +1xxxxxxx. Added an option to acces Test.SENDER or Test.SENDER_LAME which is +1xxxxxxx