Xamarin android app crashes on boot with BroadcastReceiver but starts? - android

I am trying to start an app build in Xamarin that runs normally when pushed to the emulator running android 7.1 (API 25). However when I want to start a service from the app on boot the app crashes but then still seems to be running and working? Since I have no way of debugging an emulator on reboot I am clueless as to where this is going wrong.
I have the following broadcastreceiver:
[BroadcastReceiver]
[IntentFilter(new[] { Intent.ActionBootCompleted })]
public class BootBroadcastReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action.Equals(Intent.ActionBootCompleted))
{
Toast.MakeText(context, "Action Boot Completed!", ToastLength.Long).Show();
Intent i = new Intent(context, typeof(BackGroundService));
context.StartService(i);
}
}
}
With the following permissions:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:label="One.Android" android:icon="#drawable/baseball">
<receiver android:enabled="true"
android:exported="true"
android-permission="android.permission.RECEIVE_BOOT_COMPLETED"
android:name=".BootBroadcastReceiver" >
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>
And the following service:
[Service]
public class BackGroundService : Service
{
private Timer _checkServiceTimer;
private Notifications notifi = new Notifications();
public override IBinder OnBind(Intent intent)
{
throw new NotImplementedException();
}
public void MyDebugServiceTester()
{
int i = 0;
_checkServiceTimer = new Timer((o) => {
i++;
notifi.SendLocalNotification("BackGround Booted", "notification number: " + i.ToString(), 0);
//Log.Debug("Refreshing background service", "ammount of times: " + i.ToString());
}, null, 0, 30000);
}
[return: GeneratedEnum]
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
Log.Debug("BackGroundReceiver", "Started Succesfully");
MyDebugServiceTester();
//return base.OnStartCommand(intent, flags, startId);
return StartCommandResult.NotSticky;
}
public override bool StopService(Intent name)
{
Log.Debug("BackGroundReceiver", "Stopped Succesfully");
return base.StopService(name);
}
Does anyone know why it crashes and then runs anyway? any tips or solutions are appreciated.

You can run adb logcat from the command line after the emulator has started. Android will cache errors for a little while, so any crash report and stack trace is still there.
Investigating this output could point you to the root cause.
An easy way to store the logcat log to a file is this command adb logcat -d > logcat.txt
EDIT:
There is also another thing you can try. While your debugger is attached.
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED com.example.app
Change 'com.example.app' to your application name. This will will send the BOOT_COMPLETE message to your broadcast receivers.

Related

My app does not listen ACTION_MY_PACKAGE_REPLACED

I noticed when App is updated, Intents all disappear, so I need this app to listen to App update and re-send the intents, like it does with BOOT_COMPLETE
AndroidManifest.xml
<receiver android:name=".AlarmReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
</intent-filter>
</receiver>
AlarmReceiver.java
public class AlarmReceiver extends BroadcastReceiver{
private AlarmManager alarmManager;
private AlarmDB pAlarms;
#Override
public void onReceive(Context context, Intent intent) {
int reqCode = intent.getIntExtra("requestCode", 0);
System.out.println("Received code:" + reqCode);
alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
pAlarms= new AlarmDB();
pLoadAlarms(context);
System.out.println("Received Signal:" + intent.getAction());
if(Intent.ACTION_MY_PACKAGE_REPLACED.equals(intent.getAction())){
System.out.println("Replaceing Packing");
for(int i=0;i<pAlarms.getSize();i++){
if(pAlarms.get(i).enabled){
setAlarm(context,pAlarms.get(i));}
}
}
}
...
}
And I tested ACTION with adb shell
C:\Users\-----\AppData\Local\Android\sdk\platform-tools>adb shell am broadcast -a ACTION_MY_PACKAGE_REPLACED
Broadcasting: Intent { act=ACTION_MY_PACKAGE_REPLACED }
Broadcast completed: result=0
But on Logcat it does not print anything in the code, so I assume no signal was even received.
Still, if I change versionCode at gradle and update app through android studio, all the Broadcast signals disappear and MY_PACKAGE_REPLACED is not called/received.

Creating a daemon like service for android application

I want to implement this scenario for my application. I want to schedule my service to start when the phone boots, and whenever another application calls my service I want my service to start a certain activity within the project.
So in order to be clear. I want to create a project which contains a service which runs whenever the phone boots, and is dormant, listening for a call from a third party application. And whenever that call is received this service calls an Activity (from the same project, not third party)
How can I configure my manifest file in order to achieve this?
I have also come across this suggestion but my scenario is pretty different.
Thank you very much in advance
**Define Service in manifest and Create the BroadcastReciever with boot complete permission and listen the intent.If boot completed start the service.**
public class MyService extends Service {
Context context = this;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
Intent activity = new Intent(context, MyActivity.class);
activity.putExtra("Message", "fromService");
activity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(activity );
} catch (Exception e) {
MyLog.printException(e);
}
return super.onStartCommand(intent, flags, startId);
}
}
By creating a BroadcastReceiver you can perform the service startup.
public class StartupReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Intent i = new Intent(context, ShowActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
}
and in the manifest
<receiver
android:name=".StartupReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<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>
This allows you to run an Activity, you can then start a Foreground Service from that activity. I just set this example because I have it ready, you can adapt it to run a service as you like.

why i can't start my service when the android startup ? ( code attached )

