How do I use Intent.ACTION_TIME_TICK correctly?
I would like to create a receiver which checks the battery-level every minute.
I use a Broadcast-receiver class witch is first started from main-Activity.
Starting the broadcast receiver is not the problem. When the app is open everything works fine. However, if the app ends, I will no longer receive broadcast information.
Now to my problem: how can I continue to receive information after completing the app?
My Sourcecode.
Start the Broadcast:
public class Main extends AppCompatActivity {
[...]
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String app = getResources().getString(R.string.app_name);
[...]
btnStart.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
registerReceiver(receiver, new IntentFilter(Intent.ACTION_TIME_TICK));
Log.d(app + ".Main", "register receiver with '" + Intent.ACTION_TIME_TICK + "'");
}
});
}
}
Receive information in Receiver.class:
public class Receiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
BatteryManager bm = (BatteryManager)context.getSystemService(context.BATTERY_SERVICE);
int akku = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
Calendar calendar = Calendar.getInstance();
int minute = calendar.get(Calendar.MINUTE);
if(action.equals(Intent.ACTION_TIME_TICK))
{
Log.d(app + ".Receiver", "Receiver detected '" + action + "'");
if(minute%5 == 0) {
startNotification(akku);
}
}
}
}
Manifest:
<receiver android:name=".Receiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.ACTION_TIME_TICK"></action>
</intent-filter>
</receiver>
You need to registre the receiver in Service, than it will work on background.
I dont know it on 100%, but I think that TIME_TICK doesnt work if you define it in manifest, you must register it in class.
you need to register your broadcaster subclass either on subclassed applicant onCreate() {...} or in your activity..
You can use the service for running in the background even after your app is closed and will notify the required.
Related
I'm just getting familiarised with the Local Broadcast Messages. I have 2 activities.
MainActivity :
I have 2 buttons. On the click of 1 button, I'm broadcasting the message. On the click of another one, I'm navigating to second Activity.
public class MainActivity extends AppCompatActivity {
Button btn;
Button btn1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button)findViewById(R.id.sendBroadCast);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendMessage();
}
});
btn1 = (Button)findViewById(R.id.btn);
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
}
});
}
void sendMessage(){
Log.d("RAK","Gonna send braodcast");
Intent intent = new Intent("customMsg");
intent.putExtra("message", "This is my message!");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
Second Activity :
Registering for the receiver in onCreate of this activity.
public class SecondActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Log.d("RAK","In oncreate of second activity.Registered for local receiver");
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("customMsg"));
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Get extra data included in the Intent
String message = intent.getStringExtra("message");
Log.d("receiver", "Got message: " + message);
}
};
#Override
protected void onDestroy() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onDestroy();
}
}
The issue I'm facing is, the second Activity is not receiving the broadcast. Please help me.
P.S : Please dont mark this a duplicate. I have followed this link : how to use LocalBroadcastManager?
Thanks,
Rakesh
So as to receive the broadcast the second activity should be up and running while the first one is sending a broadcast, which is going to be hard in your case (2 activities not running at same time).
Your first Activity sends the broadcast, but no activity (in your case second activity) is launched yet so the messgae get 'lost'.
You could test by broadcasting from within a service for example, and your second activity running. Then, the activity could handle/receive it.
What you may want to do is passing a String to the secondActivity using extraData. If you wish to test BroadcastReceiver, then, try with a service sending the broadcast !
The problem is your registering your broadcast receiver inside onCreate() of second activity, that means the second activity should have been previous launched before you broadcast your intent keeping in mind that your do not unregister it when the second activity is destroyed.
Alternative you can register your receiver statically in the Manifest file
public class Receiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
// Whatever
}
}
Manifest
<receiver
android:name=".Receiver"
android:exported="false" >
<intent-filter>
<action android:name="customMsg" />
</intent-filter>
</receiver>
NOTE:
Registering statically ensure that the the receiver is registered at system boot time or when the application is added at run time
I have an app that downloads data and put it into an SQLite Database when a notification is issued. This works fine while the app is in use but I need it to work when the app is closed too.
I have set up a BroadcastReceiver within that is called when the app is closed but I'm not sure how to get it to continue with adding to the database.
Here is the code I am using:
AndroidManifest.xml
<manifest....
<application...
<receiver android:name=".broadcast.PacksReceiver" >
<intent-filter>
<action android:name="ADD_PACK" >
</action>
</intent-filter>
</receiver>
PacksReceiver
public class PacksReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("PacksReceiver", "onReceive");
String message = intent.getStringExtra("message");
PacksActivity pa = new PacksActivity();
pa.downloadPack(null, message);
}
}
PacksActivity
public void downloadPack(View v, String thisPackID){
Log.d("download", "pack");
//THIS LOG IS CALLED EVERYTIME
vRef = v;
if(vRef != null){
runOnUiThread(new Runnable() {
#Override
public void run() {
onScreenProgressBar = (ProgressBar) vRef.findViewById(R.id.onScreenProgress);
onScreenProgressCircle = (ProgressBar) vRef.findViewById(R.id.onScreenProgressCircle);
dlPercent = (TextView) vRef.findViewById(R.id.dlPercent);
onScreenProgressCircle.setVisibility(View.VISIBLE);
onScreenProgressBar.setVisibility(View.VISIBLE);
onScreenProgressCircle.setProgress(0);
}
});
}
if(thisPackID == null){
thisPackID = pack_id;
}
String url = MyApp.getAppContext().getString(R.string.serverURL) +
MyApp.getAppContext().getString(R.string.getAppendixA) + "/" + thisPackID;
Intent appA_Intent = new Intent(Intent.ACTION_SYNC, null, this, DownloadService.class);
appA_Intent.putExtra("url", url);
appA_Intent.putExtra("onCreate", "false");
appA_Intent.putExtra("receiver", downloadPackReceiver);
appA_Intent.putExtra("downloadType", "GET_APPENDIX_A");
appA_Intent.putExtra("requestId", 101);
MyApp.getAppContext().startService(appA_Intent);
}
start the Service from
onReceive()
method because you can get mutiple broadcast one after another.
Write the code to add data in your database in your PackReciever inside OnRecieve() Method because that is where you recieve push notifications.
Don't call activity inside the receiver. Instead, use IntentService to download all packs. IntentService automatically finishes once it completes its work.
Override its onHandleIntent() method and download packs and save to database there.
I have a MainActivity and a MyBroadcastReceiver. The BroadcastReceiver waits for incoming SMSes and reads the sms and senderId, it should send this data to MainActivity in real time. I have tried to implement the BroadcastReceiver in the Activity itself but it launches the activity again.
Public class MainActivity extends AppCompatActivity{
public static String BROADCAST_ACTION = "SMSCOMING";
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final Bundle bundle = intent.getExtras();
try {
//Getting the data d
triggerFunc(d);
}
}
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter filter = new IntentFilter();
filter.addAction(BROADCAST_ACTION);
this.registerReceiver(this.broadcastReceiver, filter);
}
void triggerFunc(data d){
//Do some stuff
}
}
Please note that we have two kind of broadcast receivers in Android:
Standalone broadcast receivers (one of four main Android building blocks). This type of receivers must be registered in Android manifest file. These receivers will be run whenever their matching intents are received, no matter app's UI is running or not.
In-Activity broadcast receivers. This kind of receivers don't need to be registered in Manifest file, you should instead register them at runtime. These receivers are only run when their enclosing activity is active and running.
So, if you would like your app to be able to catch all SMS messages, regardless of its UI status, you would need the former option. However if you would need your app to catch SMS message while its activity is shown, you would need the latter option.
When the BroadcastReceiver receives an SMS notification, it cannot know if the Activity is running or not. If you want to launch the Activity, you need to create an appropriate Intent and call Context.startActivity().
You should create a class which extends BroadcastReceiver rather than simply an instance of an anonymous inner class. Also, you should register your BroadcastReceiver using the <receiver> tag in AndroidManifest.xml.
whatever code you have added in question as per that your Receiver only called when you Activity is running. instead of that create broadcast separately(remove from activity & create new class in your package) and register in AndroidManifest file and call your activity from Receiver.
just like below.
create BroadcastReceiver Class in your package.
public class BinarySMSReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
final Bundle bundle = intent.getExtras();
try {
//Getting the data d
Intent intent = new Intent();
intent.setClassName(context, "activity.class");
intent.putExtras(bundle);
context.startActivity(intent);
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
};
in AndroidManifest
<receiver android:name="com.company.application.SMSBroadcastReceiver" >
<intent-filter android:priority="500">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
First,I have searched for the question and found about 2-3 stackoverflow links but I dont get a definite answer.Basically,my app needs to start a activity when the phone is docked (any type of dock) or when screen is off.I registered a broadcast receiver in manifest:
<receiver android:name=".BootReciever">
<intent-filter >
<action android:name="android.intent.action.ACTION_DOCK_EVENT"/>
<action android:name="android.intent.action.SCREEN_OFF"/>
</intent-filter>
</receiver>
And in my class:
public class BootReciever extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals(Intent.ACTION_DOCK_EVENT)){
//work for dock
}
if (action.equals(Intent.ACTION_SCREEN_OFF)) {
//work for screen off
}
}
}
But both doesnt work.My work is not done is both the cases.I read about I have to do it in services but since I have never worked with my own service and I fell android.developers.com is a bit of pro friendly,I have difficulty getting it to work.Can somebody say me how to I achieve the above?And my app has to listen for it as long service.So even when my app isnt in foreground.Thanks for your help.
The SCREEN_OFF has definitely to be registered programatically (see this link for instance, it'a a protected intent):
public class MainActivity extends Activity {
BroadcastReceiver receiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("TAG", "on or off");
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
Log.d("TAG", "Register receiver");
registerReceiver(receiver, filter);
} catch (Exception e) {
Log.d("TAG", "Caught: " + e.getStackTrace());
}
}
#Override
public void onDestroy() {
super.onDestroy();
try {
Log.d("TAG", "Unregister receiver");
unregisterReceiver(receiver);
} catch (Exception e) {
Log.d("TAG", "Caught: " + e.getStackTrace());
}
}
}
For the ACTION_DOCK_EVENT I would assume something else being wrong. May be it doesn't work due to the combination with ACTION_SCREEN_OFF, may be it's due to a naming issue (I wouldn't expect a relative path for .BootReciever, for instance; check, if a full qualified class name works).
Hope this helps .... Cheers!
Receivers for these kinds of intents need to be registered dynamically in the code.
this.receiver = new BootReceiver();
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_DOCK_EVENT);
this.registerReceiver(receiver, filter);
You could do this in any activity (register in onStart(), un-register in onStop(), see visible lifetime section) or in you application object.
The problem with dynamic registration though is your application has to be started before BootReceiver can receive intents.
I've found a lot of pages about this in the web, but none of them helped me. I've been for hours stucked in this problem. That's why i decided to make my own question.
What I want to do is an application that receives an intent of the type ACTION_MEDIA_BUTTON and the method onReceive() of the Broadcastreceiver does something.
My Activity is like this:
public class MusicControlActivity extends Activity {
private MediaButtonIntentReceiver receiver = new MediaButtonIntentReceiver();
#Override
public void onCreate(Bundle p_SavedInstanceState) {
super.onCreate(p_SavedInstanceState);
setContentView(R.layout.main);
IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
filter.setPriority(1000);
registerReceiver(receiver,filter);
}
#Override
public void onDestroy()
{
unregisterReceiver(receiver);
}
And my broadcastreceiver as follow:
public class MediaButtonIntentReceiver extends BroadcastReceiver {
public MediaButtonIntentReceiver()
{
super();
}
#Override
public void onReceive(Context context, Intent intent)
{
String v_IntentAction = intent.getAction();
if (!Intent.ACTION_MEDIA_BUTTON.equals(v_IntentAction)) {
return;
}
KeyEvent v_Event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (v_Event == null) {
return;
}
int v_Action = v_Event.getAction();
if (v_Action == KeyEvent.ACTION_DOWN) {
// do something
Toast.makeText(context, "BUTTON PRESSED!", Toast.LENGTH_SHORT).show();
}
abortBroadcast();
}
}
The problem is that it doesn't work, no matter what I do. I've tried registering it dynamically with registerReceiver as in the code above. Also I've tried statically in the AndroidManifest.xml like this:
<receiver android:name=".MediaButtonIntentReceiver" android:enabled="true">
<intent-filter android:priority="10000000">
<action android:name="android.intent.action.ACTION_MEDIA_BUTTON" />
</intent-filter>
</receiver>
And as you can see I've set the priority to a high level and even though it doesn't work.
I've been on this for the whole day and I don't know what to do. The method onReceive from the broadcastreceiver isn't called anytime.
Does anyone know what should I do?
Use android.intent.action.MEDIA_BUTTON Instead in your manifest. Check : http://developer.android.com/training/managing-audio/volume-playback.html
First, you should stop using Toast as your diagnostic test. Use the Log class to log to LogCat, or breakpoints, or something.
Next, you should get rid of your MediaButtonIntentReceiver constructor, as it is not needed.
Then, I would dump the if (!Intent.ACTION_MEDIA_BUTTON.equals(v_IntentAction)) block, since it is also not needed.
Next, I would make sure that your media button actually works. Does it control other applications, like a music player? It may be that your media button is not Android-compliant or something.