Is it possible to directly send a broadcast intent from a PreferenceScreen?
For example, I would like to do something like the following:
<PreferenceScreen android:title="Enable">
<intent android:action="com.otherapp.ENABLE" />
</PreferenceScreen>
But when I try this, the app FC's w/ ActivityNotFoundException.
BTW, the receiver is simply defined as:
<receiver android:name=".Receiver">
<intent-filter>
<action android:name="com.otherapp.ENABLE" />
</intent-filter>
</receiver>
This broadcast receiver has been tested to work ok, but just not from the PreferenceScreen.
TIA!
You can extend Preference to make it send a broadcast when clicked:
public class BroadcastPreference extends Preference implements Preference.OnPreferenceClickListener {
public BroadcastPreference(Context context, AttributeSet attrs) {
super(context, attrs);
this.setOnPreferenceClickListener(this);
}
#Override
public boolean onPreferenceClick(Preference preference) {
getContext().sendBroadcast(getIntent());
return true;
}
}
Then use your custom preference in the xml file
<com.app.example.BroadcastPreference android:title="Enable">
<intent android:action="com.otherapp.ENABLE" />
</com.app.example.BroadcastPreference>
Preferences send intents to activities, not to broadcast receivers. If you want to send intents to broadcast receivers, create activity that forwards intents to broadcast receivers
public class ForwardingActivity extends Activity {
#Override
protected void onStart() {
super.onStart();
Intent incomingIntent = getIntent();
Intent outgoingIntent = new Intent(incomingIntent);
outgoingIntent.setComponent(null); // unblock recipients
sendBroadcast(outgoingIntent);
}
}
with no UI
<activity
android:name=".ForwardingActivity "
android:theme="#android:style/Theme.NoDisplay" >
<intent-filter>
<action android:name="com.otherapp.ENABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
I think, you should add category android.intent.category.DEFAULT to intent-filter in your manifest.
It should look like this:
<receiver android:name=".Receiver">
<intent-filter>
<action android:name="com.otherapp.ENABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Related
I found many topic but no case fit for my question.
The first my app working smooth, it is always startup with device by code bellow:
In AndroidManifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
and receiver:
<!-- start when module start broadcast -->
<receiver android:name=".StartOnBoot"
android:exported="true">
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<!-- listen messenger received -->
<receiver
android:name=".Phone.SmsListener"
android:exported="true">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
And class StartOnBoot
public class StartOnBoot extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
Intent serviceIntent = new Intent(context, MainActivity.class);
serviceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(serviceIntent);
}
} }
And now I added 2 broadcast to listen state of SD card and SIM card. But when I finish, My app can not start when my device restarted. And I don't know, where is problem, nothing clue.
<!-- broad cast SDCard receive-->
<receiver android:name=".Peripheral.SDCardListener">
<intent-filter>
<action android:name="android.intent.action.MEDIA_EJECT" />
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<data android:scheme="file" />
</intent-filter>
</receiver>
<receiver android:name=".Phone.SimCardReceiver">
<intent-filter>
<action android:name="android.intent.action.SIM_STATE_CHANGED"/>
</intent-filter>
</receiver>
And 2 classes receiver:
public class SDCardListener extends BroadcastReceiver {
//restart app when SD card mounted
#Override
public void onReceive(Context context, Intent intent) {
Log.d("TAG","SDcard state : " + intent.getAction());
if (intent.getAction().equals(Intent.ACTION_MEDIA_EJECT)){
//sdcard eject
}else if (intent.getAction().equals(Intent.ACTION_MEDIA_MOUNTED)){
SDCard.getInstance().SDCardMounted();
}
}
}
for sim state:
public class SimCardReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("TAG", "Sim state :" + intent.getAction());
}
}
My device target is only Android 7.1, SDK lv 25.
Some methods I tried but not work:
I removed SimCardReceiver
I added "android:priortity to StartBoot" like this:
<intent-filter android:priority="1000">
But still not working, Remember, my app always work without 2 broadcast SDCardListener and SimCardReceiver
Extra question:
How many broadcast are available to use in one app. How many is good ? one or not limit
Could I merge all receiver to one broadcast
I would like to received a notification of the change of state of WiFi connection in my Android application.
I found several suggestion (here on SO) that mostly leads to the definition of an intent.
I'm using this approach:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_controller);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
registerReceiver(broadcastReceiver, intentFilter);
checkWiFi();
}
public BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null)
checkWiFi();
}
};
That works but I'm wondering if I can use a Manifest centric approach i.e. if I put this in my AndroidManifest.xml:
<activity
android:name=".MainActivity"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.net.wifi.STATE_CHANGE" />
</intent-filter>
</activity>
I should be notified of the incoming intent . Right?
How can I handle this in my Activity?
Best regards, Mike
You should create class
MyBroadcastReceiver extends BroadcastReceiver
and next Manifest
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="android.net.wifi.STATE_CHANGE" />
</intent-filter>
</receiver>
I have a customer that needs a custom launcher to make his devices like a kiosk, just because he needs the device have limited access to limited applications. Everything is ok so far.
One of the most important feature he wants is the possibility to increase/decrease the applications that can be launch in his devices. I wrote the GCM receiver and it's also ok.
My problem is: I want to send a custom broadcast from the GCM service to my main activity (the home activity). I think the code is OK, but the broadcast is never received in main activity. Any ideas?
My manifest:
<activity
android:name="jv.android.atmlauncher.activity.HomeScreen"
android:excludeFromRecents="true"
android:label="#string/app_name"
android:launchMode="singleTask"
android:screenOrientation="nosensor" >
<intent-filter>
<action android:name="jv.antroid.atmlauncher.apklistchanged" /> <!-- This is my custom broadcast -->
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
My Service:
#Override
public void onHandleIntent(Intent intent) {
...
Intent intent = new Intent("jv.antroid.atmlauncher.apklistchanged");
sendBroadcast(intent);
}
My home activity:
private BroadcastReceiver listapkReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.homescreen);
registerReceiver(listapkReceiver, new IntentFilter("jv.antroid.atmlauncher.apklistchanged"));
listapkReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
... Do something.
}
};
}
#Override
protected void onDestroy() {
unregisterReceiver(listpkReceiver);
super.onDestroy();
}
In my android application I am starting the activity using broadcast receiver. If my device lock during this activity and if I unlock it then activity restart mean it run on create again
Please help me to solve this problem
Thanks in advance
What's your activity declaration in AndroidManifest.xml?
I think u should appoint launchMode to "singleTask" like that:
<activity android:name=".Youracticity" android:launchMode="singleTask" android:configChanges="orientation|keyboardHidden" android:screenOrientation="portrait">
</activity>
^-^
In your Manifest do you have anything like this:
<action android:name="android.intent.action.USER_PRESENT" />
<receiver android:name="com.activities.app" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
If yes, then please handle it properly.
for detect screen on and screen off register a broadcast reciver like:
<receiver android:name="receiverScreen">
<intent-filter>
<action android:name="android.intent.action.SCREEN_ON" />
<action android:name="android.intent.action.SCREEN_OFF" />
<action android:name="android.Intent.ACTION_USER_PRESENT" />
</intent-filter>
</receiver>
In Activity or Service:
try {
IntentFilter if= new IntentFilter(Intent.ACTION_SCREEN_ON);
if.addAction(Intent.ACTION_SCREEN_OFF);
if.addAction(Intent.ACTION_USER_PRESENT);
BroadcastReceiver mReceiver = new receiverScreen();
registerReceiver(mReceiver, if);
} catch (Exception e) {
}
receiver code where System inform you if Screen on/off happen:
public class receiverScreen extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)){
}
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){
}
if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)){
}
}
}
I try to get a broadcast receiver working. Should be as simple as possible, I have my manifest like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mytest.intentRec" android:versionCode="1"
android:versionName="1.0">
<application android:icon="#drawable/icon" android:label="#string/app_name"
android:debuggable="true">
<activity android:name=".mainAct" 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.mytest.intentRec.MyIntentRec"
android:enabled="true" >
</receiver>
</application>
<uses-sdk android:minSdkVersion="7" />
</manifest>
As you can see I have a main activity mainAct, this does nothing but sending the broadcast once started:
public class mainAct extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.sendBroadcast(new Intent());
}
}
and I have a class MyIntentRec, which is as simple as it could:
public class MyIntentRec extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.v("IntentRec", "got it");
}
}
What I expect is that when I start my app that a broadcast is sent and being picked up and that a log entry is written. I don't see that log entry and I don't see any error. I'm suspecting to have either an error in the manifest or in sending the broadcast. I just created an empty intent there, does it need to be some intent with certain properties?
Please setClass for your Intent,
EX:
public class mainAct extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent i=new Intent("any string");
i.setClass(this, MyIntentRec.class);
this.sendBroadcast(i);
}
}
That is what it means " The absence of any filters means that it can be invoked only by Intent objects that specify its exact class name."
[Old answer]
You should register what kind of actions you need in the manifest.
Ex:
<receiver android:name="com.mytest.intentRec.MyIntentRec" android:enabled="true" >
<intent-filter>
<action android:name="your.intent" />
</intent-filter>
</receiver>
send it,
this.sendBroadcast(new Intent("your.intent"));
it is insufficient to make just new Intent();. You have to specify it with some action. Also, you have to specify in your manifest the intent filter for this particular action. Please read more here and here.
You didn't define any Intent Filters in the manifest for your BroadcastReceiver. Specify one for a custom Action type. You also have to define this custom Action type in the Intent you brodcast upon startup.
Try specifying what actions your receiver should catch in the manifest. You can do this as such:
<receiver android:name="com.mytest.intentRec.MyIntentRec">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>