I trying to write simple basic application that will start my service when the phone is start.
i add all the permission i need.
I install the application on my android ( android 6.01 ).
And when i reboot my phone - i can't see that the service is up or did any action.
why this is not working ?
how can i debug a service on android ?
The code:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAG" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.NoActionBar">
<service android:name=".MyService" android:enabled="true" android:exported="true"/>
<receiver android:name=".MainBroadcastReceiver" android:enabled="true" android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
</application>
public class MainBroadcastReceiver extends BroadcastReceiver {
public MainBroadcastReceiver(){
}
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, MyService.class));
}
}
public class MyService extends Service {
private File _file;
private Timer _timer;
private FileOutputStream _fileOutputStream;
public MyService() throws IOException {
_file = new File("/sdcard/" + "myServiceText.txt");
_file.createNewFile();
_fileOutputStream = openFileOutput(_file.getName(), Context.MODE_APPEND);
_fileOutputStream.write("Ctor called".getBytes());
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
_timer = new Timer("timer");
_timer.schedule(new TimerTask()
{
#Override
public void run()
{
try {
_fileOutputStream.write("onCreate Called".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}, 0, 5000);
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
_fileOutputStream.write("onStartCommand".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
return START_STICKY;
}
Your code is fine, the reason your service is not running it's because your app is in Stopped State.
1. Stopped state is a security procedure that allows your app to "wake itself up" only after user first manually launches it from the home screen.(Unless you are a system)
By doing so android prevents malicious apps to be installed and run in your phone background without you knowing.
2. How to debug a background process?
When working with background processes there are two great tools you need in your belt -
First is the adb broadcast command -
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED
Second is attach remote debugger (Android Studio):
Run | Attach debugger to android process (last option in the menu) | choose your app's process.

how to use broadcast receiver on receive

i have a project and when i run the application,one service should be active and when the device is turned on,my android service should be active.
The project runs in emulator successfully but in my phone when i turn on the device it doesn't works!
my broadcast receiver :
public class BroadcastReceiverOnTurnedOn extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, MyService.class);
context.startService(startServiceIntent);
}
}
i added :
<receiver android:name="com.dariran.BroadcastReceiverOnTurnedOn">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
to appliation tag on Manifest.xml and
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
You are registering a BroadcastReceiver not a Service. Services will generally run in the background all of the time (if memory and resources permit).
Your broadcast receiver activates only when the device is rebooted - and your emulator "boots" every time you start it up. Your phone does not "boot" when the app is installed.
You should either register for events like "app installed" or else actually implement a service, like here:
http://www.vogella.com/tutorials/AndroidServices/article.html
You need to make sure that once you install the app on device it should be started once by clicking app icon then only boot receiver will receive boot event on subsequent reboots calls.
i undrestand that if i install app in internal storage in works successfully even device rebooted but when i install the app on external storage and then reboot device it not work
i have a project that when run application one service be active and when device be turn on my android service be active. the project run in device's internal memory successfully but when i install it on external memory and reboot my device again don't work!
for first i call my service in first acitivity and it works, but when i reboot my device it doesn't work !
my activity :
public class FirstClass extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.first);
final Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
public void run()
{
startService(new Intent(getApplicationContext(), MyService.class));
startActivity(new Intent(FirstClass.this, MainActivity.class));
finish();
}
},5000);
}
/////////////////////////////////////////////////
}
my broadcast receiver :
public class BroadcastReceiverOnTurnedOn extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, MyService.class);
context.startService(startServiceIntent);
}
}
i added :
<service
android:name="com.dariran.MyService"
android:enabled="true"
android:exported="true" >
</service>
<receiver android:name="com.dariran.BroadcastReceiverOnTurnedOn"
android:enabled="true">
<intent-filter android:priority="1">
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE" />
</intent-filter>
</receiver>to appliation tag on Manifest.xml and
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
i added this code to my service class to put a filter to recognize the external storage but don't work again :(
#Override
public void onStart(Intent intent, int startId) {
try {
IntentFilter filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
BroadcastReceiver mReceiver = new BroadcastReceiverOnTurnedOn();
registerReceiver(mReceiver, filter);
} catch (Exception e) {
}
}

Can i start an android service without activity or GUI?

My target Android is 4.1.2. I created an simple android service which will show Toast on boot. But this application should not have any GUI. I was success running this service only from an activity which show GUI on start.
public class MyServices extends Service {
private MediaRecorder recorder = null;
#Override
public IBinder onBind(Intent intent) {
return null;
}
public int onStartCommand(Intent intent, int flags, int StartId)
{
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
}
}
You can start this service from RebootReceiver but As of Android 3.0 the user needs to have started the application at least once before your application can receive android.intent.action.BOOT_COMPLETED events.
Reboot Receiver -> Android BroadcastReceiver on startup - keep running when Activity is in Background
First you have to create a receiver:
public class BootCompletedReceiver extends BroadcastReceiver {
final static String TAG = "BootCompletedReceiver";
#Override
public void onReceive(Context context, Intent arg1) {
Log.w(TAG, "starting service...");
context.startService(new Intent(context, MyServices.class));
}
}
Then add permission to your AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
and register intent receiver:
<receiver android:name=".BootCompletedReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
After this is done, your application (Application class) will run along with services, but no Activities, don't put your application on SD card (APP2SD or something like that), because it has to reside in the main memory to be available right after the boot is completed.

Categories

Resources