I want to know when users installs a new app. I have used broadcast receiver.
<receiver android:name=".NewInstallReceiver">
<intent-filter>
<action android:name="android.intent.action.package_added" />
<data android:scheme="package" />
</intent-filter>
</receiver>
Code:
public class NewInstallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String act = intent.getAction();
Log.e("ee", "new install" + intent);
if (Intent.ACTION_PACKAGE_ADDED.equals(act) || Intent.ACTION_PACKAGE_REMOVED.equals(act)) {
/* ContentResolver contentResolver = context.getContentResolver();
contentResolver.query()*/
}
}
}
I see no logs when i install app from playstore.
Should I use service? If yes then how can i make it run for infinite times?
I guess there is typo in your intent filter, try below intent filter
<receiver android:name=".NewInstallReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_INSTALL"/>
<data android:scheme="package" />
</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
My app widget stops working after upgrading to targetSDk to 28.
It is flawlessly working on old targetsdk devices.
I am getting the following error:
W/BroadcastQueue: Background execution not allowed: receiving Intent { act=ch.corten.aha.worldclock.WIDGET_DATA_CHANGED flg=0x10 } to ch.corten.aha.worldclock/.WorldClockWidgetProvider
W/BroadcastQueue: Background execution not allowed: receiving Intent { act=ch.corten.aha.worldclock.WIDGET_DATA_CHANGED flg=0x10 } to ch.corten.aha.worldclock/.WeatherWidgetProvider
androidmanifest.xml file contents are given below-
<!-- clock widget -->
<receiver
android:name=".WorldClockWidgetProvider"
android:exported="false"
android:label="#string/clock_widget_name" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_DISABLED" />
</intent-filter>
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_ENABLED" />
</intent-filter>
<intent-filter>
<action android:name="ch.corten.aha.worldclock.WIDGET_DATA_CHANGED" />
</intent-filter>
<intent-filter>
<action android:name="ch.corten.aha.worldclock.CLOCK_TICK" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/world_clock_appwidget_info" />
</receiver>
<receiver
android:name=".WeatherWidgetProvider"
android:enabled="#bool/enable_weather_widget"
android:exported="false"
android:label="#string/weather_widget_name" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_DISABLED" />
</intent-filter>
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_ENABLED" />
</intent-filter>
<intent-filter>
<action android:name="ch.corten.aha.worldclock.WIDGET_DATA_CHANGED" />
</intent-filter>
<intent-filter>
<action android:name="ch.corten.aha.worldclock.CLOCK_TICK" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/weather_appwidget_info" />
</receiver>
And my reviever class code(
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (WIDGET_DATA_CHANGED_ACTION.equals(intent.getAction())
|| CLOCK_TICK_ACTION.equals(intent.getAction())) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (pm.isScreenOn()) {
onClockTick(context);
}
}
}
Where clock widget provider is extending AppWidgetProvider.
world clock activity
private static void sendWidgetRefresh(Context context) {
// send update broadcast to widget
Intent broadcast = new Intent(ClockWidgetProvider.WIDGET_DATA_CHANGED_ACTION);
context.sendBroadcast(broadcast);
}
project link for reference. Followed previous posts but did not worked.
Oreo - Widget services and broadcast receiver: Not allowed to start service Intent
The problem is in implicit broadcast that you're making in sendWidgetRefresh.
You can break through the ban by defining a component name in your intent.
private static void sendWidgetRefresh(Context context) {
// send update broadcast to widget
Intent broadcast = new Intent(ClockWidgetProvider.WIDGET_DATA_CHANGED_ACTION);
ComponentName componentName = new ComponentName(context, WorldClockWidgetProvider.class);
broadcast.setComponent(componentName);
context.sendBroadcast(broadcast);
}
This worked for me!
Change your implicit intent to explicit intent, because starting Oreo implicit intents don't run in background!
https://developer.android.com/about/versions/oreo/background.html
I have a several devices (Minix X68-i) all running the same firmware and software versions.
On some of them my boot receiver works fine, others it rarely works, and a few it's closer to 50-50 whether they will receive the event.
I'm out of ideas as to what could cause the code to work so erratically, other than potentially faulty hardware.
Manifest:
<receiver android:enabled="true" android:exported="true"
android:name="com.proreception.displaymanagement.Receiver.BootReceiver"
android:label="StartMyActivity" >
<intent-filter android:priority="500" >
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
BootReceiver
public class BootReceiver extends BroadcastReceiver {
private static final String TAG = "BootReceiver";
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction()) && constants.ONBOOT) {
Intent i = new Intent(context, FullscreenActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Log.d(TAG, "Starting Application");
context.startActivity(i);
}
}
}
I use this code to send data to my BroadcastReceiver.
Log.d("recive message message message", message);
Intent resultBroadCastIntent = new Intent();
resultBroadCastIntent.setAction(Intent.ACTION_SEND);
resultBroadCastIntent.addCategory(Intent.CATEGORY_DEFAULT);
resultBroadCastIntent.putExtra(OUTPUT_TEXT, message);
sendBroadcast(resultBroadCastIntent);
and the BroadcastReceiver code
public class Broadcast_Receiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, Notification_Intent_Service.class));
String resultText =intent.getStringExtra(Notification_Intent_Service.OUTPUT_TEXT);
Log.d("recive dwwwwwwwwwwwwwwww", resultText);
// this never run when message arrive
}
}
and this is my manifest
<receiver
android:name=".Service.Broadcast_Receiver"
android:enabled="true"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
now in
Log.d("recive message message message", message);
the message is printed and I see it but it wasn't sent to the BroadcastReceiver or is it that the BroadcastReceiver didn't receive the data? I'm not sure where the problem is.
You can use the BOOT_COMPLETED id when sending a broadcast
Intent resultBroadCastIntent = new Intent("android.intent.action.BOOT_COMPLETED");
resultBroadCastIntent.putExtra(OUTPUT_TEXT, message);
sendBroadcast(resultBroadCastIntent);
or Specify SEND action in <intent-filter>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.SEND" />
</intent-filter>
Note: Make sure your BroadcastReceiver isn't an Inner class otherwise add static into it or move it in upper level.
You need to register Intent.ACTION_SEND for Broadcast receiver in manifest
<receiver
android:name=".Service.Broadcast_Receiver"
android:enabled="true"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.SEND" />
</intent-filter>
</receiver>
I'm trying to get all SD card statuses using the BroadcastReceiver, but the code isn't working correctly. The BroadcastReceiver does not give a comprehensive log after a change in SD card status, such as Turn on(off) USB Storage. Any ideas?
Manifest receiver actions:
<receiver android:name=".Broadcasts.BroadcastChangeSDCardStatus">
<intent-filter>
<action android:name="android.intent.action.MEDIA_REMOVED"/>
<action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
<action android:name="android.intent.action.MEDIA_EJECT"/>
<action android:name="android.intent.action.MEDIA_MOUNTED"/>
</intent-filter>
</receiver>
OR this receiver defined:
<receiver android:name=".Broadcasts.BroadcastChangeSDCardStatus">
<intent-filter>
<action android:name="android.intent.action.ACTION_MEDIA_BAD_REMOVAL"/>
<action android:name="android.intent.action.ACTION_MEDIA_EJECT"/>
<action android:name="android.intent.action.ACTION_MEDIA_REMOVED"/>
<action android:name="android.intent.action.ACTION_MEDIA_UNMOUNTED"/>
</intent-filter>
</receiver>
BroadcastReceiver class to detect
public class BroadcastChangeSDCardStatus extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
boolean status = getStorageStatus();
Log.e("SDCARD Status: ", status + "");
}
public static boolean getStorageStatus() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return false;
} else {
return false;
}
}
}
<receiver android:name=".Broadcasts.BroadcastChangeSDCardStatus" >
<intent-filter>
<action android:name="android.intent.action.MEDIA_REMOVED" />
<action android:name="android.intent.action.MEDIA_MOUNTED" />
</intent-filter>
Above code should work but as you said you already tried this so it looks like something is wrong with your receiver name .Your broadcast receivers is not registered.Give receiver name complete package name with class name correctly
You also need to set the android:scheme to "file" :
Do this by adding <data android:scheme="file" /> to your receiver like:
<receiver android:name=".Broadcasts.BroadcastChangeSDCardStatus">
<intent-filter>
<action android:name="android.intent.action.MEDIA_REMOVED"/>
<action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
<action android:name="android.intent.action.MEDIA_EJECT"/>
<action android:name="android.intent.action.MEDIA_MOUNTED"/>
<data android:scheme="file" />
</intent-filter>
</receiver>
Hope this helps you out
i'm after adding this permission resolve my problem now:
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />