broadcastReceiver doesn't work from notification (pendingIntent) - java

BroadCastReceiver doesn't work if i create PendionIntent by getBroadcast(someArgs);
but if i create by getServie() and catch event in onStartCommand() it work fine
public class someClass extends Service
{
Notification createNotif()
{
RemoteViews views = new RemoteViews(getPackageName(),R.layout.notif);
ComponentName componentName = new ComponentName(this,someClass.class);
Intent intentClose = new Intent("someAction");
intentClose.setComponent(componentName);
views.setOnClickPendingIntent(R.id.notifClose, PendingIntent.getBroadcast(this, 0, intentClose, PendingIntent.FLAG_UPDATE_CURRENT));
Notification notification = new Notification();
notification.contentView = views;
notification.flags |= Notification.FLAG_ONGOING_EVENT;
return notification;
}
#Override
public void onCreate()
{
super.onCreate();
BroadcastReceiver broadcastReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
if(intent.getAction().equals("someAction"))
someMethod();
}
};
IntentFilter intentFilter = new IntentFilter("someAction");
intentFilter.addAction("anyAction");
registerReceiver(broadcastReceiver,intentFilter);
}
}

Your BroadcastReceiver is a local variable inside the onCreate() method. Once you exit that method block, there is nothing holding on to the BroadcastReceiver and it will be garbage collected.
You should instead create a separate class that extends BroadcastReceiver and declare it in your AndroidManifest.xml.
<application ...
...
<receiver android:name=".MyReceiver" >
<intent-filter>
<action android:name="someAction" />
</intent-filter>
</receiver>
</application>

Related

Broadcastreceiver that should be triggered by an alarm remains untriggered

I wanted to set alarms that played audio files. Yet they don't, according to the log, the alarms are not executed. This is my code:
<manifest ...>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<application
...>
<service android:name=".S1" />
<activity
...>
...
</activity>
<receiver
android:name=".A1" >
</receiver>
<receiver
android:name=".A2">
</receiver>
</application>
</manifest>
and
public class S1 extends Service {
public void al(Class Klasse, long Wann)
{
AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this.getApplicationContext(), Klasse);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, intent, PendingIntent.FLAG_ONE_SHOT);
alarmMgr.set(AlarmManager.RTC_WAKEUP, Wann, pendingIntent);
Log.i("Debug","Alarm");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
al(A1.class,time.getTimeInMillis());
al(A2.class,time.getTimeInMillis()+(5*1000));
//...
return START_STICKY;
}
}
and
class A1 extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//...
Log.i("Debug","Play Audio A1");
}
}
class A2 extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//...
Log.i("Debug","Play Audio A2");
}
}
In the logs, I see "Alarm" but neither "Play Audio A1" nor "Play Audio A2".
I am using a Huawei P20 and I followed https://dontkillmyapp.com/huawei. But they still don't fire.

How can i keep a thread in android app forever?

