Always running Service with BroadcastReceiver for Call Tapping - android

My Requirment
I am trying to build an application which shows a Toast whenever user makes a outgoing call from the phone. For this I am using a BroadcastReceiver to tap the call action and a service (to run Receiver always). once I start this activity, it starts showing toast when a outgoing call get initiated ...everything works well.
Issues
Sometimes I dont get any Toast Action EVEN for Outgoing call as well, is that mean service stops after some time ?
After phone reboot Toast Action for Outgoing call stops. Untill you start the servce again manually.
The code I have written is ok ? OR can it be improved ?
Below is the complete code -
MainActivity.class
public class MainActivity extends Activity
{
CallNotifierService m_service;
boolean isBound = false;
private ServiceConnection m_serviceConnection = new ServiceConnection()
{
#Override
public void onServiceConnected(ComponentName className, IBinder service)
{
m_service = ((CallNotifierService.MyBinder)service).getService();
Toast.makeText(MainActivity.this, "Service Connected", Toast.LENGTH_LONG).show();
isBound = true;
Intent intent = new Intent(MainActivity.this, CallNotifierService.class);
startService(intent);
}
#Override
public void onServiceDisconnected(ComponentName className)
{
m_service = null;
isBound = false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, CallNotifierService.class);
bindService(intent, m_serviceConnection, Context.BIND_AUTO_CREATE);
}
.
.
.
}
CallNotifierService.class
public class CallNotifierService extends Service
{
private final IBinder myBinder = new MyBinder();
private static final String ACTION_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL";
private static final String ACTION_ANSWER = "android.intent.action.ANSWER";
private static final String ACTION_CALL = "android.intent.action.CALL";
private CallBr br_call;
#Override
public IBinder onBind(Intent arg0)
{
return myBinder;
}
#Override
public void onDestroy()
{
Log.d("service", "destroy");
this.unregisterReceiver(this.br_call);
Toast.makeText(CallNotifierService.this, "Receiver Un-Registered", Toast.LENGTH_LONG).show();
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
final IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_ANSWER);
filter.addAction(ACTION_CALL);
filter.addAction(ACTION_OUTGOING_CALL);
this.br_call = new CallBr();
this.registerReceiver(this.br_call, filter);
Toast.makeText(CallNotifierService.this, "onStartCommand Called", Toast.LENGTH_LONG).show();
return START_STICKY;
}
public class MyBinder extends Binder
{
CallNotifierService getService()
{
return CallNotifierService.this;
}
}
public class CallBr extends BroadcastReceiver
{
public CallBr() {}
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "Action:"+intent.getAction(), Toast.LENGTH_LONG).show();
}
}
}
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.alwaysrunningprocesswithcallanswertap"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-sdk
android:minSdkVersion="22"
android:targetSdkVersion="22" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.example.alwaysrunningprocesswithcallanswertap.CallNotifierService" />
</application>
</manifest>
Could anyone please help for the issue OR pointout something better ?

#Bharat Once device switch off automatically service will stop, So when ever your device reboot that time you need to start service again then only you will get Toast Action, refer this example code :
BootCompleteReceiver.java
package com.example.newbootservice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class BootCompleteReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, AutostartService.class);
context.startService(service);
}
}
AutostartService .java
package com.example.newbootservice;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class AutostartService extends Service {
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
return Service.START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service Destroy", Toast.LENGTH_LONG).show();
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
MainActivity.java
package com.example.newbootservice;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startService(new Intent(getBaseContext(), AutostartService.class));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
Manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.newbootservice"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<service android:name=".AutostartService"/>
<receiver android:name=".BootCompleteReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

Related

Unable to print log when boot is completed

I am unabe to load a message(log) when boot is completed. I have tried with below code:
In BootReceiver.java file:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Booting Completed", Toast.LENGTH_LONG).show();
Log.d("On Boot Load", "Boot loading");
}
}
In Services.java file:
public class UpdateService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.d("Service", "Updating Services");
return null;
}
}
I have also added with below code in menifes.xml:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver android:name=".receivers.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
When I run the app the log does not appear in logcat section.
The receiver tag should be inside application tag and the uses-permission tag should be outside application tag but inside of manifest tag.
You should use onStartCommand() implementation:
public class UpdateService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.d("Service", "Updating Services");
return null;
}
#Override
public int onStartCommand(Intent pIntent, int flags, int startId) {
Log.d("On Boot Load", "Boot loading");
return super.onStartCommand(pIntent, flags, startId);
}
}
Also beware of other filter like android.intent.action.QUICKBOOT_POWERON.
I use this code (without a service) and it works for me (just tested it):
AndroidManifest.xml:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver android:name=".MyBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Kotlin:
class MyBootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == ACTION) {
Logger.warning("BOOTING UP!")
}
}
companion object {
const val ACTION = "android.intent.action.BOOT_COMPLETED"
}
}

