My service don't start on system boot, only when the user press the refresh button. I've tried everythng searched in stack but nothing i've rewrited my code 4 times and nothing, i want my service run in a time interval and when the refresh button is pressed, i canĀ“t understand why is not running on boot, Have i missed something?
Manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.moody"
android:installLocation="internalOnly"
android:versionCode="0"
android:versionName="0.6.7.2 alpha" >
<permission
android:name="com.android.moody.permission.GET_SERVER_DATA"
android:protectionLevel="normal" />
<uses-sdk
android:maxSdkVersion="18"
android:minSdkVersion="14"
android:targetSdkVersion="17" />
<uses-permission android:name="com.android.moody.permission.GET_SERVER_DATA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:allowClearUserData="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="activities.MainActivity"
android:label="#string/app_name" >
</activity>
<activity
android:name="activities.Menu_esq"
android:label="#string/title_activity_menu_esq" >
</activity>
<activity
android:name="activities.BaseActivity"
android:label="#string/title_activity_base" >
</activity>
<activity
android:name="activities.MainView"
android:label="#string/title_activity_main_view" >
</activity>
<activity
android:name="activities.LoginActivity"
android:label="#string/app_name"
android:noHistory="true"
android:windowSoftInputMode="adjustResize|stateVisible" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.moody.LeftActivity"
android:label="#string/title_activity_left" >
</activity>
<activity
android:name="com.example.moody.RightActivity"
android:label="#string/title_activity_right" >
</activity>
<activity
android:name="activities.UserDetailsActivity"
android:label="#string/title_activity_user_details" >
</activity>
<activity
android:name="fragments.FragTopicsPreview"
android:label="#string/title_activity_copy_of_topics_preview" >
</activity>
<activity android:name="activities.LoadingActivity" >
</activity>
<service
android:name="service.ServiceBackground"
android:enabled="true"
android:icon="#drawable/ic_launcher"
android:label="#string/moody_service" >
</service>
<receiver android:name="service.Alarm" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver
android:name="service.StartServiceReceiver"
android:permission="com.android.moody.permission.GET_SERVER_DATA" >
<intent-filter>
<action android:name="moody_get_data" />
</intent-filter>
</receiver>
</application>
ServiceBackground
public class ServiceBackground extends Service {
Alarm alarm = new Alarm();
public ServiceBackground() {
// TODO Auto-generated constructor stub
}
private boolean isRunning = false;
Object getContent;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
// android.os.Debug.waitForDebugger();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
// Starts the alarm
alarm.setAlarm(getApplicationContext());
// Announcement about starting
Log.d("service", "Service Started");
// Start a Background thread
isRunning = true;
Thread backgroundThread = new Thread(new BackgroundThread());
backgroundThread.start();
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
// Stop the Background thread
isRunning = false;
}
private class BackgroundThread implements Runnable {
public void run() {
try {
while (isRunning) {
Log.d("service", "Thread started");
new ManContents().getAll(getResources(),
getApplicationContext());
isRunning = false;
}
stopSelf();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Alarm
public class Alarm extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, ServiceBackground.class));
}
public void setAlarm(Context context) {
String alarm = Context.ALARM_SERVICE;
AlarmManager am = (AlarmManager) context.getSystemService(alarm);
Intent intent = new Intent("moody_get_data");
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
int type = AlarmManager.ELAPSED_REALTIME_WAKEUP;
// long interval = AlarmManager.INTERVAL_FIFTEEN_MINUTES;
long interval = 1000 * 60 * 2;
long triggerTime = SystemClock.elapsedRealtime() + interval;
am.setRepeating(type, triggerTime, interval, pi);
}
public void CancelAlarm(Context context) {
Intent intent = new Intent(context, Alarm.class);
PendingIntent sender = PendingIntent
.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
}
StartServiceReceiver
public class StartServiceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("service", "Starting service from serviceReceiver");
Intent service = new Intent(context, ServiceBackground.class);
context.startService(service);
}
}
NOTES:
i already tried starting the service directly without filters, but
for no reason don't start, so with filters was the only way that
worked.
I also tried without the StartServiceReceiver.java, with the intent inside the alarm but no luck, i can change the code again if somebody thinks that its the problem.
I've the while(isRunning) in the thread only for future purpose, but i think the problem it's not because this.
Compared with one of my implementations, there're small differences in the manifest:
used permissions (seems to be equal with yours
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
The Receiver
<receiver
android:name="com.<!your activity!>"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Yoiu see that there's an additional entry about the permission.
Related
I'm currently working on a simple android app. The idea is, it changes the wallpaper automatically after 12 A.M or when the date is changed. It's working on android Oreo and lower versions, however, it doesn't work on android 9(Pie). However, if I change the date manually from the setting of the phone, it calls the broadcast. I have googled a lot, and some suggested to register the broadcast on your java codes instead of Manifest. Unfortunately, it didn't work.
I have tested this question in Stackoverflow.
First of all, changing the date is not part of implicit broadcasts, secondly, I assumed it is. then I changed the codes but it didn't work.
Now I'm gonna provide some codes of my broadcast:
DailyBroadcastReceiverService
public class DailyBroadcastReceiverService extends Service {
private BroadcastReceiver dailyZekrBr;
private Context context;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
registerDailyZekrReceiver();
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(dailyZekrBr);
dailyZekrBr = null;
}
private void registerDailyZekrReceiver() {
context= this.getApplicationContext();
Log.d("Register", "onStart: Now gonna register the broadcast receiver on Daily Boadcast receiver");
dailyZekrBr = new DailyZekrBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addCategory(Intent.CATEGORY_DEFAULT);
filter.addAction("android.intent.action.ACTION_TIME_CHANGED");
filter.addAction("android.intent.action.TIME_SET");
filter.addAction("android.intent.action.DATE_CHANGED");
filter.addAction("android.intent.action.TIMEZONE_CHANGED");
this.registerReceiver(dailyZekrBr, filter);
}
}
DailyZekrBroadcastReceiver
public class DailyZekrBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("DailyZekrBroadcast", "onReceive:The broadcast is called ");
DailyZekrHandler.setTodayImage(context);
}
}
setTodayImage
public static void setTodayImage(Context context) {
int todayImage = DailyZekrHandler.nameOfTheWeek();
DisplayMetrics metrics = new DisplayMetrics();
WindowManager window = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
window.getDefaultDisplay().getMetrics(metrics);
Log.d("DailyZekrBroadCast", "trying to change imge: " + todayImage);
if(todayImage != DailyZekrHandler.getTodayImage(context)) {
DailyZekrHandler.storeTodayImage(context);
Bitmap tempbitMap = BitmapFactory.decodeResource(context.getResources(), todayImage);
Bitmap bitmap = Bitmap.createScaledBitmap(tempbitMap, metrics.widthPixels, metrics.heightPixels, true);
WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
wallpaperManager.setWallpaperOffsetSteps(1, 1);
wallpaperManager.suggestDesiredDimensions(metrics.widthPixels, metrics.heightPixels);
try {
wallpaperManager.setBitmap(bitmap);
Log.d("DailyZekrBroadCast", "today_image: " + todayImage);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ellia.dailyzekr">
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-9778979220370457~9773548477"/>
<receiver android:name=".core.DailyZekrBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_TIME_CHANGED"/>
<action android:name="android.intent.action.TIME_SET"/>
<action android:name="android.intent.action.DATE_CHANGED"/>
<action android:name="android.intent.action.TIMEZONE_CHANGED" />
</intent-filter>
</receiver>
<service android:name=".core.DailyBroadcastReceiverService"/>
<activity android:name=".SplashActivity" android:theme="#style/Theme.AppCompat.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
</activity>
</application>
</manifest>
I am new to android and I am trying to learn by doing some basics projects. The current app I am working on requires me to use BroadcastReceiver, but I need it to run when the phone starts and when the app closes.
I need it to receive all the incoming SMS, even when the app is not running.
Currently I have a startForeground which uses a notification to run. Is there a way to make the app run without the notification?
Please help. Here is my code:
public class IncomingSMS extends Service {
// Get the object of SmsManager
final SmsManager sms = SmsManager.getDefault();
//get audioManager
AudioManager aud;
public void onCreate(){
Log.i("MyActivity", "aaa");
IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
filter.addAction(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED);
registerReceiver(receiver, filter);
registerReceiver(receiver, filter);
Notification notification= new Notification();
startForeground(1, notification);
}
public void onDestroy(){
unregisterReceiver(receiver);
Log.i("MyActivity", "Destroyed");
}
public int onStartCommand(Intent intent, int flags, int startId){
return START_STICKY;
}
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Retrieves a map of extended data from the intent.
Log.i("MyActivity", "aaa");
final Bundle bundle = intent.getExtras();
aud = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
try {
if (bundle != null) {
Log.i("MyActivity", "Bundle");
final Object[] pdusObj = (Object[]) bundle.get("pdus");
for (int i = 0; i < pdusObj.length; i++) {
SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
String message = currentMessage.getDisplayMessageBody();
Log.i("MyActivity", message);
//Some Code
} // end for loop
} // bundle is null
}catch (Exception e) {
Log.e("SmsReceiver", "Exception smsReceiver" + e);
Log.i("MyActivity", "bbb");
}
}
};
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
And AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="pi.sum.nesbtesh.SARA" >
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="......"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="......">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</service>
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="#android:style/Theme.Translucent" />
</application>
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.SEND_SMS"></uses-permission>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
</manifest>
What you want is a BroadcastRceiever to run on phone startup, here you go. Basically you start your service in its callback.
For when the app closes, I wouldn't say that's quite possible because most of the times when you close an app, it just stats in Stopped but isn't destroyed. So I'd suggest you create a BaseActivity which is an Activity subclass that override onStop() or onPause() and start your service in this method.
Then every other Activity in your app are subclass of BaseActivity
I am getting action of buttons by getaction on receive() method which is a method of broadcast receiver but its sho a null plz tell me what I do in this to get a value which is not null
+my notify method is following
private void Notify(String notificationTitle, String notificationMessage)
{
String ns=Context.NOTIFICATION_SERVICE;
NotificationManager notificationManager=(NotificationManager)getSystemService(ns);
#SuppressWarnings("deprecation")
Notification notification=new Notification(R.drawable.bg,"Time",System.currentTimeMillis());
RemoteViews notificationView=new RemoteViews(getPackageName(),R.layout.main);
Intent notificationIntent=new Intent(this,PlayerAudioActivity.class);
PendingIntent pendingNotificationIntent=PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.contentView=notificationView;
notification.flags|=Notification.FLAG_NO_CLEAR;
//supposed button call intent
Intent switchIntent=new Intent(this,MyReceiver.class);
PendingIntent pendingIntent=PendingIntent.getBroadcast(this, 0, switchIntent, 0);
notificationView.setOnClickPendingIntent(R.id.btnPrevious, pendingIntent);
notificationManager.notify(1, notification);
}
-my broadcastreceiver class is following
public class MyReceiver
extends BroadcastReceiver {
private static final String TAG = "waaaawoooooooooOOOOOOjnjkhdfku";
public void onReceive(Context context, Intent intent) {
final String action=intent.getAction();
// if(AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)){
Log.d(TAG, ""+action);
// Bundle extras=intent.getExtras();
// String ieString=extras.getString("Locale");
// try{
// final int Appwidgid=extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,AppWidgetManager.INVALID_APPWIDGET_ID);
// if(Appwidgid!=AppWidgetManager.INVALID_APPWIDGET_ID)
// {
// this.onDeleted(context, new int[] { Appwidgid });
// }
// else {
// onReceive(context, intent);
// }
// context.startService(new Intent(context,PlayerAudioActivity.class));
// Log.i(TAG,"Starting Service ConnectivityListener");
// }catch(Exception e){
// Log.e(TAG,e.toString());
// }
// }
}
private void onDeleted(Context context, int[] is) {
// TODO Auto-generated method stub
}
}
+manifest file is following
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.Audio.audioplayer"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name=".MyReceiver" android:enabled="true">
<intent-filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED"/><action
android:name="android.net.conn.CONNECTIVITY_CHANGE"/><action
android:name="android.net.conn.DATA_ACTIVITY_CHANGE"/>
</intent-filter>
</receiver>
<activity
android:name="com.Audio.audioplayer.PlayerAudioActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<data android:scheme="tel" />
</intent-filter>
</activity>
<activity
android:name=".PlayListActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.Audio.audioplayer.PlayerAudioActivity" />
</activity>
</application>
</manifest>
As adamp mentioned in this post you cannot access an action on an intent that you've not set:
{...}
//supposed button call intent
Intent switchIntent=new Intent(this, MyReceiver.class);
PendingIntent pendingIntent=PendingIntent.getBroadcast(this, 0, switchIntent, 0);
{...}
You have to add your designated action to that intent by using setAction().
Something like this:
{...}
Intent switchIntent=new Intent(this, MyReceiver.class);
switchIntent.setAction("YOUR_ACTION");
PendingIntent pendingIntent=PendingIntent.getBroadcast(this, 0, switchIntent, 0);
{...}
ps: just pseudo code
I am trying to catch a bluetooth device disconnection intent filter.
I added a log to the onReceive but it never reaches it and is not displayed in the logcat.
I suspect that the problem is with my manifest.xml configuration:
manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.company"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="16" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name="com.company.MyReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED" />
<action android:name="android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED" />
<action android:name="android.bluetooth.adapter.action.DISCOVERY_STARTED" />
</intent-filter>
</receiver>
<activity
android:name=".BTActivity"
android:label="BTActivity" >
</activity>
</application>
</manifest>
MyReceiver extends BroadcastReceiver:
#Override
public void onReceive(Context context, Intent intent) {
Log.i("got-in", "got-in-");
// String action = intent.getAction();
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.i("disconnect", device.getName());
Intent i = new Intent(context, BTActivity.class);
Bundle b = new Bundle();
b.putString("deviceName", device.getName());
intent.putExtras(b); // Put your id to your next Intent
context.startActivity(i);
// finish();
}
Use this code for receiving a disconnect (when Bluetooth is still turned on):
<intent-filter> <action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
<action android:name="android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED" />
<action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" />
</intent-filter>
Also you have to register a service that then registers a broadcast receiver for Bluetooth status change, so your app knows when Bluetooth was turned off and therefore discards all active devices, as you won't receive a ACL_DISCONNECT when Bluetooth is simply turned off.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(bluetoothTurnedOnOff, filter);
return START_STICKY;
}
private final BroadcastReceiver bluetoothTurnedOnOff = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1) == BluetoothAdapter.STATE_OFF) {
[...]
For new users. it will works . Your manifest file looks
<receiver android:name="(package name).BluetoothReceiver" >
<intent-filter>
<action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
<action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" />
</intent-filter>
</receiver>
and your receiver will look like
else if (intent.getAction().equals(`enter code here`
BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
// connection lost
Try removing the <category .../> from the intent-filter and try again.
Try android.bluetooth.device.action.ACL_DISCONNECTED action in intent filter. It should solve your problem.
From everything I've seen on Stack Exchange and elsewhere, I have everything set up correctly to start an IntentService when Android OS boots. Unfortunately it is not starting on boot, and I'm not getting any errors. Maybe the experts can help...
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.phx.batterylogger"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="internalOnly">
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.BATTERY_STATS" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<service android:name=".BatteryLogger"/>
<receiver android:name=".StartupIntentReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
BroadcastReceiver for Startup:
package com.phx.batterylogger;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class StartupIntentReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = new Intent(context, BatteryLogger.class);
context.startService(serviceIntent);
}
}
UPDATE: I tried just about all of the suggestions below, and I added logging such as Log.v("BatteryLogger", "Got to onReceive, about to start service"); to the onReceive handler of the StartupIntentReceiver, and nothing is ever logged. So it isn't even making it to the BroadcastReceiver.
I think I'm deploying the APK and testing correctly, just running Debug in Eclipse and the console says it successfully installs it to my Xoom tablet at \BatteryLogger\bin\BatteryLogger.apk. Then to test, I reboot the tablet and then look at the logs in DDMS and check the Running Services in the OS settings. Does this all sound correct, or am I missing something? Again, any help is much appreciated.
Well here is a complete example of an AutoStart Application
AndroidManifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="pack.saltriver" android:versionCode="1" android:versionName="1.0">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<receiver android:name=".autostart">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity android:name=".hello"></activity>
<service android:enabled="true" android:name=".service" />
</application>
</manifest>
autostart.java
public class autostart extends BroadcastReceiver
{
public void onReceive(Context context, Intent arg1)
{
Intent intent = new Intent(context,service.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
Log.i("Autostart", "started");
}
}
service.java
public class service extends Service
{
private static final String TAG = "MyService";
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
}
#Override
public void onStart(Intent intent, int startid)
{
Intent intents = new Intent(getBaseContext(),hello.class);
intents.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intents);
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
}
}
hello.java - This will pop-up everytime you start the device after executing the Applicaton once.
public class hello extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Toast.makeText(getBaseContext(), "Hello........", Toast.LENGTH_LONG).show();
}
}
Following should work. I have verified. May be your problem is somewhere else.
Receiver:
public class MyReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(arg1.getAction())) {
Log.d("TAG", "MyReceiver");
Intent serviceIntent = new Intent(context, Test1Service.class);
context.startService(serviceIntent);
}
}
}
Service:
public class Test1Service extends Service {
/** Called when the activity is first created. */
#Override
public void onCreate() {
super.onCreate();
Log.d("TAG", "Service created.");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("TAG", "Service started.");
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.d("TAG", "Service started.");
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="internalOnly">
<uses-sdk android:minSdkVersion="8" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.BATTERY_STATS"
/>
<!-- <activity android:name=".MyActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"></category>
</intent-filter>
</activity> -->
<service android:name=".Test1Service"
android:label="#string/app_name"
>
</service>
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
Your Service may be getting shut down before it completes due to the device going to sleep after booting. You need to obtain a wake lock first. Luckily, the Support library gives us a class to do this:
public class SimpleWakefulReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// This is the Intent to deliver to our service.
Intent service = new Intent(context, SimpleWakefulService.class);
// Start the service, keeping the device awake while it is launching.
Log.i("SimpleWakefulReceiver", "Starting service # " + SystemClock.elapsedRealtime());
startWakefulService(context, service);
}
}
then, in your Service, make sure to release the wake lock:
#Override
protected void onHandleIntent(Intent intent) {
// At this point SimpleWakefulReceiver is still holding a wake lock
// for us. We can do whatever we need to here and then tell it that
// it can release the wakelock.
...
Log.i("SimpleWakefulReceiver", "Completed service # " + SystemClock.elapsedRealtime());
SimpleWakefulReceiver.completeWakefulIntent(intent);
}
Don't forget to add the WAKE_LOCK permission:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
I have found a way to make your application run well when the device reboots, please follow the steps below to be successful.
AndroidManifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="pack.saltriver" android:versionCode="1" android:versionName="1.0">
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".UIBootReceiver" android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<service android:name=".class_Service" />
</application>
</manifest>
UIBootReceiver
public class UIBootReceiver extends BroadcastReceiver {
private static final String TAG = "UIBootReceiver";
#Override
public void onReceive(Context context, Intent arg1)
{
Toast.makeText(context, "started", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(context,class_Service.class);
context.startService(intent);
}
}
This is asking permission to not need to manage battery saving for this app so you can run in the background stably.
Declare this code in onCreate () of MainActivity class:
Intent myIntent = new Intent();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
myIntent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
myIntent.setData(Uri.parse("package:" +
DeviceMovingSpeed.this.getPackageName()));
}
startActivity(myIntent);
Looks very similar to mine but I use the full package name for the receiver:
<receiver android:name=".StartupIntentReceiver">
I have:
<receiver android:name="com.your.package.AutoStart">
I've had success without the full package, do you know where the call chain is getting interrupted? If you debug with Log()'s, at what point does it no longer work?
I think it may be in your IntentService, this all looks fine.
Just to make searching easier, as mentioned in comments, this is not possible since 3.1
https://stackoverflow.com/a/19856367/6505257