I'm building an enterprise application that needs to get some information about the employees' rooted phones to do corporate management.
This thread needs to run each five minutes.
I'm using an Activity that is started by a broadcast(BOOT_COMPLETED) when the android boots up, and it starts an infinite thread to send this information to server.
My current problem is my application is being killed by android after the user opens a lot of others apps.
What would be the better way to keep a thread running in background to send this information to server?
Main Application Class
public static void startService(Context mContext){
try{
//Schedule Service.
scheduleService(mContext);
//Call onUpdate.
onUpdate();
}catch (Exception o){
Utilities.log(o.toString());
}
}
public static void scheduleService(Context mContext){
try{
final int NOTIFICATION_INTERVAL = 5 * 60 * 1000;
Intent mIntent = new Intent(mContext, ServiceReceiver.class);
AlarmManager mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
PendingIntent mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 0);
mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), NOTIFICATION_INTERVAL, mPendingIntent);
}catch (Exception o){
Utilities.log(o.toString());
}
}
ServiceReceiver
public class ServiceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context mContext, Intent intent) {
Utilities.log("Service Received");
//Start Service.
MyApplication.startService(mContext);
}
}
AndroidManifest
<receiver
android:name=".BootUpReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="android.intent.action.REBOOT"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
<receiver android:name=".ServiceReceiver"/>
BootUpReceiver
public class BootUpReceiver extends BroadcastReceiver
{
public void onReceive(Context mContext, Intent mIntent){
Utilities.log("BootUp Received.");
//Start Service.
MyApplication.startService(mContext);
}
}
create a static broadcast receiver for Repeating Alarms and start Intent Service from broadcast don't use infinite Thread
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationStatus.setupNotification(context); // if you restart your phone
}
}
class NotificationStatus{
//Call only one time from app from any activity
public static void setupNotification(Context context) {
final int NOTIFICATION_INTERVAL = 5 * 60 * 1000;
Intent myIntent1 = new Intent(context, NotificationReceiver.class);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 1, myIntent1, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), NOTIFICATION_INTERVAL, pendingIntent1);
}
}
public class NotificationReceiver extends BroadcastReceiver {
private static final int mNotificationId = 0;
#Override
public void onReceive(Context context, Intent intent) {
//start your services here for sending data
Intent intent1 = new Intent(context, SyncService.class);
context.startService(intent1);
}
}
public class SyncService extends IntentService {
public SyncService(String name) {
super(name);
}
#Override
protected void onHandleIntent(Intent intent) {
//Write code here for sending data to server
}
}
AndroidManifest
<receiver android:name="NotificationReceiver" />
<receiver android:name="BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
Define Service in Manifest
<service android:name=".SyncService"/>
You need to make your application an Android service.

Android: Repeat tasks in background. Does my approach is correct?

I read several threads about repeat asynchronous tasks in background, I first used this way: https://stackoverflow.com/a/6532298 but for some reasons, it seems that after sometime (several hours), it stopped.
So, now I am using this way, but I don't know if this is a good way to proceed:
BroadcastReceiver
public class RetrieveDataTaskBroadcast extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
SharedPreferences mSharedPreferences = context.getSharedPreferences(MY_PREF, 0);
int delayInMs = mSharedPreferences.getInt("set_delay_refresh", 20)*60*1000;
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, RetrieveDataService.class);
PendingIntent pi = PendingIntent.getService(context, 0, i, 0);
am.cancel(pi);
if (delayInMs > 0) {
am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + delayInMs,
delayInMs, pi);
}
}
}
My service class:
public class RetrieveDataService extends Service implements OnRefreshInterface {
private Context context;
private PowerManager.WakeLock mWakeLock;
private static final String TAG = "REFRESH_SERVICE";
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void handleIntent(Intent intent) {
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mWakeLock.acquire();
//do the work
callAsynchronousTask();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
handleIntent(intent);
return START_NOT_STICKY;
}
public void onDestroy() {
super.onDestroy();
mWakeLock.release();
}
#Override
public void onCreate() {
super.onCreate();
context = this;
callAsynchronousTask();
}
public void callAsynchronousTask() {
//My asynchronous task => execute a class that extends AsyncTask
[...]
}
#Override
public void onRefreshInterface(int cb_val1, int cb_val2) {
//Callback when refresh is done
[...]
}
}
androidmanifest.xml:
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
...
<service
android:name="com.example.package.RetrieveDataService"
android:enabled="true"
android:label="Refresh Data">
</service>
<receiver
android:name="com.example.package.RetrieveDataTaskBroadcast"
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" />
</intent-filter>
</receiver>
I also added a way to launch the service when the app starts:
MainActivity:
#Override
protected void onResume() {
super.onResume();
Thread t = new Thread(){
public void run(){
SharedPreferences mSharedPreferences = getSharedPreferences(PREF, 0);
int delayInMs = mSharedPreferences.getInt("set_delay_refresh", 20)*60*1000;
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(MainBaseActivity.this, RetrieveDataService.class);
PendingIntent pi = PendingIntent.getService(MainBaseActivity.this, 0, i, 0);
am.cancel(pi);
am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + delayInMs,
delayInMs, pi);
}
};
t.start();
}
Thank you for your help and advice.
You dont need a service to launch the repeated task when the device starts. Your task will never run when the device is off.
You can set a repeating alarm using Alarm Manager.
If the trigger time you specify is in the past when the device was off, the alarm triggers immediately when the device turns on.
Check this - https://developer.android.com/training/scheduling/alarms.html