Android BroadcastReceiver onReceive() called twice on android 5.1.1 even after one register

I Could not figure out what is wrong with below code. I also checked about registering receiver twice. But that's also not the case. or may be I am missing something.
Could any please help. I really need it. :(
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;
/**
*
* #author Bharat
*
*/
public class CallNotifierService extends Service
{
private static final String ACTION_IN = "android.intent.action.PHONE_STATE";
private static final String ACTION_OUT = "android.intent.action.NEW_OUTGOING_CALL";
private CallBr br_call;
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
#Override
public void onDestroy()
{
Log.d("service", "destroy");
this.unregisterReceiver(this.br_call);
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
final IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_OUT);
filter.addAction(ACTION_IN);
this.br_call = new CallBr();
this.registerReceiver(this.br_call, filter);
return START_NOT_STICKY;
}
public class CallBr extends BroadcastReceiver
{
Bundle bundle;
String state;
String inCall, outCall;
public boolean wasRinging = false;
public boolean answered = false;
public boolean outgoing = false;
#Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals(ACTION_IN))
{
if ((bundle = intent.getExtras()) != null)
{
state = bundle.getString(TelephonyManager.EXTRA_STATE);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING))
{
inCall = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
wasRinging = true;
Toast.makeText(context, "Incoming Call : " + inCall, Toast.LENGTH_LONG).show();
}
else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK))
{
if (wasRinging == true)
{
answered = true;
Toast.makeText(context, "Answered", Toast.LENGTH_LONG).show();
}
}
else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE))
{
wasRinging = false;
Toast.makeText(context, "Disconnected", Toast.LENGTH_LONG).show();
}
}
}
else if (intent.getAction().equals(ACTION_OUT))
{
if ((bundle = intent.getExtras()) != null)
{
outCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Toast.makeText(context, "Outgoing Call : " + outCall, Toast.LENGTH_LONG).show();
outgoing = true;
}
}
}
}
}
Below is the activity I am calling it from
public class MyActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.roaming);
Intent intent = new Intent(this, CallNotifierService.class);
startService(intent);
}
.
.
.
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ind.cosmos.main"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-sdk
android:minSdkVersion="22"
android:targetSdkVersion="22" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<!-- android:theme="#style/AppTheme"> -->
<activity
android:name="ind.cosmos.main.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="ind.cosmos.callRecord.CallNotifierService" />
</application>
As Bharat said it's better so handle it in code. Below is a trick to do so, found here, thanks to Michael Marvick who has given detail description as well.
public class PhoneStateBroadcastReceiver extends BroadcastReceiver {
public static final String TAG = "PHONE STATE";
private static String mLastState;
#Override
public void onReceive(Context context, Intent intent) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (!state.equals(mLastState)) {
mLastState = state;
Log.e(TAG, state);
}
}
}
Actually .. there is nothing wrong with the code. its System who triggers this. some time its 2 times.. other times it touches 4 times.
So the best we can do it handle it in the code itself.
I have the same behavior, and there is no issue in your code. android.intent.action.PHONE_STATE can be received few times, but Intent's bundle is always different, for example:
D/App(2001): Bundle{ state => OFFHOOK; subscription => 1; }Bundle
D/App(2001): Bundle{ incoming_number => 555555555; state => OFFHOOK; subscription => 9223372036854775807; }Bundle

Handle event Power button press if activity is Closed

