Get from Android BroadcastReceiver to a UI - java

I have a receiver that works well, but I can't seem to show a proper UI, although the toast appears correctly. As far as I can tell, this is caused by Android requiring the class to extend Activity, however, the class already extends BroadcastReceiver, so I can't do this.
So, I tried to do an Intent, but this failed too. There are no errors, but the screen doesn't show. Source code is below.
Broadcast (Method in AndyRoidAlarm)
public void setAlarm(){
Intent intent = new Intent(AndyRoidAlarm.this, Reciever.class);
PendingIntent sender = PendingIntent.getBroadcast(AndyRoidAlarm.this,
0, intent, 0);
// We want the alarm to go off 30 seconds from now.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 10);
// Schedule the alarm!
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);
// Tell the user about what we did.
if (mToast != null) {
mToast.cancel();
}
mToast = Toast.makeText(AndyRoidAlarm.this, "Alarm Scheduled for 30secs", Toast.LENGTH_LONG);
mToast.show();
}
Reciever
public class Reciever extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "Alarm Received", Toast.LENGTH_LONG).show();
Intent i = new Intent();
i.setClass(context, AlarmRing.class);
}
}
Reciever V2
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "Alarm Received", Toast.LENGTH_LONG).show();
Intent foo = new Intent(context, AlarmRing.class);
//foo.putExtra("id", "id");//example, if you wish to pass custom variables
context.startActivity(foo);
}
AlarmRing
public class AlarmRing extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.alarm);
MediaPlayer mp = MediaPlayer.create(getBaseContext(), R.raw.sweetchild);
mp.start();
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.comaad.andyroidalarm"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".AndyRoidAlarm"
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="com.comaad.andyroidalarm.Reciever" android:enabled="true">
<intent-filter>
<action android:name="com.comaad.andyroidalarm.Reciever"></action>
</intent-filter>
</receiver>
<activity android:name=".AlarmRing"></activity>
</application>
</manifest>
}

In a BroadcastReceiver onReceive() method, if you need a Context (e.g., to create an Intent), use the Context that is passed to you as a parameter of onReceive(). You even have this code in your onReceive() -- you're just not doing anything with the resulting Intent (e.g., calling startActivity()).

Intent foo = new Intent(this, AlarmRing.class);
foo.putExtra("id", id);//example, if you wish to pass custom variables
this.startActivity(foo);
Edit
Check out this example to use BroadcastReciever within an Activity. http://almondmendoza.com/2009/01/04/getting-battery-information-on-android/

Related

BroadcastReceiver android - Sometimes it continues after closing the app, sometimes not

I have a BroadcastReceiver:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// show will check date and return 0 or 1.
if(show == 1) {
//notify
Intent intent2 = new Intent(context, MainActivity.class);
showNotification(context, "title", "description", intent2);
}
AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intentn = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentn, 0);
Calendar time = Calendar.getInstance();
time.setTimeInMillis(System.currentTimeMillis());
// set next alarm, I also have this in my MainActivity to run it first time every 15 min (900 sec):
if(android.os.Build.VERSION.SDK_INT>=23) {
alarmMgr.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,System.currentTimeMillis() + (1000*900), pendingIntent);
}
else{
alarmMgr.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (1000*900), pendingIntent);
}
}
In manifest I have this:
<receiver
android:name=".AlarmReceiver"
android:enabled="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
The problem is sometimes it plays, sometimes not. Sometimes when I close the app it continue to play, sometimes not. Any ideas why?
I'm testing in android 8.
Remove:
android:permission="android.permission.RECEIVE_BOOT_COMPLETED"
With that, you are saying that the sender of the broadcast has to hold this permission, and that is incorrect.
Your app needs a <uses-permission> element for android.permission.RECEIVE_BOOT_COMPLETED, though.

Repetitive alarm not working in actual devices but working in emulator

