I have to create application and want to use it always when phone works, currently my code is:
Android Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.plan.pedometer">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:enabled="true"
android:name=".PedometerService"/>
<receiver
android:name=".receiver.StartPedometerServiceAtBootReceiver"
android:label="StartPedometerServiceAtBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
StartPedometerServiceAtBootReceiver:
public class StartPedometerServiceAtBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Intent serviceIntent = new Intent(context, PedometerService.class);
context.startService(serviceIntent);
}
}
}
Service:
public class PedometerService extends IntentService {
private int Steps=0;
public PedometerService() {
super("Pedometer_Worker_Thread");
}
#Override
protected void onHandleIntent(Intent intent) {
putInSharedPreferences();
synchronized (this) {
try {
wait(1000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void putInSharedPreferences(){
stepsNumbers = getApplicationContext().getSharedPreferences("stepsData", MODE_PRIVATE);
editorStepsNumbers=stepsNumbers.edit();
editorStepsNumbers.putInt(String.valueOf(STEPS),Steps).apply();
}
}
It works if I start Service in MainActivity by:
Intent intent = new Intent(getApplication(),PedometerService.class);
startService(intent);
and Service is running in background but when I restart my phone nothing happens and Service does not start.
I have one more question, this is Pedometer application, where should I put onSensorChange method in Service? Create something like while(1) in onHandleIntent() and put it there?
UPDATE - my actually code is:
I followed this tutorial https://github.com/codepath/android_guides/wiki/Starting-Background-Services
and tried to use WakefulBroadcastReceiver
AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.plan.pedomoter">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.plan.pedomoter.MyTestService"
android:exported="false"/>
<receiver android:name="com.plan.pedomoter.BootBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
MainActivity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onStart() {
super.onStart();
launchTestService();
}
public void launchTestService() {
// Construct our Intent specifying the Service
Intent i = new Intent(this, MyTestService.class);
// Add extras to the bundle
i.putExtra("foo", "bar");
// Start the service
startService(i);
}
}
Receiver:
public class BootBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Launch the specified service when this message is received
Intent startServiceIntent = new Intent(context, MyTestService.class);
startWakefulService(context, startServiceIntent);
}
}
Service:
public class MyTestService extends IntentService {
Handler handler;
// Must create a default constructor
public MyTestService() {
// Used to name the worker thread, important only for debugging.
super("test-service");
}
#Override
public void onCreate() {
super.onCreate(); // if you override onCreate(), make sure to call super().
// If a Context object is needed, call getApplicationContext() here.
handler = new Handler();
}
#Override
protected void onHandleIntent(Intent intent) {
WakefulBroadcastReceiver.completeWakefulIntent(intent);
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(MyTestService.this, "start", Toast.LENGTH_LONG).show();
int i = 0;
}
});
int i=0;
while(true){
i++;
// Do some work here
if(i>1000)
i=0;
}
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(MyTestService.this, "stop", Toast.LENGTH_SHORT).show();
}
}
I used while(true) in MyTestService for check that app is running in background, in project I will use sensors (this is pedometer application) then I want to put something like MyAlarmReceiver from tutorial to send data to the server several times a day.
try this
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mkonuk.rebootapplication">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<service android:name=".MyService"/>
<receiver android:name=".MyBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
MainActivity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(getBaseContext(),MyService.class));
}
}
MyService
public class MyService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(getApplicationContext(),"Service started",Toast.LENGTH_LONG).show();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(getApplicationContext(),"Service Destroyed",Toast.LENGTH_LONG).show();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
MyBootReceiver
public class MyBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context,MyService.class);
context.startService(service);
}
}
I have tested when application started service will be start , even if your application destroyed service will be started again.Even if reboot android device service will be started.
Second question :
if you will use sensor with service you need to register sensor listener and unregister sensor listener when service destroyed,oncreate method override sensor object and create sensor and sensor manager.In onstartCommand method register generated sensor listener sensor manager object ,unregister listener when service destroy
you can check this link
Accelemeter in android
if you want to send message from service to activity,you have to implement onbind() method ,activity need to bind on service check this link
bind activity on service using sensor
bind/unbind service
Hello I am a little new and looking for the some help, (It is not an answer) I coulndt add any other commentI was trying to execute a similar app, I followed what mithat show,then when I turn off my mobili it seems like it starts, but just when I put my cellphone password, it appears a system toast that says "app Stop", so i could t get it. Even when I sweep the app from 'Recent app" it says "app Stop"
I would like to run it for ever,
thanks
Related
I'm trying to create a service that monitors received sms,
the service onStartCommand and OnCreate are getting called, however when I'm sending sms Broadcast receiver OnReceive is not getting called, What is the problem?
Here is my code:
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:dataExtractionRules="#xml/data_extraction_rules"
android:fullBackupContent="#xml/backup_rules"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.MyApplication"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<service android:enabled="true" android:name="com.example.myapplication.SmsServices" />
<receiver android:name=".SmsListener"
android:exported="true" android:priority="1000">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
</manifest>
Service
public class SmsServices extends Service {
private SmsListener smslistener;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("SmsServices", "onStartCommand");
return START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
smslistener = new SmsListener();
IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(smslistener, filter);
Log.d("SmsServices", "Registered Sms Listener.");
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(smslistener);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Broadcast receiver
public class SmsListener extends BroadcastReceiver {
public SmsListener (){}
#Override
public void onReceive(Context context, Intent intent) {
Log.d("SmsListener", "Sms received.");
if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(intent.getAction())) {
for (SmsMessage smsMessage : Telephony.Sms.Intents.getMessagesFromIntent(intent)) {
String msgBody = smsMessage.getMessageBody();
String msgAddr = smsMessage.getOriginatingAddress();
}
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent( this, SmsServices.class ) );
Log.d("Main","Service Started.");
}
}
I've looked at similar posts with the same question, yet none of the sugested fixes resolved such for me - I've attempted refactoring my service, I've checked the permissions in my xml, I've given the permission then restarted the device, and the service is definitely running - below is the service in full, and the manifest.
public class NotificationWatchdog extends NotificationListenerService {
#Override
public void onNotificationPosted(StatusBarNotification sbn, NotificationListenerService.RankingMap rankingMap) {
Log.i("NotifStatus", "Notification Recieved");
Toast.makeText(this, sbn.getNotification().tickerText, Toast.LENGTH_SHORT).show();
super.onNotificationPosted(sbn, rankingMap);
}
#Override
public void onListenerConnected() {
Log.i("NotifStatus", "Listener Awake");
super.onListenerConnected();
}
#Override
public void onCreate() {
Log.i("ThreadStatus", "Thread Created.");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
Log.i("ThreadStatus", "Thread Awake");
//WebRequest stuff here, not related to question.
// If we get killed, after returning from here, restart
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
#Override
public void onDestroy() {
Log.i("ThreadStatus", "Thread Destroyed");
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}}
<?xml version="1.0" encoding="utf-8"?>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.ProdigyEndpoint"
android:networkSecurityConfig="#xml/network_security_config">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".NotificationWatchdog"
android:label="#string/service_name"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
<meta-data
android:name="android.service.notification.default_filter_types"
android:value="1,2">
</meta-data>
<meta-data
android:name="android.service.notification.disabled_filter_types"
android:value="2">
</meta-data>
</service>
</application>
<uses-permission android:name="android.permission.INTERNET"/>
Apologies in advance for what I'm sure will be a foolish question.
Sorry for my english. I have spent 2 days but I can't send push messages to android. I use google cloud message. For example in gcm I create a new project and I have an id:
Then I enabled gcm and added the server key
I have code like this:
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.alexy.gcmclient">
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.hmkcode.android.gcm.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.hmkcode.android.gcm.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
>
<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=".GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.hmkcode.android.gcm" />
</intent-filter>
</receiver>
<service
android:name=".GcmMessageHandler"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
</application>
</manifest>
GcmBroadcastReceiver
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.e("GcmBroadcastReceiver", "GcmBroadcastReceiver");
// Explicitly specify that GcmMessageHandler will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GcmMessageHandler.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
GcmMessageHandler
public class GcmMessageHandler extends IntentService {
String mes;
private Handler handler;
public GcmMessageHandler() {
super("GcmMessageHandler");
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
handler = new Handler();
Log.e("GcmMessageHandler", "GcmMessageHandler");
}
#Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
// The getMessageType() intent parameter must be the intent you received
// in your BroadcastReceiver.
String messageType = gcm.getMessageType(intent);
Log.e("message", messageType);
}
Main
public class MainActivity extends Activity implements OnClickListener{
Button btnRegId, unregister;
EditText etRegId;
GoogleCloudMessaging gcm;
String regid;
String PROJECT_NUMBER = "308****";
private BroadcastReceiver mRegistrationBroadcastReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
unregister = (Button) findViewById(R.id.unregister);
btnRegId = (Button) findViewById(R.id.btnGetRegId);
etRegId = (EditText) findViewById(R.id.etRegId);
btnRegId.setOnClickListener(this);
}
public void getRegId(){
new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
String msg = "";
try {
InstanceID instanceID = InstanceID.getInstance(getApplicationContext());
String token = instanceID.getToken(PROJECT_NUMBER,
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
msg = token;
//apiKey = msg;
GcmPubSub.getInstance(getApplicationContext()).subscribe(token, "/topics/users", null);
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
}
return msg;
}
#Override
protected void onPostExecute(String msg) {
etRegId.setText(msg + "\n");
Log.e("key", msg);
}
}.execute(null, null, null);
}
#Override
public void onClick(View v) {
getRegId();
}
}
I use service and tried to send some push messages to the device. In service it says Success. But the push in android is not coming (I have no output in the log)
I assume your app package name must be com.example.alexy.gcmclient or replace the package name build.gradle
defaultConfig
applicationId "com.yourpackge"
<permission
android:name="com.example.alexy.gcmclient.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission
android:name="com.example.alexy.gcmclient.permission.C2D_MESSAGE" />
<receiver android:name=".GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.example.alexy.gcmclient" />
</intent-filter>
</receiver>
The package names for C2D_MESSAGE are wrong, change them to your package name. Also, make sure you have the configuration file near the build.gradle of your app directory. Edit: go through all of the manifest and change wherever you see hmk to your package name. Your package name should be com.example.alexy.gcmclient as per your manifest.
I'm creating a service which is started, but no communication is received via broadcast. I suspected that there was something wrong with IntentFilter and names, but it all seems correct.
I've been studying example from vogella (par. 8)
What have I done wrong? Why broadcast is not received by MainActivity?
MainActivity
package com.jackslastssid;
import ...
public class MainActivity extends ActionBarActivity {
class MainActivityAfterCaller extends AfterCaller {
public void callback() {
update_something();
}
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(MainActivity.this, "Daemon called back! :)", Toast.LENGTH_LONG).show(); // never happend
}
};
#Override
protected void onResume() {
super.onResume();
registerReceiver(receiver, new IntentFilter(SayHelloDaemon.NOTIFICATION));
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
}
SayHelloDaemon:
public class SayHelloDaemon extends IntentService {
public static final String NOTIFICATION = "com.jackslastssid.SayHelloDaemon";
public SayHelloDaemon() {
super("SayHelloDaemon");
}
class SayHelloDaemonAfterCaller extends AfterCaller {
public void callback() {
Intent intent = new Intent(NOTIFICATION);
sendBroadcast(intent);
}
}
// will be called asynchronously by Android
#Override
protected void onHandleIntent(Intent intent) {
new SayHelloAsyncTask().execute(new Pair<AfterCaller, Map>(new SayHelloDaemonAfterCaller(), Data.getInstance().getQueryMap()));
}
}
AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jackslastssid" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<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>
<service
android:name=".SayHelloDaemon"
android:icon="#drawable/icon"
android:label="#string/service_name"
android:exported="false"/>
</application>
</manifest>
It looks like you haven't started the service in the activity.
Intent intent = new Intent(this, SayHelloDaemon.class);
startService(intent);
Below is my Java code and my XML code. Can someone please tell me why my onReceieve method is never getting called.
Java:
public class PopUPSMS extends Activity {
String RECEIVE_SMS = "RECEIVE_SMS";
private static final String LOG_TAG = "PopUPSMS";
static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.i(LOG_TAG, "onCreate");
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.i(LOG_TAG, "onReceive");
}
}, new IntentFilter(RECEIVE_SMS));
}
}
XML:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.smith.johnathan.phone"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".PopUPSMS"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-sdk android:minSdkVersion="3" />
</manifest>
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.i(LOG_TAG, "onReceive");
}
}, new IntentFilter(RECEIVE_SMS));
You have registered your broadcast receiver with the string "RECEIVE_SMS". The IntentFilter should be of a form of an action. With your declaration:
static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";
you will have:
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.i(LOG_TAG, "onReceive");
}
}, new IntentFilter(ACTION));
You can have a look at the Api demos Manifest for the XML declaration
You can't use receiver as an inner class. Create a separate one.
Don't you need to specify that you want to receive SMS in your manifest?
<application android:icon="#drawable/icon" android:label="#string/app_name">
<receiver android:name=".MyApp">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>