How can I know if the Power button is Pressed while Activity is Closed, not screen on/off because I want to know exactly how many times Power button is Pressed.
I think I have use Broadcast or Service, but I can't find any solutions that work for me, I don't know what should I do. Here are some solutions I found but not work.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_POWER) {
// Do something here...
Log.d("#tag", "ACTION_Down ");
}
return super.onKeyDown(keyCode, event);
}
Manifest
<uses-permission android:name="android.permission.PREVENT_POWER_KEY" />
or this, but I don't need it because It work only screen on/off, if I fast double click Power button when screen Off then It not work.
public class PowerBroadcast extends BroadcastReceiver {
private boolean screenOff;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
{
screenOff = true;
Toast.makeText(context, "ACTION_SCREEN_OFF ", Toast.LENGTH_SHORT).show();
Log.d("#tag", "ACTION_SCREEN_OFF ");
}
else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON))
{
screenOff = false;
Toast.makeText(context, "ACTION_SCREEN_ON", Toast.LENGTH_LONG).show();
Log.d("#tag", "ACTION_SCREEN_On ");
}
}
}
check this out :
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) {
Log.i("", "Dispath event power");
//do watever u want.
return true;
}
return super.dispatchKeyEvent(event);
}
or try the hole code :
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.userpresent"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.userpresent.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.example.userpresent.LockService" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</service>
</application>
</manifest>
MainActivity.java
package com.example.userpresent;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(getApplicationContext(), LockService.class));
}
}
LockService.java
package com.example.userpresent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Binder;
import android.os.IBinder;
public class LockService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
final IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
final BroadcastReceiver mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
return super.onStartCommand(intent, flags, startId);
}
public class LocalBinder extends Binder {
LockService getService() {
return LockService.this;
}
}
}
ScreenReceiver.java
package com.example.userpresent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
public class ScreenReceiver extends BroadcastReceiver {
public static boolean wasScreenOn = true;
#Override
public void onReceive(final Context context, final Intent intent) {
Log.e("LOB","onReceive");
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
// do whatever you need to do here
wasScreenOn = false;
Log.e("LOB","wasScreenOn"+wasScreenOn);
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
// and do whatever you need to do here
wasScreenOn = true;
}else if(intent.getAction().equals(Intent.ACTION_USER_PRESENT)){
Log.e("LOB","userpresent");
Log.e("LOB","wasScreenOn"+wasScreenOn);
//do something.
}
}
}

Android - My background service's registered broadcast receiver cannot be turned off if the device restarts with the receiver registered

I'm trying to create a small app that listens for my Bluetooth media receiver's on press commands and launches a Tasker task when it is pressed. The service is started and stopped using an intent I send from tasker.
Everything runs perfectly until I restart my device (or lose power) whilst my service's receiver is still registered. Once my device reboots, the receiver remains registered and my app crashes if I try to unregister it using my STOP intent. How do I unregister my receiver if my phone is about to switch off?
Target API is 16 (4.1):
MainActivity (A dummy activity for security):
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
finish();
}
}
RemoteControlReceiver
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class RemoteControlReceiver extends BroadcastReceiver {
public RemoteControlReceiver () {
super();
}
#Override
public void onReceive(Context context, Intent intent) {
intent.setClass(context, RemoteControlService.class);
context.startService(intent);
}
}
RemoteControlService
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Handler;
import android.os.IBinder;
import android.view.KeyEvent;
import com.example.simplemediabuttonlistener.TaskerIntent;
public class RemoteControlService extends Service {
public RemoteControlService() {
}
private Handler handler;
//sets up the audio manager and names the receiver component (registered later)
AudioManager manager;
ComponentName mReciever = new ComponentName(RemoteControlReceiver.class.getPackage().getName(), RemoteControlReceiver.class.getName());
#Override
public void onCreate(){
super.onCreate();
}
#Override
public void onDestroy(){
super.onDestroy();
manager.unregisterMediaButtonEventReceiver(mReciever);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
handler = new Handler();
String intentAction = intent.getAction();
//if we are using our custom start intent
if (intentAction == "com.example.simplemediabuttonlistener.START"){
//we have launched from tasker...
//so register our receiver
manager = (AudioManager) getSystemService(AUDIO_SERVICE);
manager.registerMediaButtonEventReceiver(mReciever);
}
//if we are using our custom stop intent
if (intentAction == "com.example.simplemediabuttonlistener.STOP"){
//we have stopped from tasker...
//so stop service
stopSelf();
}
//if a media button is pressed
if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
KeyEvent event = (KeyEvent) intent
.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (event == null) {
return START_STICKY;
}
int keycode = event.getKeyCode();
int action = event.getAction();
//check which button it is and run the appropriate task
if (keycode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE
|| keycode == KeyEvent.KEYCODE_MEDIA_PLAY
|| keycode == KeyEvent.KEYCODE_MEDIA_PAUSE
|| keycode == KeyEvent.KEYCODE_HEADSETHOOK) {
if (action == KeyEvent.ACTION_DOWN) {
handler.post(new Runnable() {
public void run() {
if ( TaskerIntent.testStatus( getApplicationContext() ).equals( TaskerIntent.Status.OK ) ) {
TaskerIntent i = new TaskerIntent( "BTPLAY" );
getApplicationContext().sendBroadcast( i );
}
}
});
}
}
if (keycode == KeyEvent.KEYCODE_MEDIA_NEXT) {
if (action == KeyEvent.ACTION_DOWN) {
// Start your app here!
handler.post(new Runnable() {
public void run() {
if ( TaskerIntent.testStatus( getApplicationContext() ).equals( TaskerIntent.Status.OK ) ) {
TaskerIntent i = new TaskerIntent( "BTNEXT" );
getApplicationContext().sendBroadcast( i );
}
}
});
}
}
}
return START_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
// We dont bind to an activity, so this is unused
return null;
}
}
AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.simplemediabuttonlistener"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="18" />
<permission android:name = "net.dinglisch.android.tasker.PERMISSION_RUN_TASKS" />
<permission android:name = "android.permission.BLUETOOTH" />
<uses-permission android:name = "android.permission.BLUETOOTH" />
<uses-permission android:name = "net.dinglisch.android.tasker.PERMISSION_RUN_TASKS" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name=".RemoteControlReceiver" >
<intent-filter android:priority="1000000000" >
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
<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=".RemoteControlService">
<intent-filter>
<action android:name= "com.example.simplemediabuttonlistener.START">
<category android:name = "android.intent.category.DEFAULT" />
</action>
<action android:name= "com.example.simplemediabuttonlistener.STOP">
<category android:name = "android.intent.category.DEFAULT" />
</action>
</intent-filter>
</service>
</application>
</manifest>
If I'm not mistaken I think you need to switch
#Override
public void onDestroy(){
super.onDestroy();
manager.unregisterMediaButtonEventReceiver(mReciever);
}
to
#Override
public void onDestroy(){
manager.unregisterMediaButtonEventReceiver(mReciever);
super.onDestroy();
}
so it unregisters the receiver prior to it being destoryed.