Notification.Builder does not create a notification

Im trying to create a notification from an edittext and broadcast receiver. In my first Activity the user should input a message and push the broadcast button. I want to take that string and create a notification from it and open a new activity that displays the message. I am doing all the notification work in my broadcast receiver class.
I have looked around onlne at examples and other peoples code but im not sure what im not getting right. The application loads up just fine and the broadcast button sends the broadcast to the receiver and Logs the string but the notification is never created.
Thanks for any help.
Broadcast class that sends broadcast message:
public class BroadcastReceiverActivity extends Activity
{
EditText et;
Button btn1;
public static String BString = "HappyHemingway";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_broadcast_receiver);
et = (EditText)findViewById(R.id.et1);
btn1 = (Button)findViewById(R.id.btn1);
btn1.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
String message = et.getText().toString();
send(message);
}
});
}
/*
* This function creates an intent and
* sends a broadcast from the message
* parameter passed in.
*/
protected void send(String msg)
{
Log.i("msg", msg);
Intent i = new Intent();
i.putExtra("message",msg);
i.setAction(BString);
sendBroadcast(i);
}
}
Receiver class that creates notification:
public class Receiver extends BroadcastReceiver
{
// #SuppressLint("NewApi")
#Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if(action!=null&&action.equals("HappyHemingway"))
{
String msg = intent.getStringExtra("message");
Log.i("Received",msg);
Intent i = new Intent(context,ViewNotification.class);
i.putExtra("message",msg);
PendingIntent pi = PendingIntent.getActivity(context, 0, i,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder builder = new Notification.Builder(context).
setSmallIcon(0).setAutoCancel(true).setTicker(msg).
setWhen(System.currentTimeMillis()).setContentTitle("New Notification!").
setContentText(msg).setContentIntent(pi);
NotificationManager mgr = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification n = builder.build();
mgr.notify(0, n);
Log.i("Received again",msg);
}
}
}
notification viewer class that is never launched
public class ViewNotification extends Activity
{
String text;
TextView txttext;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.viewnotification);
NotificationManager notificationmanager;
notificationmanager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationmanager.cancel(0);
Intent i = getIntent();
text = i.getStringExtra("message");
txttext = (TextView) findViewById(R.id.text);
txttext.setText(text);
Log.i("made it", "made it made it made it");
}
}
manifest
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".BroadcastReceiverActivity"
android:label="#string/app_name" >
<action android:name="android.intent" />
<category android:name="android.intent.category.LAUNCHER" />
</activity>
<activity android:name=".ViewNotification"></activity>
<receiver android:name="Receiver">
<intent-filter>
<action android:name="HappyHemingway">
</action>
</intent-filter>
</receiver>
</application>
</manifest>
Hopefully its just a simple error I'm overlooking.This is my first time using Android Studio instead of Eclipse but I dont see how that could make any difference under than my unfamiliarity with the IDE.
Anything helps
thanks.
I'm not sure why I had setSmallIcon(0.)
When I changed it to setSmallIcon(R.drawable.ic_launcher) everything worked fine.

How to start activity when user clicks a notification?