I know this is duplicate question but I have tried all the solution available on the Internet but not able to find the solution.
manifest file
<receiver android:name=".UpdateTables"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
calling this method in onCreate() of mainActivity.java and I also tried to call the method from application class.
private void setTheTimeToUpdateTables(Context context) {
Log.i("Update table function","Yes");
AlarmManager alarmManager=(AlarmManager) getSystemService(ALARM_SERVICE);
Intent alarmIntent=new Intent(context,UpdateTables.class);
PendingIntent pendingIntent=PendingIntent.getBroadcast(context,0,alarmIntent,PendingIntent.FLAG_UPDATE_CURRENT);
//alarmManager.cancel(pendingIntent);
Calendar alarmStartTime = Calendar.getInstance();
alarmStartTime.setTimeInMillis(System.currentTimeMillis());
//midnight
alarmStartTime.set(Calendar.HOUR_OF_DAY, 0);
alarmStartTime.set(Calendar.MINUTE, 1);
alarmStartTime.set(Calendar.SECOND, 0);
if(Calendar.getInstance().getTimeInMillis()>alarmStartTime.getTimeInMillis())
{
alarmStartTime.add(Calendar.DATE,1);
}
Log.i("TIME IS ",Long.toString(alarmStartTime.getTimeInMillis()));
System.out.println("Updating table time "+alarmStartTime);
System.out.println("Time in millseconds "+alarmStartTime.getTimeInMillis());
alarmManager.setInexactRepeating(AlarmManager.RTC,alarmStartTime.getTimeInMillis(),AlarmManager.INTERVAL_DAY,pendingIntent);
Log.d("Alarm","Set for midnight");
}
public class UpdateTables extends BroadcastReceiver {
//midnight saga
DbHelper dbHelper;
ArrayList<ListMedicine> reminderInfo;
private SharedPreferences sharedPreferences;
private static AlarmManager alarmManager;
private static void init(Context ctx){
if (alarmManager==null)
alarmManager=(AlarmManager) ctx.getSystemService(Activity.ALARM_SERVICE);
}
#Override
public void onReceive(Context context, Intent intent) {
Log.i("Update tables","yes");
}
When app is closed than it the updatetables broadcast receiver will not call.
output of ./adb shell dumpsys alarm before the app closed.
RTC #5: Alarm{28e47fec type 1 when 1487010660087 user.com.hlthee}
tag=*alarm*:user.com.hlthee/.UpdateTables
type=1 whenElapsed=+23h48m35s946ms when=2017-02-14 00:01:00
window=-1 repeatInterval=86400000 count=0
operation=PendingIntent{24cc8fb5: PendingIntentRecord{19e0864a user.com.hlthee broadcastIntent}}
But when the app is closed from recent activity then this entry is also delete. Why?
thats why no alarm is rang when app is closed.
Any help would be appreciated.
define a custom action name, such as:
public static final String MY_ACTION = "com.sample.myaction"
create a BroadcastReceiver:
public class MyAlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(MY_ACTION)) {
// Do something here
}
}
}
Register the receiver on your AndroidManifest.xml:
<receiver android:name="com.sample.MyAlarmReceiver">
<intent-filter>
<action android:name="com.sample.myaction"/>
</intent-filter>
setup the alarm, use the following PendingIntent:
Intent i = new Intent(MY_ACTION);
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), 0, i, 0);

Start new Activity after few seconds with BroadcastReceiver

I would like to start new activity after few seconds with BroadcastReceiver. New Activity needs to be started even if the app is closed in the meantime.
For now I have this but nothing happens when I run it:
Main.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(), Receiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1, intent, 0);
int seconds = 5;
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, seconds);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);;
}
});
}
Receiver.java
public class Receiver extends BroadcastReceiver {
private PowerManager.WakeLock mWakelock;
#SuppressWarnings("deprecation")
private KeyguardManager.KeyguardLock mLock;
private static ContentResolver sResolver;
#SuppressWarnings("deprecation")
#Override
public void onReceive(Context paramContext, Intent intent) {
this.mWakelock = ((PowerManager) paramContext.getSystemService("power"))
.newWakeLock(805306394/* | PowerManager.ON_AFTER_RELEASE */,
"wakelock");
this.mWakelock.acquire();
this.mLock = ((KeyguardManager) paramContext
.getSystemService("keyguard")).newKeyguardLock("");
this.mLock.disableKeyguard();
setLockPatternEnabled(true);
sResolver = paramContext.getContentResolver();
Intent startMain;
startMain = new Intent(paramContext, NewActivity.class);
startMain.setAction("com.name.NewActivity");
startMain.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
paramContext.startActivity(startMain);
}
/**
* used for to enable lock in all patterns
*
* #param enabled
*/
#SuppressWarnings("deprecation")
public static void setLockPatternEnabled(boolean enabled) {
setBoolean(android.provider.Settings.System.LOCK_PATTERN_ENABLED,
enabled);
}
private static void setBoolean(String systemSettingKey, boolean enabled) {
android.provider.Settings.System.putInt(sResolver, systemSettingKey,
enabled ? 1 : 0);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.name" >
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.Light.NoTitleBar" >
<activity
android:name=".Main"
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="com.name.NewActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.name.NewActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
Does anyone know where is the problem? I also need that this new Activity unlocks the screen if it's locked, like alarm or call does.
You can do something like this: (ignore this one)
int millis = 500;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
startActivity(new Intent(SplashScreenActivity.this, HomeActivity.class));
SplashScreenActivity.this.finish();
}
}, millis);
Update 1 (should work): Try this in your MainActivity, your probably counting time in wrong way so use calendar. If it works, I'll try to explain.
Intent intent = new Intent(this, Receiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, 0); //Or you can get broadcast in your way.
int seconds = 25;
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, seconds);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
Update 2: You should register your receiver in the manifest. In some cases there are intent filters on receivers but I it should work like that. Be sure that name of your package and receiver are correct.
<application ...>
<activity ...>
...
<receiver android:name=".package.YourReceiver">
</receiver>
...
</application>

