hi guys thank you for answering my question,i have made an android app in android studio i want to make funtion when i close the app the function start automatically in background is there any way to do it (Sorry For My Bad English)
You can use services. Here is the link for the official documentation:
https://developer.android.com/guide/components/services.html
You can use Application class.
public class App extends Application {
private static App instance;
private static Context context;
#Override
public void onCreate() {
super.onCreate();
App.context = getApplicationContext();
startService(new Intent(this, YourBackgroundService.class));
}
}
Then in BackgroundService class should be like this :
public class YourBackgroundService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
} <br>
Make sure you can declare this class in AndroidManifest.xml
<service android:name=".YourBackgroundService" />
If you declare like this the application will run always in background.
Related
I'm trying to create a service which will run a socket for receiver data when the app is closed.
According to this thread on Github Flutter should provide an abstraction for background execution, flutter doesn't have an abstraction that executes a code in the background, so I'm writing a native code.
The service opens up correctly, but as soon as the app is closed, it gets moved to cache services and after approximately 5 minutes it is ended.
I found this background_service MainActivity.java, but I'm not using the notification example contained in that repository. (The service contained in this repository also gets terminated once the app is closed.
The example plugin for this article as well.
I still don't have a concrete plan to make the socket connection in the service. I actually would like to call the socket_io_client function within the service, sort of like a callback, but I'm not sure if it will work.
So I just want to know if it is possible to keep the service running after the app is closed. If yes, how?
MainActivity.java
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "com.retroportalstudio.www.background_service";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent forService = new Intent(this, MyService.class);
forService.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(new MethodChannel.MethodCallHandler() {
#Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
if (methodCall.method.equals("startService")) {
startService(forService);
result.success("Service Started");
}
}
});
}
}
public class MyService extends Service {
// #Override
// public int onStartCommand(Intent intent, int flags, int startId) {
// return START_STICKY;
// }
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
My Discovery class extends Service class. When I try to get its singletone from other class this way:
Discovery discovery = Discovery.getInstance();
I get a NullPointerException. This is the Discovery code:
public static Discovery getInstance(){
if (discovery == null){
discovery = new Discovery();
discovery.initDiscovery ();
}
Log.i(TAG, "get discovery instance");
return discovery;
}
public Discovery() {
}
private void initDiscovery(){
mDiscoveredDevices = new ArrayList<String>();
BluetoothManager bluetoothManager = (BluetoothManager) discovery.getSystemService(Context.BLUETOOTH_SERVICE);<--NullPointerException
....
}
This is not Android my friend.
To create a service you need to declare it in manifest:
<service
android:name=".DiscoveryService" />
After which you can instantiate it but never using operator new. Instead you need to call:
startService(context, new Intent(context, DiscoveryService.class);
There are other ways of firing a service intent but this will suffice for now.
The service's construction code should be placed at onCreate:
class DiscoveryService extends Service {
#Override
public void onCreate() {
service construction code here
}
}
And its request handling code in onStartCommand:
public int onStartCommand(Intent intent, int flags, int startId) {
handle incoming intent
}
Now, if you do need to access a service instance probably the simplest way
of achieving it would be to declare and maintain a static instance reference within
the service. Do it like this:
class DiscoveryService extends Service {
private static DiscoveryService inst; // <-----------------
public DiscoveryService getInstance() {
return inst;
}
#Override
public void onCreate() {
service construction code here
inst = this;
}
#Override
public void onDestroy() {
cleanup code here
inst = null;
}
}
This approach has its shortcomings, but unlike yours, it will work. Still use with care.
Finally - years of writing & reviewing Android code have led me to the conclusion
that what most novice developers want when they ask for Service, is in fact an IntentService..
Please read the docs and make sure you got your class right.
Good luck.
I am implementing in my Android app a splash screen which:
dowloads a sqlite database from a server
loads urls to get JSONs
creates a sqlite database in the device and execute several queries
I am using AsyncTask to do everything, my problem will occur if the user close the app in the middle of the process or turn off the device because the app:
could be creating a database or executing crucial queries in the device
could be downloading the sqlite db from a server
could be running several important process
etc
Definitely, the entire process (3-5 seconds) is important.
So... How could I avoid this? should I use handlers, loaders, on-(pause, stop, destroy) methods in order to get my objective? Can you give me an example?
As mentioned in the comment above, you should use a service as their lifecycle is separate to that of the activity.
Create the service like so:
public class MyService extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Do everything you need to here, then call stop:
Log.d("DEBUG", "Started...");
stopSelf();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
Intent intent = new Intent("com.example.androidexample.SERVICE_STOPPING");
sendBroadcast(intent);
super.onDestroy();
}
}
Then in the activity:
public class MainActivity extends Activity {
private ServiceCompleteReceiver receiver;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter filter;
receiver = new ServiceCompleteReceiver();
filter = new IntentFilter("com.example.androidexample.SERVICE_STOPPING");
startService(new Intent(this, MyService.class));
registerReceiver(receiver, filter);
}
public class ServiceCompleteReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Do whatever needs to be done here
unregisterReceiver(receiver);
}
}
}
EDIT :
Don't forget to add it to your manifest as well
<service
android:name="com.example.androidexample.MyService"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
</service>
I have a test project, my simple test case extends AndroidTestCase class :
public class MyTest extends AndroidTestCase{
private Context mContext;
public MyTest(){
super();
}
#Override
public void setUp() throws Exception {
super.setUp();
mContext = getContext();
//Start my service
mContext.startService(new Intent(mContext, MyService.class));
}
#Override
protected void runTest() {
...
}
...
}
In setUp() callback of my above test case, I started MyService.
MyService has also been declared in AndroidManifest.xml of my test project:
<service
android:name="com.my.app.services.MyService"/>
MyService.java :
public class MyService extends Service {
#Override
public void onCreate() {
super.onCreate();
Log.d("MyService", "onCreate()");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Log.d("MyService", "onStartCommand");
}
...
}
But after I run my test case, I noticed from log that neither onCreate() nor onStartCommand() callbacks of MyService have been called.
Why? Is there any special rule applied to Service usage in Android Test Framework which I missed?
The context returned by AndroidTestCase is probably a mocked context - it probably has no implementation for startService. Have you read http://developer.android.com/tools/testing/service_testing.html ?
If you want to wowk with service then use ServicetestCase.
I have been having the same problem, I think. I am trying to test code which calls startService, not test the service itself, so I created a new service for testing purposes.
It appears that test cases can start services, but the services have to be part of the main project being tested, they can't be part of the test project. I don't really like having a test only class in my project, but since it seems to be the only way ...
I'm trying to call a service class to update the value of a variable from my widget but it doesn't ever seem to get to the service class. I've had a look at some examples and I can't figure out what I'm doing wrong, and I don't really know very much about services yet. All help appreciated.
Service class
public class toggleMonitoringService extends Service{
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate()
{
Log.d("Me","creating service");
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int startId, int something) {
// TODO Auto-generated method stub
String toggle = intent.getExtras().getString("Toggle");
Log.d("Me","Toggle : " + toggle);
if (toggle.equals("app1"))
{
UpdateWidgetService.monitorApp1 = !UpdateWidgetService.monitorApp1;
}
else if (toggle.equals("app2"))
{
UpdateWidgetService.monitorApp2 = !UpdateWidgetService.monitorApp2;
}
super.onStartCommand(intent, startId, something);
return 0;
}
}
Where I set up the intent and pending intent to handle the button click from the widget
Intent monitor1toggle = new Intent(this.getApplicationContext(),toggleMonitoringService.class);
monitor1toggle.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
monitor1toggle.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,allWidgetIds);
monitor1toggle.putExtra("Toggle","app1");
PendingIntent monitor1 = PendingIntent.getService(getApplicationContext(), 0 , monitor1toggle,0);
remoteViews.setOnClickPendingIntent(R.id.firstappstatus, monitor1);
Try start service manually, wihtout using PendingIntent.
Better way is not to start service each time you need to do something, but to start it once, bind to it and use common method calls when you need something from the service.
For your example even a simple Thread would be more appropriate.