I am attempting to convert some code I found in a tutorial for my own use. Originally, the code launched the system contacts list when the user would click a notification generated by my app. I am trying to start an Activity of my own instead of launching the contact list, but it's not working. More specifically, nothing happens. There is no error, and my Activity doesn't load either. The notification window disappears after clicking, and the original Activity is still visible.
Here is my code:
public class MyBroadcastReceiver extends BroadcastReceiver {
private NotificationManager mNotificationManager;
private int SIMPLE_NOTFICATION_ID;
public void onReceive(Context context, Intent intent){
Bundle extras = intent.getExtras();
String deal = (String) extras.get("Deal");
String title = "Deal found at " + (String) extras.get("LocationName");
mNotificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notifyDetails = new Notification(R.drawable.icon, title,System.currentTimeMillis());
Class ourClass;
try {
ourClass = Class.forName("com.kjdv.gpsVegas.ViewTarget");
Intent startMyActivity = new Intent(context, ourClass);
PendingIntent myIntent = PendingIntent.getActivity(context, 0,startMyActivity, 0);
notifyDetails.setLatestEventInfo(context, title, deal, myIntent);
notifyDetails.flags |= Notification.FLAG_AUTO_CANCEL;
notifyDetails.flags |= Notification.DEFAULT_SOUND;
mNotificationManager.notify(SIMPLE_NOTFICATION_ID, notifyDetails);
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
This is my entry in the AndroidManifext.xml file...
<activity android:name=".ViewTarget" android:label="#string/app_name" >
<intent-filter>
<action android:name="com.kjdv.gpsVegas.ViewTarget" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
And this is my Activity that I want to launch...
public class ViewTarget extends ListActivity {
public ListAdapter getListAdapter() {
return super.getListAdapter();
}
public ListView getListView() {
return super.getListView();
}
public void setListAdapter(ListAdapter adapter) {
super.setListAdapter(adapter);
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.locations);
Log.v("db", "Inside ViewTarget");
}
}
Which Android version are you running on? You might wanna try using NotificationCompat instead. This class is include in the latest support package.
Intent notificationIntent = new Intent(context, ViewTarget.class);
PendingIntent contentIntent = PendingIntent.getActivity(context,
0, notificationIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
NotificationManager nm = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Resources res = context.getResources();
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setContentIntent(contentIntent)
.setSmallIcon(R.drawable.app_icon)
.setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.app_icon))
.setTicker(payload)
.setWhen(System.currentTimeMillis())
.setAutoCancel(true)
.setContentTitle("Message")
.setContentText(payload);
Notification n = builder.getNotification();
n.defaults |= Notification.DEFAULT_ALL;
nm.notify(0, n);
EDIT:
I know this is an old thread/question but this answer helped me for showing the activity when tapping the notification.
For those people that this isn't working is probably because you haven't "registered" the activity in your manifest. For example:
<activity
android:name="com.package.name.NameOfActivityToLaunch"
android:label="Title of Activity" >
<intent-filter>
<action android:name="com.package.name.NAMEOFACTIVITYTOLAUNCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
And, hopefully, this should work.
Hope it helped...
you should set action and category for Intent.
Intent startMyActivity = new Intent(context, ourClass);
startMyActivity .setAction(Intent.ACTION_MAIN);
startMyActivity .addCategory(Intent.CATEGORY_LAUNCHER);
it works
I figured out the problem. I forgot to include the package name in the activity declaration in the Manifest file.
Wrong:
activity android:name=".ViewTarget" android:label="#string/app_name"
Correct:
activity android:name="com.kjdv.gpsVegas.ViewTarget" android:label="#string/app_name"
Can you try removing the Intent filter, so it looks like this:
<activity android:name=".ViewTarget" android:label="#string/app_name" />
Also, not sure if this code will work:
ourClass = Class.forName("com.kjdv.gpsVegas.ViewTarget");
Intent startMyActivity = new Intent(context, ourClass);
Can you try it like this instead:
Intent startMyActivity = new Intent(context, ViewTarget.class);
In order to launch an Activity from an Intent, you need to add a flag:
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
This is true even if you declare the class in the Intent's constructor.
check this code
public class TestActivity extends Activity {
private static final int UNIQUE_ID = 882;
public static NotificationManager nm;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Intent navigationIntent = new Intent();
navigationIntent.setClass(classname.this, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, navigationIntent,
0);
String body = "New notificattion added!!!";
String title = "Notification";
Notification n = new Notification(R.drawable.icon, body,
System.currentTimeMillis());
//this is for giving number on the notification icon
n.number = Integer.parseInt(responseText);
n.setLatestEventInfo(this, title, body, pi);
n.defaults = Notification.DEFAULT_ALL;
nm.notify(UNIQUE_ID, n);

Categories

Resources