AlarmManager broadcast not being received

I have been trying to slowly learn the Android API over the past month. I have read documentation, viewed examples and can't seem to figure out what I'm doing incorrectly. Basically the app sets an alarm 1 minute exactly after the app was started.
The issue I am currently having is after setting an alarm, it isn't being received. Here's what I have:
SetAlarmActivity.java
public class SetAlarmActivity extends AppCompatActivity {
private final String TAG = "AlarmTest";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_set_alarm);
Calendar c = Calendar.getInstance();
c.add(Calendar.MINUTE, 1);
Log.d(TAG, "Alarm time is " + c.getTime());
// set the intent to launch our SetAlarmActivity
Intent alarmIntent = new Intent(SetAlarmActivity.this, SetAlarmActivity.class);
// retrieve a PendingIntent to perform a Broadcast
PendingIntent pendingAlarmIntent = PendingIntent.getBroadcast(SetAlarmActivity.this, 0, alarmIntent, 0);
// grab the Alarm Service and tell it to call our Intent at the set time
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingAlarmIntent);
}else{
alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingAlarmIntent);
}
}
}
AlarmReceiver.java
public class AlarmReceiver extends WakefulBroadcastReceiver {
private final String TAG = "AlarmTest";
#Override
public void onReceive(Context context, Intent intent){
Log.d(TAG, "Received broadcast!");
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="bz.bdu.alarmtest" >
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme" >
<activity android:name=".SetAlarmActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".AlarmReceiver" />
</application>
</manifest>
You have to create the intent between the Current activity and receiver class. change your code like this.
Intent intent = new Intent(SetAlarmActivity.this, AlarmReceiver.class);
change
Intent alarmIntent = new Intent(SetAlarmActivity.this,
SetAlarmActivity.class);
to
Intent alarmIntent = new Intent(SetAlarmActivity.this,
AlarmReceiver.class);
then its works fine

Android IntentReceiver never receives custom intent from WidgetProvider

(This is my first SE question ever, but I've relied heavily on this site for it's fantastic community as I've bumbled around learning Java and Android!)
I'm creating an Android widget that (for the time being) has only one button that functions as a two-sided dice. Eventually this widget will support all major RPG dice sizes (d6, d8, d20, etc), but for now I'm just trying to get the intent/receiver system working.
Currently nothing happens when I hit the d2 button in my widget. So far as I can tell by debugging my custom intent is fired, but the onReceive in my IntentReceiver never catches it. Any assistance you can provide would be much appreciated!
Here is my WidgetProvider:
public class MyWidgetProvider extends AppWidgetProvider {
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
remoteViews.setOnClickPendingIntent(R.id.btnReset, buildButtonPendingIntent(context));
Log.e(null, "Setup remote views & Onclick");
Toast.makeText(context, "Test", Toast.LENGTH_SHORT).show();
pushWidgetUpdate(context, remoteViews);
}
public static PendingIntent buildButtonPendingIntent(Context context) {
Intent intent = new Intent();
intent.setAction("ca.sulli.rpgdicewidget.intent.action.D2");
Log.e(null, "Setting new ButtonPendingIntent");
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public static void pushWidgetUpdate(Context context, RemoteViews remoteViews) {
Log.e(null, "Updating widget!");
ComponentName myWidget = new ComponentName(context, MyWidgetProvider.class);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(myWidget, remoteViews);
}
}
And here is my receiver:
public class MyWidgetIntentReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.e(null,"Checking intent by receiver");
if(intent.getAction().equals("ca.sulli.rpgdicewidget.intent.action.D2")){
Log.e(null,"Correct intent received!");
updateWidgetPictureAndButtonListener(context);
}
}
private void updateWidgetPictureAndButtonListener(Context context) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
Log.e(null,"Updating text since the intent was received!");
remoteViews.setTextViewText(R.id.txtResult, "Intent Received! ");
remoteViews.setOnClickPendingIntent(R.id.btnD2, MyWidgetProvider.buildButtonPendingIntent(context));
MyWidgetProvider.pushWidgetUpdate(context.getApplicationContext(), remoteViews);
}
}
And for completions' sake, my manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ca.sulli.rpgdicewidget"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name="MyWidgetProvider" >
<intent-filter >
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="ca.sulli.rpgdicewidget.intent.action.D2" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/widget_info" />
</receiver>
</application>
</manifest>
And the appwidget-provider:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="200dp" android:minHeight="70dp" android:initialLayout="#layout/main" android:updatePeriodMillis="30000">
</appwidget-provider>
Many thanks for any help provided, and many thanks for the help this community has already provided for me by answering so many other questions!
I cannot see anywhere in your code where you are using the PendingIntent that you have created, you can use the alarmmanager to schedule a message, presumably immediately, using code like this:
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (i * 1000), pendingIntent);
Broadcast messages are quite complex though, so you may want to weigh up if you want to use them, you could consider using a regular intent and context.sendBroadcast instead

Categories

Resources