I am trying to restart my app on receiving sms if it is force stopped. This is my code.
Its not restarting the app.Should I try writing receiver as another class.
In manifest :
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<receiver android:name=".MySMSbr">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
My mainActivity onCreate() :
private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
BroadcastReceiver SMSbr;
public void onCreate(Bundle savedInstanceState) {
Toast.makeText(getApplicationContext(),"in OnCreate", Toast.LENGTH_LONG).show();
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
SMSbr = new BroadcastReceiver()
{
#Override
public void onReceive(Context context,Intent intent)
{
this.abortBroadcast();
Toast.makeText(context, "in onReceive", Toast.LENGTH_LONG).show();
toggleLogging(AppSettings.getServiceRunning(MainActivity.this),
AppSettings.getLoggingInterval(MainActivity.this));
this.clearAbortBroadcast();
}//end of onReceive method
};//end of BroadcastReceiver
IntentFilter SMSfilter = new IntentFilter(SMS_RECEIVED);
this.registerReceiver(SMSbr, SMSfilter);
}
in togglelogging the service is started
where is it going wrong.
You are declaring a BroadcastReceiver in your manifest - i.e, static receiver but in fact you do not have such a class and you are creating a dynamic receiver in your activity.
What you are actually doing is registering your receiver when your activity starts, but you want the other way around (start your activity/app once the receiver receives a broadcast).
You need to create a class which is called SMSbr extends BroadcastReceiver and there you can perform your logics.
That way you will have the receiver always registered and when an SMS broadcast will be received it will wake your app.
Related
I have a broadcast which monitors for unlock event for the phone. But when the app's process is killed and no longer in memory, Unlocking the phone does not trigger the Receiver, instead I can see in the Android studio, that new process is created for that app.
If lock and unlock it again, then as the process is already running, I can see the BroadcastReceiver is triggered.
<receiver
android:name=".UserPresentBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
Broadcast Receiver:
public class UserPresentBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = UserPresentBroadcastReceiver.class.getSimpleName();
#Override
public void onReceive(Context arg0, Intent intent) {
Log.d(TAG, "onReceive: Unlock Boradcast received");
if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
Toast.makeText(arg0, "You just unlocked the device", Toast.LENGTH_LONG).show();
}
}
}
I am unable to understand this behavior. Is this the default behavior?
You have to register and unregister this broadcast receiver in Activity(or Service for listening in background all the time).
Manifest entry won't work.
I have a service that is running in the foreground, inside this service i have a broadcast receiver, that listen to the SMS_RECEIVED action.
When the user is inside the application (both the application and the service are in the foreground) everything works well, and i am receiving the intent.
But when the user exists the application (only the service with the broadcast is in the foreground), the service stops when sms is received.
When the service is stopped no error reports are found anywhere (not in the logcat and no crash dialog pops up).
My service with the broadcast:
public class myService extends IntentService {
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(myService.this, intent.getAction(), Toast.LENGTH_SHORT).show();
}
};
#Override
public void onCreate() {
super.onCreate();
IntentFilter i= new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
i.setPriority(999);
registerReceiver(mReceiver, receiverFilter);
startForeground(...);
}
public void onDestroy() {
super.onDestroy();
stopForeground(true);
}
}
And i also have the following permission in my manifest:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
myService is declared like this in the manifest:
<service
android:name=".Services.myService"
android:enabled="true"
android:exported="false" />
I had the same problem and I solved it removing <uses-permission android:name="android.permission.RECEIVE_SMS" />. But removing this permission I can't detect incoming SMS, so I created a class like these Catching Outgoing SMS using ContentObserver and used MESSAGE_TYPE_RECEIVED = 1 instead MESSAGE_TYPE_SENT = 2. You need to add this permission <uses-permission android:name="android.permission.READ_SMS" />.
I am writing an app which receives SMS data message, encrypt its content and save it to database. To realize it I've created a service with a local BroadcastReceiver as follow:
public class SMMReceiverService extends Service {
private class SMMreceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
Bundle extras = intent.getExtras();
//call a method from service
}
}
private SMMreceiver smmReceiver;
private IntentFilter intentFilter;
#Override
public void onCreate(){
super.onCreate();
android.os.Debug.waitForDebugger();
smmReceiver = new SMMreceiver();
intentFilter = new IntentFilter();
intentFilter.addAction("android.provider.Telephony.DATA_SMS_RECEIVED");
intentFilter.addDataScheme("sms");
intentFilter.addDataAuthority("localhost","8901");
registerReceiver(smmReceiver, intentFilter);
}
}
Service is starting normally but onReceive method of SMMreceiver is never called. In manifest I've declared only my service as follow:
<service
android:name=".Services.SMMReceiverService"
android:enabled="true"
android:exported="true" >
</service>
There are also all required permissions:
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
How to solve my problem in correct way? I will be grateful for your help!
Well, it seems like you kind of answered your own question.
"Service is starting normally but onReceive method of SMMreceiver is never called. In manifest I've declared only my service as follow:"
you have to also declare your receiver in your manifest, did you do that?
I am trying to develop an android app, in which I want to sent a message from the phone while making call.
The destination number is taken from the application database.
I have completed till that part, but I cant access the broadcast receiver in my activity:
public class PARENT_CALLActivity extends Activity
{
/** Called when the activity is first created. */
String PARENT=null;
EditText edparent;
Button submit;
String parent_number;
public static final String BROADCAST = "sha.pcall.android.action.broadcast";
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
edparent=(EditText)findViewById(R.id.editText1);
submit=(Button)findViewById(R.id.btnsubmit);
submit.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
// TODO Auto-generated method stub
PARENT=edparent.getText().toString();
MyDabasehandler db=new MyDabasehandler(getApplicationContext());
if(db.getContact().equals(null))
{
db.addContact(new Contacts(PARENT));
}
else
{
db.editContact();
}
Intent intent = new Intent(getApplicationContext(),LocationUpdateReceiver.class);
sendBroadcast(intent);
finish();
}
});
}
public class LocationUpdateReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
String outgoing_number=intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Toast.makeText(context, outgoing_number, Toast.LENGTH_LONG).show();
}
}
}
If you are creating a separate class by extending Broadcast receiver I suggest you do it in a separate Class file. If you only want to receive broadcasts as long as the activity is open create a private Broadcast receiver variable. like in this question:
Where to register a BroadcastReceiver (Activity lifecycle fun)
In latter case you can register the broadcast receiver variable with this method called registerreceiver.
Here is the link
It all actually depends on the requirements. If you want to receive broadcasts even if your app is closed (or the activity is not in the foreground), you need to register your broadcast receiver in the manifest file like this:
<receiver
android:name="com.example.myapp.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.example.myapp" />
</intent-filter>
</receiver>
This is an example of google cloud message broadcast receiver. You also need to add intent filter, to specify which type of broadcast you want to receiver. In the above example the broadcast receiver can receive (see the intent-filter tag) two intents with actions:
"com.google.android.c2dm.intent.RECEIVE"
and
"com.google.android.c2dm.intent.REGISTRATION"
After you are done with this you can accomplish your tasks in the overridden onReceive() method of broadcast receiver.
Hope this helps.
I'm just trying this little sample project, all it does:
Activity one has a Button that sends a Broadcast. Activity two displays a toast when received.
Below is the code, the Broadcast is never received. What do I do wrong?
Sending the Broadcast
public class SendBroadcast extends Activity {
public static String BROADCAST_ACTION = "com.unitedcoders.android.broadcasttest.SHOWTOAST";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void sendBroadcast(View v){
Intent broadcast = new Intent();
broadcast.setAction(BROADCAST_ACTION);
sendBroadcast(broadcast);
}
}
Receiving it
public class ToastDisplay extends Activity {
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(getApplicationContext(), "received", Toast.LENGTH_SHORT);
}
};
#Override
protected void onResume() {
IntentFilter filter = new IntentFilter();
filter.addAction(SendBroadcast.BROADCAST_ACTION);
registerReceiver(receiver, filter);
super.onResume();
}
#Override
protected void onPause() {
unregisterReceiver(receiver);
super.onPause();
}
}
Manifest
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".SendBroadcast" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ToastDisplay">
<intent-filter>
<action android:name="com.unitedcoders.android.broadcasttest.SHOWTOAST"></action>
</intent-filter>
</activity>
</application>
What do I do wrong?
The source code of ToastDisplay is OK (mine is similar and works), but it will only receive something, if it is currently in foreground (you register receiver in onResume). But it can not receive anything if a different activity (in this case SendBroadcast activity) is shown.
Instead you probably want to startActivity ToastDisplay from the first activity?
BroadcastReceiver and Activity make sense in a different use case. In my application I need to receive notifications from a background GPS tracking service and show them in the activity (if the activity is in the foreground).
There is no need to register the receiver in the manifest. It would be even harmful in my use case - my receiver manipulates the UI of the activity and the UI would not be available during onReceive if the activity is not currently shown. Instead I register and unregister the receiver for activity in onResume and onPause as described in
BroadcastReceiver documentation:
You can either dynamically register an instance of this class with Context.registerReceiver() or statically publish an implementation through the tag in your AndroidManifest.xml.
Toast.makeText(getApplicationContext(), "received", Toast.LENGTH_SHORT);
makes the toast, but doesnt show it.
You have to do Toast.makeText(getApplicationContext(), "received", Toast.LENGTH_SHORT).show();
Extends the ToastDisplay class with BroadcastReceiver and register the receiver in the manifest file,and dont register your broadcast receiver in onResume() .
<application
....
<receiver android:name=".ToastDisplay">
<intent-filter>
<action android:name="com.unitedcoders.android.broadcasttest.SHOWTOAST"/>
</intent-filter>
</receiver>
</application>
if you want to register in activity then register in the onCreate() method e.g:
onCreate(){
sentSmsBroadcastCome = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "SMS SENT!!", Toast.LENGTH_SHORT).show();
}
};
IntentFilter filterSend = new IntentFilter();
filterSend.addAction("m.sent");
registerReceiver(sentSmsBroadcastCome, filterSend);
}
You need to define the receiver as a class in the manifest and it will receive the intent:
<application
....
<receiver android:name=".ToastReceiver">
<intent-filter>
<action android:name="com.unitedcoders.android.broadcasttest.SHOWTOAST"/>
</intent-filter>
</receiver>
</application>
And you don't need to create the class manually inside ToastDisplay.
In the code you provided, you must be inside ToastDisplay activity to actually receive the Intent.
I think your problem is that you send the broadcast before the other activity start ! so the other activity will not receive anything .
The best practice to test your code is to sendbroadcast from thread or from a service so the activity is opened and its registered the receiver and the background process sends a message.
start the ToastDisplay activity from the sender activity ( I didn't test that but it may work probably )
You forget to write .show() at the end, which is used to show the toast message.
Toast.makeText(getApplicationContext(), "received", Toast.LENGTH_SHORT).show();
It is a common mistake that programmer does, but i am sure after this you won't repeat the mistake again... :D
Your also have to register the receiver in onCreate(), like this:
IntentFilter filter = new IntentFilter();
filter.addAction("csinald.meg");
registerReceiver(receiver, filter);