I created a alarm and I hope when alarm is stop can set a String to TextView in MainActivity so I try to use interface but it's get error :
Caused by: java.lang.ClassCastException: AlarmReceiver cannot be cast to AlarmReceiver$OnAlarmOver
AlarmReceiver.java
public class AlarmReceiver extends BroadcastReceiver {
public AlarmReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
...
OnAlarmOver onAlarmOver = (OnAlarmOver) context; //<--error
onAlarmOver.OnAlarmOverText("Alarm stop");
}
public interface OnAlarmOver {
public void OnAlarmOverText(String overText);
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity implements AlarmReceiver.OnAlarmOver {
...
public void OnAlarmOverText(String overText){
alarm_text.setText(overText);
}
}
My English is very poor, sorry.
You are trying to cast the context to OnAlarmOver. Of course, this is not going to work. I think you want to capture a broadcast emit somewhere else inside of your app.
1) You need to define your broadcast. Then, in your activity, you should register it. For example:
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
if(intent.getAction().equals(SearchService.NOTIFICATION)){
}
}
}
};
#Override
protected void onResume() {
super.onResume();
registerReceiver(receiver, new IntentFilter(SearchService.NOTIFICATION));
}
Remember to unregister in the pause method
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
2) You need to create an Intent and the send the broadcast like this.
private void publishResults(Search result) {
Intent intent = new Intent(NOTIFICATION);
intent.putExtra(RESULT, result);
sendBroadcast(intent);
success = true;
}
To sum up, I don't know why you want to use an interface (listener) for this if it is is provided by Android. Maybe, you should explain a little more what do you want to do. I hope this answer can help you.
Related
I start a service from activity button click that fire a service class and start Broadcastreceiver and it's run in background but I want to unregisterReceiver with a button click from same activity class.it seem not working.I added receiver class to menifest.
Here is my code.
Activity button click for registerreceiver
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent svc = new Intent(this, DemoService.class);
startService(svc);
});
DemoService.class
public class DemoService extends Service {
static final String LOGGING_TAG = "MyDemo";
private static Alarm1 tickReceiver =new Alarm1();
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onStart(Intent intent, int startId){
super.onStart(intent, startId);
Log.v(LOGGING_TAG, "DemoService.onStart()");
}
#Override
public void onCreate(){
super.onCreate();
Log.d(LOGGING_TAG, "DemoService.onCreate()");
registerReceiver(
new Alarm1(),
new IntentFilter(Intent.ACTION_TIME_TICK));
}
}
Activity button click for unregisterReceiver
unreg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DemoService demo=new DemoService();
demo.unreg();
});
And receiver class
public class Alarm1 extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("tag","working");
}
How can I unregisterReceiver from unreg button click.
If I click in unreg button it show me error java.lang.IllegalArgumentException: Receiver not registered:
create a method for unregistering Receiver in Service class. And call the service with action like.
Intent svc = new Intent(this, DemoService.class);
svc.setAction("com.package.UN_REGISTER");
startService(svc);
and in Service class handle them in onStartCommand ()
like
if(intent.getAction().equals("com.package.UN_REGISTER")
//call your unregister method
Add action in Manifest in your service Tag
<IntentFilter>
<action name = "com.package.UN_REGISTER">
</IntentFilter>
You should use Bound Services for this. Check link for implementation and usage
If you want to correctly register and unregister a BroadcastReceiver. The BroadcastReceiver passed in registerReceiver() and unregisterReceiver() must be the same instance, so is the Context instance be invoked. Because the implement uses Context and BroadcastReceiver instances to uniquely map to a "Register operation".
(NOTE that at the end of this Question I have an EDIT in which I have replaced one method with what the Answer said to do in order to fix the problem of onReceive never getting called and added onDestroy to fix a new problem that cropped up after fixing first problem.)
Here's how I attempted to capture the broadcast data, but onReceive never gets called since Log.w never displays anything:
public class MatchesActivity extends Activity implements DatabaseConnector.DatabaseProcessListener
{
public static String SOME_ACTION = "com.dslomer64.servyhelperton.SOME_ACTION";
public static String STRING_EXTRA_NAME = "match";
#Override protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
LocalBroadcastManager.getInstance(this).registerReceiver
(
new BroadcastReceiver()
{
#Override public void onReceive(Context context, Intent intent)
{
String s = txaMatches.getText().toString() + intent.getStringExtra(STRING_EXTRA_NAME) ;
txaMatches.setText(s);
Log.w("MatchesActivity","`````onReceive <" + s + ">");
}
}, new IntentFilter(SOME_ACTION)
);
...
DatabaseConnector dbc = new DatabaseConnector(getApplicationContext(), assets);
dbc.setDbProcesslistener(this); // set way to know matches has been defined
dbc.findDBMatches();
} // end onCreate
} // end MatchesActivity
Database connector:
public DatabaseConnector(Context _context, AssetManager _assets)
{
mContext = _context;
//This method, called in `MatchesActivity` on button press, does start the service:
public void findDBMatches()
{
Intent i= new Intent(mContext, QueryDB.class);
mContext.startService(i);
}
// Here's the service:
public static class QueryDB extends IntentService
{
public QueryDB() { super(QueryDB.class.getSimpleName()); }
public QueryDB(String name) { super(name); }
//Here's the procedure that does all the work (and it does execute):
#Override protected void onHandleIntent(Intent intent)
{ ...
publishProgress(dicWord); // a String
}
//This does execute but it doesn't send `progress` back to `MatchesActivity`,
//which initiated request for service (note: `publishProgress` is so named
//because `QueryDB` used to be an `AsyncTask` and I just didn't change the name):
protected void publishProgress(String progress)
{
Intent intent = new Intent(MatchesActivity.SOME_ACTION);
intent.putExtra(MatchesActivity.STRING_EXTRA_NAME, progress);
this.sendBroadcast(intent); // THIS LINE IS THE PROBLEM, FIXED BELOW
Log.w("DatabaseConnector", "`````publishProgress <" + progress + ">");
}
}
What connection(s) have I failed to make?
EDIT
This is the CORRECTED method found just above:
protected void publishProgress(String progress)
{
Intent intent = new Intent(MatchesActivity.SOME_ACTION);
intent.putExtra(MatchesActivity.STRING_EXTRA_NAME, progress);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
Here is onDestroy in MatchesActivity (which starts the service), necessary to call when service has finished its work:
#Override protected void onDestroy()
{
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
}
Note that onDestroy refers to a new MatchesIntent variable, defined as:
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver()
{
#Override public void onReceive(Context context, Intent intent)
{
String s = intent.getStringExtra(STRING_EXTRA_NAME) ;
txaMatches.append(s + "\n");
}
};
And onCreate in MatchesActivity got simpler because of defining mMessageReceiver:
#Override protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
LocalBroadcastManager.getInstance(this).registerReceiver
(
mMessageReceiver, new IntentFilter(SOME_ACTION)
);
}
What connection(s) have I failed to make?
In your first block of code, you are using LocalBroadcastManager. In your second block of code, you are not.
Replace:
this.sendBroadcast(intent);
with:
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
My code has two activities.
public class OnCallingActivity extends Activity implement TextToSpeech.OnInitListener{}
public class TextReceiverActivity extends BroadcastReceiver{}
i want first activity to extend sencond activity
OnCallingActivity extends TextReceiverActivity {}
so I did this,
public class OnCallingActivity extends Activity implements TextToSpeech.OnInitListener {
private TextReceiverActivity TextReceiverActivityClass;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.on_calling_layout);
TextReceiverActivityClass= new TextReceiverActivity();
speaker= new TextToSpeech(this, this);
callerIdText=(TextView)findViewById(R.id.callerIdtextview);
callerText=(TextView)findViewById(R.id.callermsgtextview);
translatedText=(TextView)findViewById(R.id.translatedTextview);
speakButton=(ImageButton)findViewById(R.id.btnSpeak);
sendButton=(Button)findViewById(R.id.buttonsend);
endCallButton=(ImageButton)findViewById(R.id.buttonendCall);
}
my second activity is as follow,
public class TextReceiverActivity extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
number ="";
message="";
final Bundle bundle = intent.getExtras();
try {
if(bundle != null) {
final Object[] pduObjects = (Object[]) bundle.get("pdus");
for(int i = 0; i < pduObjects.length; ++i) {
SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pduObjects[i]);
number = currentMessage.getDisplayOriginatingAddress();
message = currentMessage.getDisplayMessageBody();
Toast.makeText(context, "SENDER NUMBER: " + number + "; MESSAGE: " + message, Toast.LENGTH_LONG).show();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
in first activity i called the method of second activity like this
public void onReceive(Context context, Intent intent) {
TextReceiverActivityClass.onReceive(context, intent);
}
onReceive gives values for number and message..so how can i get them to my first activity to display them in TextViews.
onReceive is an inbuilt method so i can't change the return type.
If TextReceiverActivity extends BroadcastReceiver, then TextReceiverActivity isnt an Activity and I would refrain from calling it an Activity.
The onReceive method of a BroadcastReceiver is meant to be called from the Android sytem, not you.
To send a message from an Activity to a BroadcastReceiver you would send a Broadcast. See the docs.
If you want to send a message from your BroadcastReceiver to your Activity, there's a couple of questions about that.
I want to pause the MediaPlayer when the user unplugs his headphones. I found out that I can use the "ACTION_AUDIO_BECOMING_NOISY" broadcast , so I tried it out !
Theoretically it works , BUT the time of receiving takes too long. The music is still playing for 3-5 seconds before it really pauses.This wouldnt be acceptable for an user.
How are other devolopers able to pause it in milliseconds ? Are there better Soloutions ?
My BroadcastReceiver which is actually for Notifications :
public class NotificationBroadcast extends BroadcastReceiver {
...
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
Intent iPause = new Intent(context , SongService.class);
iPause.putExtra("com.Hohos.mplay.Services.SongService.MEDIA_ACTION", NOTIFY_EXTRA_PAUSE);
context.startService(iPause);
}
...
}
I also added <uses-permission android:name="android.permission.ACTION_HEADSET_PLUG"/>
, which really didnt any difference
Thanks for your help guys !
To know when the user unplugs his headphones you need to listen the action ACTION_HEADSET_PLUG and check the state extra:
Broadcast Action: Wired Headset plugged in or unplugged.
The intent will have the following extra values:
state - 0 for unplugged, 1 for plugged.
name - Headset type, human
readable string
microphone - 1 if headset has a microphone, 0
otherwise
This is an example:
public class MainActivity extends Activity {
private HeadsetBroadcastReceiver mHeadsetBroadcastReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myReceiver = new HeadsetBroadcastReceiver();
}
#Override
protected void onResume() {
IntentFilter filter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
registerReceiver(mHeadsetBroadcastReceiver, filter);
super.onResume();
}
#Override
protected void onPause() {
unregisterReceiver(mHeadsetBroadcastReceiver);
super.onPause();
}
private class HeadsetBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
int state = intent.getIntExtra("state", -1);
if (state == 0) {
//Headset is unplugged
} else if(state == 1) {
//Headset is plugged
}
}
}
}
}
I have got an action bar activity with a LocalBroadcastManager defined exactly like in the answer here, except the only difference is that it is defined in an ActionBarActivity.
For some reason, no matter what I try I can't manage to get to the receiver's onReceive (i.e. successfuly receiving broadcast message).
Service code:
public class GcmIntentService extends IntentService {
#Override
protected void onHandleIntent(Intent intent) {
Intent toDrawerActivity = new Intent(syncActionName);
String syncType = extras.getString("data");
toDrawerActivity.putExtra("syncType", syncType);
System.out.println("sending intent in service");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
And the activity code:
public class DrawerActivity extends ActionBarActivity {
private BroadcastReceiver dataUpdaterReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("in broadcast receiver");
}
};
protected void onCreate(){
...
...
LocalBroadcastManager.getInstance(this).registerReceiver(dataUpdaterReceiver,
new IntentFilter(GcmIntentService.syncActionName));
}
protected void onDestroy(){
LocalBroadcastManager.getInstance(this).unregisterReceiver(dataUpdaterReceiver);
}
}
What exactly am I doing wrong here?
Your have that problem due to you used the wrong parameter for sendBroadcast() method:
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
It should be:
LocalBroadcastManager.getInstance(this).sendBroadcast(toDrawerActivity);