BroadcastReceiver Not receiving Broadcast

I am trying to broadcast a toast message with the following code extending Activity. But the broadcast is not received by another Activity, the toast is not displayed. Can someone solve my error? The main activity is SendBroadcast.java
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class SendBroadcast extends Activity {
public static String BROADCAST_ACTION =
"com.unitedcoders.android.broadcasttest.SHOWTOAST";
#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);
}
}
Toast Display Activity is ToastDisplay.java
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.widget.Toast;
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).show();
}
};
#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();
}
}
and manifest.xml is as follows
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.broad"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="3" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:icon="#drawable/ic_launcher"
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>
<receiver android:name=".ToastReceiver" >
<intent-filter>
<action android:name="com.unitedcoders.android.broadcasttest.SHOWTOAST" />
</intent-filter>
</receiver>
</application>
</manifest>
There can be two types of broacast: static and dynamic. Static are those that are declared in the manifest file. Dynamic can be declared during runtime. You combined these two types of broadcast in one broadcast.
To declare a simple dynamic broadcast you can use the following code (that is based on your code). It will simply display toast message when activity is shown.
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
public class BroadcastTestActivity extends Activity {
public static String BROADCAST_ACTION =
"com.unitedcoders.android.broadcasttest.SHOWTOAST";
BroadcastReceiver br = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.w("Check", "Inside On Receiver");
Toast.makeText(getApplicationContext(), "received",
Toast.LENGTH_SHORT).show();
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
IntentFilter filter = new IntentFilter();
filter.addAction(BROADCAST_ACTION);
filter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(br, filter);
}
#Override
protected void onResume() {
super.onResume();
sendBroadcast();
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(br);
}
public void sendBroadcast() {
Intent broadcast = new Intent();
broadcast.setAction(BROADCAST_ACTION);
broadcast.addCategory(Intent.CATEGORY_DEFAULT);
sendBroadcast(broadcast);
}
}
So now instead of showing toast you can call your new activity. The following actions depend on your needs (what you want to do).
Where is ToastReceiver class?
<receiver android:name=".ToastReceiver">
<intent-filter>
<action android:name="com.unitedcoders.android.broadcasttest.SHOWTOAST"/>
</intent-filter>
</receiver>`
Change
public class ToastDisplay extends Activity {
private BroadcastReceiver receiver = new BroadcastReceiver() {
}
to
public class ToastReceiver extends BroadcastReceiver {
}
Try
<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>
<intent-filter>
<action android:name="android.intent.action.BROADCAST" />
</intent-filter>
</activity>
In onCreate() call
sendBroadcast(v);
Button b1 = (Button)findViewById(R.id.button1);
b1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
try {
String RESULT = new TestAsyncTask().execute(" ").get();
System.out.println("RESULT "+RESULT);
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});

Categories

Resources