Hi this is my first question on stackoverflow and I'm a beginner on Android programming. I've looked through numerous webpages but can't seem to find my solution. What I'm trying to do is launch a new activity when a button is pressed after 5 seconds with a BroadcastReceiver. This activity will have a new UI with graphics and sounds (eventually). I got the BroadcastReceiver to work but the program crashes when it tries to launch the new intent. What am I doing wrong?
The method in my MainActivity class:
public void setAlarm(){
Intent intent = new Intent(MainActivity.this, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis() + 5 * 1000, pendingIntent);
}
My BroadcastReceiver class:
public class MyBroadcastReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent){
Intent intent1 = new Intent(context, ShakeActivity.class);
context.startActivity(intent1);
Toast.makeText(context, "Broadcast works", Toast.LENGTH_LONG).show();
}
}
Manifest file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.shakecounter"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.shakecounter.MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.shakecounter.ShakeActivity"
android:label="#string/title_activity_shake" >
</activity>
<receiver android:name="com.example.shakecounter.MyBroadcastReceiver">
</receiver>
</application>
</manifest>
Intent intent1 = new Intent(context, ShakeActivity.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent1);
Try this one.
Intent iAlarm = new Intent( mcontext1, Alertdialogclass.class );
iAlarm.addFlags(Intent.FLAG_FROM_BACKGROUND);
iAlarm.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mcontext1.startActivity(iAlarm);
You have to put the flag FLAG_ACTIVITY_NEW_TASK when You are starting from inside a Receiver:
Intent intent1 = new Intent(context, ShakeActivity.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent1);
If there is another problem, You should post the logcat.
Related
I am developing android application which need auto restart when restart device for that I am using broadcast receiver with action BOOT_COMPLETED.
Broadcast receiver is receiving message when I am restarting device but in restart method I want to start main activity for that I used Intent but in onReceive method of receiver I am getting null context so I am unable to restart main Activity.
Below is code for that.
MainActivity.java
private Object activity;
private TextView tvImeiNum;
private BroadcastReceiver rebootreceiver;
private IntentFilter filter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvImeiNum = (TextView)findViewById(R.id.tv_imeinum);
filter = new IntentFilter();
filter.addAction(Intent.ACTION_BOOT_COMPLETED);
filter.addAction(Intent.ACTION_REBOOT);
rebootreceiver = new BootUpReceiver(MainActivity.this);
LocalBroadcastManager.getInstance(this).registerReceiver(rebootreceiver,
filter);//registering receiver
generateUniqueCode();
}
BootupReceiver.java
public class BootUpReceiver extends BroadcastReceiver {
MainActivity ma;
public BootUpReceiver(MainActivity maContext){
ma=maContext;
}
public BootUpReceiver(){
}
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
Log.d("TAG REBOOT", "onReceive: " + intent);
Log.d("Reboot complete", "connection");
GlobalTool.restartApplication(context);
}
}
}
GlobalTool.java
public class GlobalTool {
#RequiresApi(api = Build.VERSION_CODES.M)
public static void restartApplication(Context context) {
Log.d("IN App restart:", "");
Log.d("TAG", "restartApplication: ");
if(context != null)
{
Log.d("TAG NULL", "restartApplication: ");
Intent mainIntent = new Intent(context, MainActivity.class);
AlarmManager alarmMgr = (AlarmManager)
context.getSystemService(ALARM_SERVICE);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addNextIntent(mainIntent);
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
long alarmTime = System.currentTimeMillis() + (1 * 1000);
alarmMgr.setExact(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
Log.d("TAG", "restartApplication: 111");
Log.d("TAG", "restartApplication: 111");
}
else {
Intent mainIntent = new Intent(context, MainActivity.class);
AlarmManager alarmMgr = (AlarmManager)
context.getSystemService(ALARM_SERVICE);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addNextIntent(mainIntent);
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
long alarmTime = System.currentTimeMillis() + (1 * 1000);
alarmMgr.setExact(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
Log.d("TAG", "restartApplication: 111");
Log.d("TAG", "restartApplication: 111");
}
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.kioskappdemo">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:name="KioskApplication"
android:allowBackup="true"
android:dataExtractionRules="#xml/data_extraction_rules"
android:fullBackupContent="#xml/backup_rules"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.KioskAppDemo"
tools:targetApi="31"
tools:ignore="Instantiatable">
<service
android:name=".RebootService"
android:enabled="true"
android:exported="true"></service>
<activity
android:name=".MainActivity"
android:exported="true"
android:screenOrientation="landscape"
android:theme="#style/Theme.AppCompat.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".Activity.BootUpReceiver"
android:enabled="true"
android:exported="true">
<intent-filter >
<action
android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.REBOOT" />
<action
android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="com.reboot.test" />
<action
android:name="android.intent.action.TIMEZONE_CHANGED" />
<action
android:name="android.intent.action.DATE_CHANGED" />
</intent-filter>
</receiver>
</application>
</manifest>
Some you code improvements:
Don't put context to Brodcast Receiver constructor. Use the Context from onReceive method
public class BootUpReceiver extends BroadcastReceiver {
public BootUpReceiver(){
//TODO log
}
...
You should not use LocalBroadcastManager::registerReceiver call. If Broadcast receiver is added to AndroidManifest then it will be started by the system.
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver
android:name=".activity.BootUpReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Don't use CamelCase for package names (use .activity.BootUpReceiver insetad .Activity.BootUpReceiver)
I have implemented a simple app in order to set an alarm (e.g. 7.00pm) every minute. When running this app at emulator, which android version is 8.1, it runs successfully in background even the app is killed. But when running the same app at my android 9 when app is killed it stops running in background.
public class MainActivity extends AppCompatActivity {
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.context = this;
ComponentName receiver = new ComponentName(this, AlarmReceiver.class);
PackageManager pm = this.getPackageManager();
pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
Intent alarm = new Intent(this.context, AlarmReceiver.class);
alarm.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
boolean alarmRunning = (PendingIntent.getBroadcast(this.context, 0, alarm, PendingIntent.FLAG_NO_CREATE) != null);
if(alarmRunning == false) {
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.context, 0, alarm, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime(), 60000, pendingIntent);
}
}
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-permission android:name="com.android.alarm.permission.FLAG_ACTIVITY_NEW_TASK" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<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=".BackgroundService" />
<receiver android:name=".AlarmReceiver"
android:enabled="true"
android:exported="true"
android:label="RestartServiceWhenStopped">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.bluetooth.adapter.action.STATE_CHANGED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="android.intent.action.TIME_SET" />
</intent-filter>
</receiver>
</application>
AlertReceiver.java
public class AlarmReceiver extends BroadcastReceiver {
private static int minutes=0;
#Override
public void onReceive(Context context, Intent intent) {
Log.e("Service",String.valueOf(Calendar.getInstance().getTimeInMillis()));
intent = new Intent(AlarmClock.ACTION_SET_ALARM);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
minutes++;
intent.putExtra(AlarmClock.EXTRA_HOUR, 7);
intent.putExtra(AlarmClock.EXTRA_MINUTES, minutes);
context.startActivity(intent);
/*Intent background = new Intent(context, BackgroundService.class);
context.startService(background);*/
}
Do you have any idea how to fix this? Thank you in advance!
I wrote my custom broadcast receiver to receive intents from my other app but it doesn't recieve anything. Im sure that first app is sending broadcast corectly. Can someone help me?
App1:
public void broadcastIntent() {
Intent intent = new Intent();
String permissions = "com.example.android.mybroadcastreceiver.my_permissions.MY_PERMISSION";
intent.putExtra("name", editName.getText().toString());
intent.putExtra("price", Float.parseFloat(editPrice.getText().toString()));
intent.putExtra("quantity", Integer.parseInt(editQuantity.getText().toString()));
intent.setAction("com.example.android.projekt1.notification");
sendBroadcast(intent, permissions);
}
And I run this function on my setOnClickListener method.
There is my broadcast receiver:
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Intennt received.", Toast.LENGTH_LONG).show();
Intent serviceIntent = new Intent(context, MyService.class);
serviceIntent.putExtras(intent);
context.startService(serviceIntent);
}
}
So while sending broadcast I have 0 toast messages and my service doesn't run too.
There is androidManifest from receiver:
<?xml version="1.0" encoding="utf-8"?>
<permission-group android:name="com.example.android.mybroadcastreceiver.my_permissions"
android:label="my permissions group"/>
<permission android:name="com.example.android.mybroadcastreceiver.my_permissions.MY_PERMISSION"
android:permissionGroup="com.example.android.mybroadcastreceiver.my_permissions"
android:label="my permission"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".MyBroadcastReceiver"
android:permission="com.example.android.mybroadcastreceiver.my_permissions.MY_PERMISSION">
<intent-filter>
<action android:name="com.example.android.projekt1.notification">
</action>
</intent-filter>
</receiver>
<service android:name="MyService" />
</application>
I run my receiver first then I run my main app and press the button to send broadcast
set package name of targeting application:
public void broadcastIntent() {
Intent intent = new Intent();
String permissions = "com.example.android.mybroadcastreceiver.my_permissions.MY_PERMISSION";
intent.putExtra("name", editName.getText().toString());
intent.putExtra("price", Float.parseFloat(editPrice.getText().toString()));
intent.putExtra("quantity", Integer.parseInt(editQuantity.getText().toString()));
intent.setAction("com.example.android.projekt1.notification");
intent.setPackage("Package name of receiver app");// set Package of targeting app
sendBroadcast(intent, permissions);
}
Can you spot any reason as to why BroadcastReceiver is not being called when the Alarm goes off? If I have the alarm launch an explicit intent, it works just fine and my activity opens. If I set the intent to open my BroadCastReceiver then nothing happens so I think there may be something wrong with my receiver class or the Manifest. Here's how I setup the alarm:
Intent intent = new Intent(this, AlarmBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 324, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mAlarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
mAlarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
Here's my broadcast receiver:
public class AlarmBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.e("MJH", "Alarm called...");
Toast.makeText(context, "Alarm...", Toast.LENGTH_LONG).show();
}
}
And here is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest package="mjh.com.apod"
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Required to act as a custom watch face. -->
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:name="android.support.multidex.MultiDexApplication"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<receiver
android:name=".AlarmBroadcastReceiver"
android:enabled="true"
android:exported="true"
android:process=":remote">
</receiver>
</application>
Thank you so very much for your time.
I think you should be using PendingIntent.getBroadcast( instead of PendingIntent.getActivity(.
I had to call getBroadcast rather than getActivity to create the PendingIntent. That fixed it.
I am trying to follow the example given here on running some code in fixed time intervals. I used the code in this example (setting the waiting time to 1 minute instead), compiled it, started in on my phone, stopped the application on the phone, and waited for several minutes.
However, no Toast was shown and neither any log-entry. I also notice that the Service.onStart seems depreciated.
Is something missing in the example? Do I need to register something when the main activity of the app is started? Or call it from somewhere else in my app? Or maybe something is wrong in the manifest?
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mypackage.test" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application>
android:allowBackup="true"
android:icon="#mipmap/stoxx"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.Light" >
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".NewEntryActivity"
android:label="#string/menu_add"
android:theme="#style/AppTheme.NoActionBar"
/>
<activity
android:name=".UserSettingActivity"
android:label="#string/menu_add"
android:theme="#style/AppTheme.NoActionBar"
/>
<receiver
android:process=":remote"
android:name=".Alarm">
</receiver>
</application>
</manifest>
You forgot to include service in your Manifest. Here is all this project that works for me, check it.
Here is my manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.alarmmanager.just_me.alarmmanager">
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application android:allowBackup="true" android:label="#string/app_name"
android:icon="#mipmap/ic_launcher" android:supportsRtl="true"
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>
<receiver android:process=":remote" android:name=".Alarm"/>
<service android:name=".MyService"/>
</application>
Here is Alarm:
public class Alarm extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();
// Put here YOUR code.
Toast.makeText(context, "com.alarmmanager.just_me.alarmmanager.Alarm !!!!!!!!!!", Toast.LENGTH_LONG).show(); // For example
wl.release();
}
public void SetAlarm(Context context)
{
AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, Alarm.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 5, pi); // Millisec * Second
}
public void CancelAlarm(Context context)
{
Intent intent = new Intent(context, Alarm.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}}
Here is service:
public class MyService extends Service
{
Alarm alarm = new Alarm();
public void onCreate()
{
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.d("!~!", "Service started.");
alarm.SetAlarm(this);
return START_STICKY;
}
#Override
public void onStart(Intent intent, int startId)
{
alarm.SetAlarm(this);
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
}
And the last one MainActivity:
public class MainActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, MyService.class);
startService(intent);
}
}