Im trying to do a simple broadcast in Android to detect the screen is on. For me this is a learning excersize to understand the Android broadcast capabilities. Please help.
I have the Android XML
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".UsbddActivity"
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=".BootReceiver">
<intent-filter>
<action android:name="android.intent.action.SCREEN_ON"></action>
</intent-filter>
</receiver>
</application>
The main Java file
package usb.usbd;
import android.app.Activity;
import android.os.Bundle;
public class UsbddActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
The Broadcast class That supposed to display the toast.
package usb.usbd;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class BootReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context arg0, Intent arg1) {
Toast.makeText( arg0, "worked", Toast.LENGTH_LONG).show();
run(arg0 );
}
public void run(Context arg0 ) {
Toast.makeText(arg0, "sss", Toast.LENGTH_SHORT).show();
}
}
It doesnt dislay any errors nor does it display the toast. How can i get the toast to display when the screen is turned on.
Have a look at this site: http://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/
First, unlike other broad casted intents, for Intent.ACTION_SCREEN_OFF and Intent.ACTION_SCREEN_ON you CANNOT declare them in your Android Manifest!
You could handle this by gaining the ReceiveBootComplete Permission, then starting a service with the onBootReceiver, which registers the Intent Filter. Sounds complicated, but there is also a good example on this site.
/edit: Ah, and I just saw that in the example it is done by onResume and onPause. It might be a way, but I wouldn't recommend it. See this question: Service and a BroadCastReceiver
It is explained there how to register a Receiver in your service.
This link covers how to start a service on boot: http://www.androidcompetencycenter.com/2009/06/start-service-at-boot/
Related
I am working on an android application that listens to Boot Complete Broadcast and performs some processes.
This broadcast works on my Moto G5 and simulator, however, on Oneplus the application never receives it.
Create a BroadCastReciver class like this :
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class RebootService extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"Service is running", Toast.LENGTH_LONG).show();
}
}
Define your service in AndroidManifest.
<receiver android:name=".RebootService">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
And finally :
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
i have some functionality in my program i want to expose but i did't seem to get the receiver working.
i tried the Manifest/Receiver:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.nohkumado.intstringsynchro" >
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:resizeableActivity = "true">
<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:name=".IntStringReceiver" android:exported="true" android:enabled="true">
<intent-filter>
<action android:name="com.nohkumado.intstringsynchro.EDIT_STRINGXML"/>
</intent-filter>
<intent-filter>
<action android:name="com.nohkumado.intstringsynchro.ADD_STRINGXML"/>
<action android:name="com.nohkumado.intstringsynchro.DEL_STRINGXML"/>
<data android:mimeType="text/plain"/>
</intent-filter>
</receiver>
</application>
</manifest>
package com.nohkumado.intstringsynchro;
import android.content.*;
import android.widget.*;
import android.util.*;
public class IntStringReceiver extends BroadcastReceiver
{
public static final String TAG = "Receiver";
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "Intent Detected:"+intent.getAction(), Toast.LENGTH_LONG).show();
switch (intent.getAction())
{
case "com.nohkumado.intstringsynchro.EDIT_STRINGXML":
{
Intent intentStartMainActivity = new Intent(context, MainActivity.class);
intentStartMainActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intentStartMainActivity);
break;
}
case("com.nohkumado.intstringsynchro.ADD_STRINGXML"):
{
Toast.makeText(context, "add token "+intent.getExtras(), Toast.LENGTH_LONG).show();
break;
}
case("com.nohkumado.intstringsynchro.DEL_STRINGXML"):
{
Toast.makeText(context, "del token "+intent.getExtras(), Toast.LENGTH_LONG).show();
break;
}
default:
{
Toast.makeText(context, "no idea what to do with "+intent, Toast.LENGTH_LONG).show();
Log.d(TAG,"no idea what to do with "+intent);
}//default
}// switch (intent.getAction())
}// public void onReceive(Context context, Intent intent)
}//class
as pointed out,i had, erroneously, in the receiver part put a
<category android:name="android.intent.category.DEFAULT"/>
which meant that in the best case only the first intent filter got fired, and not the others.... removed that
now as an other app, i created a small Tester, it has only 3 buttons to trigger the 3 actions i want to pass on as intents, since it was only a small test, i bound the onClick event in the layout file:
package com.nohkumado.istester;
import android.app.*;
import android.content.*;
import android.net.*;
import android.os.*;
import android.view.*;
import android.widget.*;
public class MainActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}//onCreate
public void callIntString()
{
callIntString(null);
}
public void callIntString(View but)
{
Toast.makeText(this, "call int string", Toast.LENGTH_SHORT).show();
String name="com.nohkumado.intstringsynchro.EDIT_STRINGXML";
Intent callIt = new Intent(name);
try
{
startActivity(callIt);
}
catch (ActivityNotFoundException e)
{
Toast.makeText(this, "no available activity"+callIt, Toast.LENGTH_SHORT).show();
//callGooglePlayStore();
}
}
private void callGooglePlayStore()
{
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.android.vending");
ComponentName comp = new ComponentName("com.android.vending", "com.google.android.finsky.activities.LaunchUrlHandlerActivity"); // package name and activity
launchIntent.setComponent(comp);
launchIntent.setData(Uri.parse("market://details?id=com.nohkumado.intstringsynchro"));
startActivity(launchIntent);
}//callIntString
}
and here was my understanding problem, instead of using startActivity, i should have tried sendBroadcast(launchIntent);
Ok, to close this up...
first, i was not completely aware, that the activity contract in the manifest, opens a way for anyone to call on this activity.
Next, i have a specific application, that i want to open up to others, meaning editing the strings.xml files of android projects, and i wanted to propose the equivalent of a REST API, with LIST/EDIT, ADD, DEL.
Now, if we work with activities, the easiest way to get a handle on my activity from outside is, i think, like this:
Intent call = pm.getLaunchIntentForPackage("com.nohkumado.intstringsynchro");
followed by some putExtra calls to insert a token identifying a specific action, and an eventual value to perform on....
finished by a startActivity
this way, the default activity is started, regardless of its name, and the intent passed on, that can be read in the onCreate method of the MainActivity.
To implement my REST API, i tryed to make 3 entry points to my app, one for each type of access, only the LIST/EDIT firing up a UI, the 2 others spawning a series of Asynctasks doing the work in background. But this meant, that an eventual user has to know wich activities to address.
So i reverted to using the putExtra of the intent with a token/value pair to implement my REST-like API.....
For educations sake i tryed out the way over the broadcast mechanism, the advantage beeing that on the client side there seems no risk of crash, no need to catch a ActivityNotFound Exception, and, from a typo in my code, i noticed that the intent activity doesn't need to be bound to my actual app, i can choose any name i want.
For this, on the client side i needed to :
String name="com.nohkumado.intstringsynchro.EDIT_STRINGXML";
Intent callIt = new Intent(name);
sendBroadcast(callIt);
but on my app side i need to implement a complete BroadCastreceiver....
On the other side, this mechanism was extremely slow, giving the whole operation a very sluggish feel
Please correct me if i got it right this time, and i am open to suggestions if there a better ways to achieve my goal to propose to others those LIST/EDIT, ADD and REMOVE functionalities?
the reports back an activity not found exception
Apparently, you do not have an activity with an <intent-filter> for an action string of com.nohkumado.intstringsynchro.EDIT_STRINGXML. Your manifest in the question certainly does not have such an activity. Your manifest in the question has a <receiver> element with an odd <intent-filter> that, among other things includes that action. However, <receiver> and <activity> are not the same thing.
Either change your code to send a broadcast, or change your code to have an activity with that action string.
I'm realy newbie in android, and i'm having dificult with broadcastreceiver in my project.
I've created uses-permission and the receiver in AndroidManifest.xml, created the class but it not passing on the logcat message.
MY RECEIVER CLASS
package com.polifrete.polifreteFunctions;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.i("Script", "Passou AQUI");
Intent i = new Intent(context, VerificaNovoFreteService.class);
context.startService(i);
}
}
MY ANDROIDMANIFEST.XML
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name="com.polifrete.polifreteFunctions.MyReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
What i'm doing wrong? Please, help me!
Not every Phone sends the BOOT_COMPLETED Broadcast. For example, I think it was HTC, sends the QUICKBOOT_POWERON Broadcast, if it has boot up. Also your logcat is maybe not connected to your phone at Boot-Up-Time. I'd suggest to create a Toast to check, wether your Boot-Reciever is executed.
You can create this Toast with this code:
Toast toast = Toast.makeText(getApplicationContext(), "Boot-Reciever Started", Toast.LENGT_LONG);
#Felipe A., it's possible that you have a problems with CPU...The oficial documentation talks about it, and says the best use is WakefulBroadcastReceiver guarantee a that CPU will stays awake, you can read this post that talk about it: https://stackoverflow.com/a/26380942/3996257
This is my code with WakefulBroadcastReceiver:
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntent_Service.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
The gcm receiver needs to add your package in your intent-filter it's the only difference with my code. And my receiver have this code:
<receiver
android:name=".App_Services.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />/>
<category android:name="your.package" />
</intent-filter>
</receiver>
It's possible your code don't recognizes your receiver because doesn't know their package. Tell me if I helps you, good luck!
I create an birthday reminder app. I want to start service at 12:00 in night to scan birthdays of person in Database. I add a broadcast receiver.
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.DATE_CHANGED"/>
</intent-filter>
</receiver>
But It don't work. I don't why..
here is the code of broadcast receiver .....
package com.example.forgetmenot;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent arg1) {
Toast.makeText(arg0, "BroadCast Receiver", Toast.LENGTH_SHORT).show();
arg0.startService(new Intent("com.example.forgetmenot.BirthdayService"));
}
}
I wanna execute this code when date change. Please Help me. I need this to work to complete my app. thanks...
create receiver in Manifest
<receiver android:name=".MyReceiver" >
<intent-filter>
<action android:name="android.intent.action.DATE_CHANGED" />
</intent-filter>
</receiver>
create BroadcastReceiver class
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_DATE_CHANGED)) {
Log.e("", "ACTION_DATE_CHANGED received");
}
}
}
100% working
I have implemented this broadcast reciever:
public class ServiceManager extends BroadcastReceiver {
private final String BOOT_ACTION = "android.intent.action.BOOT_COMPLETED";
private final String BOOT_ACTION_FIRST_LAUNCH = "android.intent.action.PACKAGE_FIRST_LAUNCH";
private final String BOOT_ACTION_RESTARTED = "android.intent.action.PACKAGE_RESTARTED";
#Override
public void onReceive(Context context, Intent intent) {
// All registered broadcasts are received by this
String action = intent.getAction();
if (action.equalsIgnoreCase(BOOT_ACTION) || action.equalsIgnoreCase(BOOT_ACTION_FIRST_LAUNCH) ||
action.equalsIgnoreCase(BOOT_ACTION_RESTARTED)) {
// TODO: Action
}
}
}
AndroidManifest.xml
<receiver android:name="package.service.ServiceManager" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.PACKAGE_FIRST_LAUNCH" />
<action android:name="android.intent.action.PACKAGE_RESTARTED" />
</intent-filter>
</receiver>
The BOOT_COMPLETED action is working right, but, the PACKAGE_FIRST_LAUNCH and PACKAGE_RESTARTED are not working. I need to launch my broadcast receiver when I launch my app, that's why I'm using these actions. But, when I launch or restart the app, the receiver is not working. It only works when I restart my mobile phone. Are there something wrong in my source?
FYI: PACKAGE_FIRST_LAUNCH is only sent to the installer package, i.e. whatever you used to install the application - for most end users that would be Android Market.
Edit:
Oh, and for "PACKAGE_RESTARTED", break that one out into its own <intent-filter> and add a
<data android:scheme="package"/>
since that one comes with an URI and an explicit scheme.
Logically it seems that PACKAGE_FIRST_LAUNCH will be broadcasted once your app is run for the first time after boot/reboot. And PACKAGE_RESTARTED should be broadcasted if your application activity stack is removed and then your app is clicked to start again (like restart).
However, you may simply achieve this by broadcasting a custom action string when ever your app is launched (perhaps from your first activity).
Manifest:
...
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></>
...
<receiver android:name=".AutoStart">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
...
Receiver:
package YourPackage;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class AutoStart extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
{
// Your code
}
}
}
The intent android.intent.action.PACKAGE_FIRST_LAUNCH is introduced in Android API Level 12. If you are using lesser API Level it will not work. So change your project settings accordingly.