I have an Android application in When application go in background and headphone remove from phone alarm start.All is fine on foreground,but when application go in background its not work.I wrote code on activity onPause() as below
#Override
protected void onPause() {
try{
super.onPause();
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.hasExtra("state")) {
int state = intent.getIntExtra("state", 0);
if (isHeadPhoneAttached && state == 0) {
isHeadPhoneAttached = false;
if (isTriggered) {
createNotification();
initTimerCounter();
makeToat();
/*handler.removeCallbacks(sendUpdatesToUI);*/
/*callTriggerActivity();*/
/*showDialog(Headphone_DIALOG);*/
}
} else if (!isHeadPhoneAttached && state == 1) {
isHeadPhoneAttached = true;
}
}
}
}, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
/*createNotification();
initTimerCounter() ;*/
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
but it's not working.Please anybody give me some idea.
You can't be sure if your application is running in the background so registering an BroadcastReceiver in the onPause method of an Activity is general bad practice.
You should use a Service instead
Related
I am developing a android app, which will update device location after 4 seconds interval and depending on the response received from the server it will open specific activity.
Problem 1) In some case it will open up a activity like incoming phone call with sound. I am facing problem when I am removing the app from recent app. I noticed the poll function is running twice at the same time, and multiple media is playing at the same time.
Problem 2) I am using Service intead of IntentService(I am a beginner and not sure which will be better). The background service should run even the phone goes to sleep mode, just like WhatsApp or other messenger run.
As the file is big enough, I am attaching only important part
public class TaxiNorrService extends Service implements LocationListener {
...
...
final Handler poll_handler = new Handler();
private NotificationManager mNM;
private final Actions actions = new Actions();
public Ringtone r;
private String newtext;
private Runnable BreakRunnable;
private Runnable poll_runnable;
private Handler BreakHandler;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
poll_runnable = new Runnable() {
#Override
public void run() {
if(!App.isAutoBreak()){
if(BreakHandler !=null){
BreakHandler.removeCallbacks(BreakRunnable);
}
if(r != null) {
if (r.isPlaying()) {
r.stop();
}
}
}
if (actions.checkPermission(getApplicationContext())) {
checkGPS();
if(isNetworkAvailable()){
if(App.isPollOn()){
poll(latitude, longitude);
}
}else{
if(BreakHandler !=null){
BreakHandler.removeCallbacks(BreakRunnable);
}
boolean foregroud = false;
try {
foregroud = new ForegroundCheckTask().execute(getApplication()).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
boolean background = isMyServiceRunning(TaxiNorrService.class);
if(foregroud == true && background == true && App.isAppForground()){
if(!App.isLoadingVisible()){
Intent intent = new Intent(TaxiNorrService.this, Loading_activity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
}
}
poll_handler.postDelayed(this, 4000);
}
};
return Service.START_STICKY;
}
private void poll(double lat, double lon){
//Connected to API endpoint
}
...
...
#Override
public void onDestroy() {
if(r != null) {
if (r.isPlaying()) {
r.stop();
}
}
poll_handler.removeCallbacks(poll_runnable);
super.onDestroy();
}
}
I found the answer for my questions. The code written in the onStartCommand should be within onCreate function. This is because onCreate will execute when service starts first time, and onStartCommand will execute every time when you start the app. Please follow this topic,
Android - running a method periodically using postDelayed() call
Hi just a newbie with android. I am trying to create a service which will constantly fetch location and update the an activity exp: Dashboard map. I have been following Android service
Now my problem is how to
- Constantly notify Dashboard activity ( was trying to simulate with while loop to notify data) from service
- I was able to print logs on connect and onBind, but i was wondering how to constantly watch for notification from service and retrieve the notified data from the Activity ie.Dashboard. Hope I am able convey my issue. I am searching for the latest api.
You should use BroadcastReceiver in your Dashboard activity. to do this follow this step:
Add a inner class to Dashboard activity like this:
public class ActionCompleteReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
String state = "disconnected";
if(intent != null)
state = intent.getStringExtra("State");
//Your Code
}
}
Add this code to Dashboard activity:
private ActionCompleteReceiver mActionReceiver;
public static final String ACTION_SERVICE_COMPLETE = "YUOR_PACKAGE_NAME.ACTION_SERVICE_COMPLETE";
Register receiver in onResume method in Dashboard activity like this
#Override
protected void onResume()
{
super.onResume();
if(mActionReceiver = null)
mActionReceiver= new ActionCompleteReceiver();
registerReceiver(mActionReceiver, new IntentFilter(ACTION_SERVICE_COMPLETE));
}
Unregister receiver onPause and onDestroy:
#Override
protected void onPause()
{
super.onPause();
if (mActionReceiver != null)
{
try
{
unregisterReceiver(mActionReceiver );
}
catch (Exception ignored)
{
}
}
}
#Override
public void onDestroy()
{
super.onDestroy();
if (mActionReceiver != null)
{
try
{
unregisterReceiver(mActionReceiver );
}
catch (Exception ignored)
{
}
}
}
In your service where you need to notify Dashboard activity add this:
Intent intent = new Intent(DashboardActivity.ACTION_SERVICE_COMPLETE);
intent.putExtra("State", "Connected");
sendBroadcast(intent);
I've create an application, VPN service, which will block internet packets. Everything is working fine but now I want to stop this VPN service on a button click event so that packets are not blocked anymore.
I've tried to use stopService(name); and stopSelf();
but nothing happened. What am I doing wrong?
public class VpnServiceCls extends VpnService {
private Thread b;
private ParcelFileDescriptor c;
private PendingIntent a;
Builder builder = new Builder();
private static final String TAG = "VpnService";
#Override
public void onDestroy() {
// TODO Auto-generated method stub
Log.d(TAG, "you are in jghbgjyhb");
if (b != null) {
Log.d(TAG, "you are in destroy2");
b.interrupt();
}
}
public void StopMyVPN()
{
Log.d(TAG, "you are in jghbgjyhb 898");
stopSelf();
if (b != null) {
Log.d(TAG, "you are in destroy");
b.interrupt();
}
b.stop();
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
b= new Thread(new Runnable() {
#Override
public void run() {
try{
//here is my logic which is working fine
}
}
catch(Exception e)
{
Log.d(TAG, "you are out "+e.toString());
}
}
});//start the service
b.start();
return START_STICKY;
}
}
on button click i am calling StopMyVPN() function but notting happen
you must close and set null interface of vpn .mInterface is vpn interface.
public void StopMyVPN() {
try {
if (mInterface != null) {
mInterface.close();
mInterface = null;
}
isRunning = false;
} catch (Exception e) {
}
stopSelf();
}
you could Bind Activity to your service for calling StopMyVPN.
I also struggled with this issue. At the end I found that my problem was caused by parcelFileDescriptor which I was not closing, and that kept my service from destroy.
private fun stop(){
try {
parcelFileDescriptor.close()
} catch (ex: IOException) {
Log.e(TAG,"parcelFileDescriptor.close()", ex)
}
stopForeground(true)
stopSelf()
}
In a typical android service you can call stopSelf(); but in this case as it is VpnService, same should work only when you closed the interfaces.
So in VpnService when you build a Tun by doing establish() and get the interface. Now if you want to shutdown your VPN tunnel, then you need to first close this interface and then you need to stop all the threads that you have started, and then you are free to call stopSelf() and it should work.
I'm sorry for my bad English.
I develop an Android app using NFC. I added a method that stops unsecured keyguards temporarily to the app for the purpose of quickly uses NFC tags.
However, I thought stopping keyguards causes battery drains when sleeping, so I added a method that recovers keyguards when devices are sleeping.
As a result, I wrote codes shown below.
public class MainActivity extends Activity {
private NfcAdapter mAdapter;
private PowerManager mPowerManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// regist screen on / off actions receiver
IntentFilter scFilter = new IntentFilter();
scFilter.addAction(Intent.ACTION_SCREEN_ON);
scFilter.addAction(Intent.ACTION_SCREEN_OFF);
scFilter.addAction(Intent.ACTION_USER_PRESENT);
registerReceiver(mScreenReceiver, scFilter);
}
#Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
String action = intent.getAction();
if (action != null && (action.equals(NfcAdapter.ACTION_TAG_DISCOVERED)
|| action.equals(NfcAdapter.ACTION_TECH_DISCOVERED)
|| action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED))) {
// manage NFC Tags here
Log.d("MainActivity", "NFC Tags detected");
Toast.makeText(getApplicationContext(), "NFC Tags detected", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onResume() {
super.onResume();
// enableForegroundDispatch
if (mAdapter == null) {
mAdapter = NfcAdapter.getDefaultAdapter(getApplicationContext());
}
if (mAdapter != null) {
Intent nfcIntent = new Intent(this, getClass());
nfcIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, nfcIntent, 0);
mAdapter.enableForegroundDispatch(this, pendingIntent, null, null);
} else {
Log.d("MainActivity", "failed getDefaultAdapter()");
}
}
#Override
public void onPause() {
if (mPowerManager != null) {
if (!mPowerManager.isScreenOn()) {
// clearWindowFlags only when device is sleeping
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}
}
// disableForegroundDispatch
if (mAdapter != null) {
mAdapter.disableForegroundDispatch(this);
mAdapter = null;
}
super.onPause();
}
#Override
public void onDestroy() {
try {
// unregist screen on / off actions receiver
unregisterReceiver(mScreenReceiver);
} catch (IllegalArgumentException e) {
}
super.onDestroy();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return false;
}
private BroadcastReceiver mScreenReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction() == null) {
return;
}
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
} else if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
}
}
};
}
But, this code didn't perform as intended on my device.
I use Nexus 7 (1st, OS 4.3, Slide lock enabled).
First, when I launched the app and put my device into sleep, keyguards didn't recover with a probability of 30%. It sounds read sound effects with NFC tags even when sleeping.
Second, my device rarely won't read NFC tags after about an hour sleep with using the app. It will not even sound anything with NFC tags. But the condition goes off after sleep again or terminating the app.
Who does know causes of the bugs?
I want set my current user to not authenticated every time the phone goes to sleep or the app is switched off (i.e. either goes to the desktop or another app), so that they always have to authenticate when the app comes back on again.
I don't want to do this in the OnStop or OnPause methods in each activity, only when the app isn't currently active.
Ideally there would be an OnStop method in the Application base object or some other global context, similar to this:
public class MyApp : Application
{
public override void OnCreate()
{
base.OnCreate();
}
}
but unfortunately this doesn't exist. Is this possible?
It turns out there isn't. The solution was to test in an inactivity timer, e.g.:
private void InactivityTimer_Elapsed(object sender, ElapsedEventArgs e)
{
_secondsElapsed += 1;
if (_screenEventReceiver.IsScreenOff || IsApplicationSentToBackground(this.ApplicationContext))
{
// do things that you would OnStop here
}
}
public static bool IsApplicationSentToBackground(Context context)
{
try
{
var am = (ActivityManager)Context.GetSystemService(Context.ActivityService);
var tasks = am.GetRunningTasks(1);
if (tasks.Count > 0)
{
var topActivity = tasks[0].TopActivity;
if (topActivity.PackageName != context.PackageName)
{
return true;
}
}
}
catch (System.Exception ex)
{
Errors.Handle(Context, ex);
throw;
}
return false;
}
private class ScreenEventReceiver : BroadcastReceiver
{
public bool IsScreenOff { get; private set; }
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action == Intent.ActionScreenOff)
{
IsScreenOff = true;
}
else
{
IsScreenOff = true;
}
}
}