No coming back from Notification, Broadcastreceiver not working - android

My goal is to
push a button btnAktivieren,
then after some time (defined by random) a notification is shown.
I tap this notification, which leads me to an alertdialog.
After this AlertDialog's choice was made, it goes back to 2.
So far, I only got to 3 even though the code should work the whole way through
What I tried
MainActivity.java
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
boolean aktiviert = false;
public EditText minutenVon = null;
public EditText minutenBis = null;
public Context con = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
con = this;
final Button btnAktivieren = (Button)findViewById(R.id.btnAktivieren);
btnAktivieren.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
minutenBis = (EditText)findViewById(R.id.etBis);
minutenVon = (EditText)findViewById(R.id.etVon);
EditText etAktuelleAufgabe = (EditText)findViewById(R.id.etAktuelleAufgabe);
if (aktiviert) {
btnAktivieren.setText("Aktivieren");
aktiviert = false;
}
else
{
btnAktivieren.setText("Deaktivieren");
Random random = new Random();
int w = (int) (random.nextDouble() * (Double.parseDouble(minutenBis.getText().toString()) - Double.parseDouble(minutenVon.getText().toString())) + Double.parseDouble(minutenVon.getText().toString()));
int interval = w * 60000;
int interval_in_sekunden = w * 60;
aktiviert = true;
String aufgabe = "";
if (etAktuelleAufgabe.getText().toString() == "")
aufgabe = "Diese Information";
else
aufgabe = etAktuelleAufgabe.getText().toString();
PendingIntent pendingIntent;
Intent intent;
intent = new Intent(con, Kommt.class);
intent.putExtra("aufgabe", aufgabe);
intent.putExtra("minutenVon", minutenVon.getText().toString());
intent.putExtra("minutenBis", minutenBis.getText().toString());
pendingIntent = PendingIntent.getBroadcast(con, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notificationBuilder = new Notification.Builder(con)
.setContentTitle(aufgabe)
.setContentText("Test")
.setSmallIcon(R.mipmap.ic_launcher)
.setWhen((System.currentTimeMillis()/1000)+interval_in_sekunden)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService (Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder);
}
}
});
}
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.test.test">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
<application
android:allowBackup="true"
android:launchMode="singleTop"
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>
<receiver android:name=".Kommt" />
</application>
</manifest>
Kommt.java
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;
import java.util.Random;
public class Kommt extends BroadcastReceiver {
public Context con;
String aufgabe = "";
String minutenVon = "";
String minutenBis = "";
private Context mContext;
public void onReceive(Context context, Intent intent) {
con = context;
aufgabe = intent.getStringExtra("aufgabe");
minutenVon = intent.getStringExtra("minutenVon");
minutenBis = intent.getStringExtra("minutenBis");
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setIcon(R.mipmap.ic_launcher);
builder.setTitle(aufgabe)
.setMessage("Test");
builder.setPositiveButton("Ja", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
neu();
}
});
builder.setNegativeButton("Nein", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
AlertDialog.Builder builder = new AlertDialog.Builder(con);
builder.setIcon(R.mipmap.ic_launcher);
builder.setTitle("Test")
.setMessage("Test2");
builder.setPositiveButton("Gut", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
neu();
}
});
builder.create().show();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
public void neu()
{
Random random = new Random();
int w = (int) (random.nextDouble() * (Double.parseDouble(minutenBis.toString()) - Double.parseDouble(minutenVon.toString())) + Double.parseDouble(minutenVon.toString()));
int interval = w * 60000;
int interval_in_sekunden = w * 60;
String aufgabe = "";
if (aufgabe == "")
aufgabe = "Test";
PendingIntent pendingIntent;
Intent intent;
intent = new Intent(con, Kommt.class);
intent.putExtra("aufgabe", aufgabe);
pendingIntent = PendingIntent.getBroadcast(con, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notificationBuilder = new Notification.Builder(con)
.setContentTitle(aufgabe)
.setContentText("Testtest3")
.setSmallIcon(R.mipmap.ic_launcher)
.setWhen((System.currentTimeMillis()/1000)+interval_in_sekunden)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build();
NotificationManager notificationManager = (NotificationManager) con.getSystemService (Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder);
}
}

You are trying to open AlertDialog from BroadcastReceiver that is not able to find context(context you) .Do one thing redirect user to from broadcastreceiver and from there show alertdialog in onCreate.
Problem One : You have to pass theme in Alert Dialog
AlertDialog.Builder builder = new
AlertDialog.Builder(context,
R.style.AppTheme);
Secondly you can't show dialog from Broadcastreceiver its not getting context as a developer hope you know how to redirect user from Broadcastreceiver to activity .
Error you must be getting crash for this
java.lang.RuntimeException: Unable to start receiver
com.stackoverflow.Kommit:
android.view.WindowManager$BadTokenException: Unable to add window --
token null is not for an application
So redirect user to MainActivity instead of showing alertDialog and in onCreate of MainActivity show alert dialog where you will have context on MainActivity
UPDATED Kommit.java(onReceive)
Intent i = new Intent(context, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); Bundle b = new Bundle();
b.putInt("notify", 1);
i.putExtras(b); //Put your id to your next Intent
context.startActivity(i);
In MainActivity OnCreate()
Bundle b = getIntent().getExtras(); int value = 0; // or other values
if(b != null)
value = b.getInt("notify");
if(value !=0)
{
//show alertdialog
}
EDIT by P. Dee: Corrected your notify.

try to change the id for different notifications:
notificationManager.notify(0, notificationBuilder);
here change 0 to some dynamic number

Normally a dialog needs an Activity context, or make the dialog type a system alert dialog
alert.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
This needs the android.permission.SYSTEM_ALERT_WINDOW to be declared in manifest.

For my opinion , onReceive can only survive for 10 seconds. So if your random time is longer than 10 seconds,the notification object is destroied which is newed in onReceive. So my advice is that do this in a new thread in Service instead of Broadcast Receiver.

Related

Why doesn't the notification appear?

I have made an app to test to show a foreground service and then tried to implement it in real app to close wifi after certain time, the code is the same as my test app but it doesn't show notification.
the service works fine but without notification
Main Activity
package com.example.countdownclosewifi.UI;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.widget.Toast;
import com.example.countdownclosewifi.MyService;
import com.example.countdownclosewifi.R;
import com.example.countdownclosewifi.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
private BroadcastReceiver receiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
// Intent filter to set the same action of the broadcast sender
IntentFilter intentFilter_getRemainingTime = new IntentFilter();
intentFilter_getRemainingTime.addAction("Count");
// what will happen when the app receive a broadcast
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int i = intent.getIntExtra("Show", 0);
binding.timeLeft.setText(String.valueOf(i));
}
};
registerReceiver(receiver, intentFilter_getRemainingTime);
binding.start.setOnClickListener(view -> {
if (binding.setTime.getText().toString().isEmpty() || Long.parseLong(binding.setTime.getText().toString()) == 0) {
Toast.makeText(MainActivity.this, "Enter the duration", Toast.LENGTH_SHORT).show();
} else {
Intent serviceIntent = new Intent(this, MyService.class);
int time = Integer.parseInt(binding.setTime.getText().toString());
serviceIntent.putExtra("Time", time);
if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.O){
startForegroundService(serviceIntent);
}
else {
startService(serviceIntent);
}
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
}
Service class
package com.example.countdownclosewifi;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
//import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.IBinder;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import com.example.countdownclosewifi.UI.MainActivity;
import java.util.Timer;
import java.util.TimerTask;
public class MyService extends Service {
private WifiManager wifiManager;
private int timeRemaining;
private Timer timer;
// Intent intent;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
IntentFilter intentFilter_stop = new IntentFilter();
intentFilter_stop.addAction("Stop timer");
timeRemaining = intent.getIntExtra("Time", 0);
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
if (timeRemaining == 0) {
wifiManager.setWifiEnabled(false);
timer.cancel();
stopSelf();
}
setNotification(timeRemaining);
Intent intent = new Intent();
intent.setAction("Count");
intent.putExtra("Show", timeRemaining);
sendBroadcast(intent);
timeRemaining -= 1;
}
}, 0, 1000);
return START_STICKY;
}
public void setNotification(int timeRemaining) {
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent =
PendingIntent.getActivity(this, 0, notificationIntent, 0);
String channel_id = "id";
Notification notification;
if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.O) {
notification = new Notification.Builder(this, channel_id)
.setContentTitle("You are running out of time")
.setContentText(String.valueOf(timeRemaining))
.setSmallIcon(R.drawable.wifi_24)
.setContentIntent(pendingIntent)
.setOnlyAlertOnce(true)
.build();
} else {
notification = new NotificationCompat.Builder(this, channel_id)
.setContentTitle("You are running out of time")
.setContentText(String.valueOf(timeRemaining))
.setSmallIcon(R.drawable.wifi_24)
.setContentIntent(pendingIntent)
.setOnlyAlertOnce(true)
.build();
}
// Notification ID cannot be 0.
startForeground(1, notification);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String id = "Notification Channel";
CharSequence name = "notification";
NotificationChannel notificationChannel = new NotificationChannel(id, name, NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(notificationChannel);
}
}
#Override
public void onDestroy() {
super.onDestroy();
stopForeground(true);
}
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.countdownclosewifi">
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<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.CountDownCloseWIFI">
<activity android:name=".UI.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyService"/>
</application>
</manifest>
it's so clear but i cant see what i am missing to show this notification.
use countdowntimer class instead of timerTask
and set the priority as MAX
NotificationManager.IMPORTANCE_HIGH
I Solved it, the problem was that the Notification ID was not the same as the Channel ID

Cannot able run Bluetooth Scanning in Foreground service more than 10 - 15 secs even though Notification is provided

I have used Service to keep my scan for android mobiles even when the app is closed. I used Broadcast receiver to restart my service when killed. It restarts the scanning and it works only for some 15 seconds and then stops
When i click button1 in {MainActivity} I started the service and have called startdiscovery() in startCommand method in {ExampleService}
Please Help me in running the app in background
MainActivity.java
import android.Manifest;
import android.app.ActivityManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.bluetooth.le.ScanResult;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResponse;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.FirebaseFirestore;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
ListView scanListView;
ArrayList<String> stringArrayList = new ArrayList<String>();
ArrayAdapter<String> arrayAdapter;
static BluetoothAdapter myAdapter = BluetoothAdapter.getDefaultAdapter();
FirebaseFirestore db = FirebaseFirestore.getInstance();
static int count=0;
ScanResult sc;
String Uuid;
Date currentTime;
private LocationSettingsRequest.Builder builder;
private final int REQUEST_CHECK_CODE=8989;
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
LocationManager locationm;
String provider;
Button button1;
BluetoothAdapter bluetoothAdapter;
Intent btEnablingIntent;
int requestCodeForEnable;
Button button;
Button scanButton1;
RegisterActivity registerActivity=new RegisterActivity();
String email ;
String phone ;
///
Intent discoverableIntenet = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
Intent mServiceIntent;
private ExampleService mYourService;
Context ctx;
public Context getCtx() {
return ctx;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
currentTime = Calendar.getInstance().getTime();
setContentView(R.layout.activity_main);
checkLocationPermission();
btEnablingIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
requestCodeForEnable=1;
discoverableIntenet.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 3000);
startActivity(discoverableIntenet);
button=(Button) findViewById(R.id.button4);
Intent intent = new Intent(MainActivity.this,ble.class);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,ble.class);
MainActivity.this.startActivity(intent);
}
});
button=(Button) findViewById(R.id.button6);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
open(view);
}
});
button=(Button) findViewById(R.id.button3);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
pdfs(view);
}
});
button=(Button) findViewById(R.id.button5);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
myths(view);
}
});
button1=(Button) findViewById(R.id.button2);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
analytics(view);
}
});
scanListView = (ListView) findViewById(R.id.scannedListView);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
scanButton1=(Button) findViewById(R.id.Button1);
scanButton1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("disc","discoveeery!");
Log.i("hiiiiiii", String.valueOf(myAdapter.isDiscovering()));
Intent serviceIntent = new Intent(MainActivity.this, ExampleService.class);
serviceIntent.putExtra("inputExtra", "hi");
// startService( serviceIntent);
mYourService = new ExampleService();
mServiceIntent = new Intent(MainActivity.this, mYourService.getClass());
if (!isMyServiceRunning(mYourService.getClass())) {
startService(mServiceIntent);
}
}
});
bluetoothOnMethod();
BluetoothFunctions();
}
public void BluetoothFunctions(){
Log.d("disc", "discovery!");
IntentFilter intentFilter;
intentFilter=new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(myreceiver, intentFilter);
intentFilter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(myreceiver, intentFilter);
arrayAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, stringArrayList);
scanListView.setAdapter(arrayAdapter);
Uuid="02.020202.020.02";
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == requestCodeForEnable) {
if (resultCode == RESULT_OK) {
Toast.makeText(getApplicationContext(), "Bluetooth is enabled", Toast.LENGTH_LONG).show();
}
else if(resultCode==RESULT_CANCELED) {
Toast.makeText(getApplicationContext(), "Bluetooth enabling cancelled", Toast.LENGTH_LONG).show();
}
}
}
final BroadcastReceiver myreceiver = new BroadcastReceiver() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getName() == null) {
return;
}
String address = device.getName();
int N = 2;
float type = intent.getFloatExtra((BluetoothDevice.EXTRA_UUID),Float.MIN_VALUE);
int rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE);
String rssi_val = String.valueOf(rssi);
String data = device.getAddress() + " " + rssi_val;
Vibrator v1 = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
stringArrayList.add(data);
if (rssi >= -50) {
v1.vibrate(VibrationEffect.createOneShot(1000, VibrationEffect.DEFAULT_AMPLITUDE));
count++;
if (device.getAddress() != null) {
Firebasepush(device.getAddress(), rssi_val);
}
}
Log.i("lll", device.getAddress());
Log.i("lll", device.getName());
Log.i("+>>>>>>>>>>>>>", BluetoothDevice.EXTRA_UUID);
Log.i("lll", rssi_val);
arrayAdapter.notifyDataSetChanged();
// Toast.makeText(getApplicationContext()," TX power: " +sc.getTxPower() + "dBm", Toast.LENGTH_SHORT).show();
//startThread();
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
Log.v("ggggggggg", "Entered the Finished ");
myAdapter.startDiscovery();
}
}
};
public void Firebasepush(String uuid,String rrsi){
Map<String, Object> updateMap = new HashMap();
updateMap.put("RSSI", rrsi);
updateMap.put("time", currentTime);
Map<String, Object> countMap = new HashMap();
countMap.put("Count", count);
countMap.put("time", currentTime);
countMap.put("Name",registerActivity.NameString);
countMap.put("Email",registerActivity.EmailId);
countMap.put("Phone Number",registerActivity.PhoneNumber);
// Add a new document with a generated ID
db.collection("users").document(Uuid).collection("contacts").document(uuid)
.set(updateMap);
db.collection("users").document(Uuid).
set(countMap);
}
void bluetoothOnMethod() {
if(bluetoothAdapter==null){
Toast.makeText(getApplicationContext(), "Bluetooth does not support ",Toast.LENGTH_LONG).show();
}
else {
if(!bluetoothAdapter.isEnabled()){
startActivityForResult(btEnablingIntent,requestCodeForEnable);
}
}
}
public boolean checkLocationPermission() {
LocationRequest request = new LocationRequest()
.setFastestInterval(1500)
.setInterval(3000)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
builder = new LocationSettingsRequest.Builder()
.addLocationRequest(request);
Task<LocationSettingsResponse> result = LocationServices.getSettingsClient( this).checkLocationSettings(builder.build());
result.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() {
#Override
public void onComplete(#NonNull Task<LocationSettingsResponse> task) {
try{
task.getResult(ApiException.class);
}catch (ApiException e){
switch (e.getStatusCode())
{
case LocationSettingsStatusCodes
.RESOLUTION_REQUIRED:
try {
ResolvableApiException resolvableApiException= (ResolvableApiException) e;
resolvableApiException.startResolutionForResult(MainActivity.this,REQUEST_CHECK_CODE);
} catch (IntentSender.SendIntentException ex) {
ex.printStackTrace();
}catch (ClassCastException ex){
}break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
{ break;}
}
}
}
});
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
new AlertDialog.Builder(this)
.setTitle(R.string.title_location_permission)
.setMessage(R.string.text_location_permission)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
})
.create()
.show();
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode,String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
//Request location updates:
// locationm.requestLocationUpdates(provider, 400, 1,this);
}
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
}
}
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
Log.i ("Service status", "Running");
return true;
}
}
Log.i ("Service status", "Not running");
return false;
}
#Override
protected void onDestroy() {
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("restartservice");
broadcastIntent.setClass(this, Restarter.class);
this.sendBroadcast(broadcastIntent);
super.onDestroy();
// Don't forget to unregister the ACTION_FOUND receiver.
// unregisterReceiver(myreceiver);
}
public void openservices(){
Intent intnt=new Intent(this ,Services.class);
startActivity(intnt);
}
public void open(View view)
{
Intent browserIntent=new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.hogist.com/#/"));
startActivity(browserIntent);
}
public void pdfs(View view)
{
Intent browserIntent=new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.mohfw.gov.in/pdf/Illustrativeguidelineupdate.pdf"));
startActivity(browserIntent);
}
public void myths(View view)
{
Intent browserIntent=new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.mohfw.gov.in/pdf/Illustrativeguidelineupdate.pdf"));
startActivity(browserIntent);
}
public void analytics(View view){
final Intent intent1 = new Intent(MainActivity.this, Analytics.class);
startActivity(intent1);
}
}
ExampleService.java
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import java.util.Timer;
import java.util.TimerTask;
public class ExampleService extends Service {
BluetoothAdapter myAdapter = BluetoothAdapter.getDefaultAdapter();
MainActivity mainActivity=new MainActivity();
public int counter=0;
#Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O)
startMyOwnForeground();
else
startForeground(1, new Notification());
}
#RequiresApi(Build.VERSION_CODES.O)
private void startMyOwnForeground()
{
String NOTIFICATION_CHANNEL_ID = "example.permanence";
String channelName = "Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setContentTitle("App is running in background")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(2, notification);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
// startTimer();
myAdapter.startDiscovery();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
// stoptimertask();
myAdapter.cancelDiscovery();
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("restartservice");
broadcastIntent.setClass(this, Restarter.class);
this.sendBroadcast(broadcastIntent);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}```
Restarter.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.util.Log;
import android.widget.Toast;
public class Restarter extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("Broadcast Listened", "Service tried to stop");
Toast.makeText(context, "Service restarted", Toast.LENGTH_SHORT).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Log.i(Restarter.class.getSimpleName(), "Service Stops! Oooooooooooooppppssssss!!!!");
context.startForegroundService(new Intent(context, ExampleService.class));
} else {
context.startService(new Intent(context, ExampleService.class));
}
}
}
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hogist_social_distancing">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
android:name=".App"
android:fullBackupContent="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".Analytics"
android:screenOrientation="portrait" />
<activity
android:name=".Services"
android:screenOrientation="portrait" />
<activity
android:name=".Permissions"
android:screenOrientation="portrait" />
<activity
android:name=".MainActivity"
android:screenOrientation="portrait" />
<activity android:name=".RegisterActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".OTPActivity" />
<activity android:name=".ble" />
<service
android:name=".ExampleService"
android:enabled="true" />
<receiver
android:name="Restarter"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="restartservice" />
</intent-filter>
</receiver>
</application>
</manifest>```
Android strives to save the battery, so it's expected that your service is stopped, especially if it runs battery draining operations such as Bluetooth scans.
Also, bare in mind that starting from Android 7, an app cannot start the BLE scan more than 5 times per 30 seconds, as mentioned here. Other issues related to BLE scanning are listed here.
If you do want to run Bluetooth scans in the background, I suggest you use a JobIntentService, in which you start BLE scan for a few seconds.
JobIntentService is very similar to IntentService but with few benefits like holding a wake lock which prevents the CPU to go to sleep
Also, this type of service does not require displaying a notification to your user. For more info: https://developer.android.com/reference/androidx/core/app/JobIntentService
are you sure your bluetooth code can work well on activity (without service)?
you can not restart your service by call Broadcast when you service was killed, because when your service was killed by OS system, it will kill your application process so your broadcast will not work. When you call return START_STICKY; it means system will automatic restart your service when it have available resource

Canceling a notification from another activity - Android

When I click a button, I create a notification in Status Bar.
By being clicked, this notification creates an activity.
In the layout of this activity, there is a button.
When I click this button, the notification that created the activity where the button is, must be canceled.
The problem comes because I can create more than one notifications, giving to them different IDs.
But when I open the Status Bar, I see al the notifications, I select one, the activity is created and I click the button to cancel the activity.
What happens is that the notification canceled is always the last created instead of being the one I selected.
This is the code from the main activity, where notifications are created:
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.ButtonBarLayout;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class NotifMenuActiv extends AppCompatActivity {
private Button but_notif, but_cancel;
private NotificationManager mNotificationManager;
private Notification.Builder mBuilder;
private EditText id;
private Intent resultIntent;
private PendingIntent pIntent;
private int req_code = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notif_menu);
mNotificationManager = (NotificationManager)getSystemService(Context
.NOTIFICATION_SERVICE);
mBuilder = new Notification.Builder(this);
mBuilder.setSmallIcon(R.drawable.joda);
resultIntent = new Intent(this, NotifActiv.class);
id = (EditText)findViewById(R.id.id);
but_notif = (Button)findViewById(R.id.but_notif);
but_notif.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
resultIntent.putExtra("id", Integer.valueOf(id.getText().
toString()));
pIntent = PendingIntent.getActivity(getApplicationContext(),
req_code++, resultIntent, PendingIntent
.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(pIntent);
mBuilder.setContentTitle(id.getText().toString());
mNotificationManager.notify(Integer.valueOf(id.getText().
toString()),mBuilder.build());
mBuilder.setContentText(Integer.valueOf(mNotificationManager
.getActiveNotifications().length).toString());
mNotificationManager.notify(Integer.valueOf(id.getText().
toString()),mBuilder.build());
}
}
});
but_cancel = (Button)findViewById(R.id.but_cancel1);
but_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mNotificationManager.cancel(Integer.valueOf(id.getText().
toString()));
}
});
}
}
And this is the onCreate method from the activity created when I click on a notification:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notif);
Intent intent = getIntent();
id = intent.getIntExtra("id",id);
mNotificationManager = (NotificationManager)getSystemService(Context
.NOTIFICATION_SERVICE);
but_exit = (Button)findViewById(R.id.but_exit);
but_exit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
// This is the button that must cancel the notification that created
// the activity
but_cancel = (Button)findViewById(R.id.but_cancel2);
but_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mNotificationManager.cancel(id);
}
});
}
Thank you very much.
SOLVED!!! the solution is to give a different requestCode to each PedingIntent.
Instead of this:
PendingIntent pIntent = PendingIntent.getActivity(getApplicationContext(),0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Do this:
PendingIntent pIntent = PendingIntent.getActivity(getApplicationContext(),req_code++, resultIntent,PendingIntent.FLAG_UPDATE_CURRENT);

How to send notifications when app was closed

I am creating an android app that consists of android push notifications.Here i need the push notifications that will run even when the app was closed. I had achieved it by calling the notification in a service. But here when i was running the code in the android >5.x devices my code was running perfectly even when app was closed notification was coming for every 5 sec but when i was running app on devices <5.x notifications was displaying only when the app was opened or when it was minimised not receiving any notifications when app was closed can any one help me what my mistake is and this is my code
SERVICE:
package com.example.servicesandroid;
import java.util.Timer;
import java.util.TimerTask;
import com.example.servicesandroid.MainActivity.MyTimerTask;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;
public class Androidservice extends Service {
final static String ACTION = "NotifyServiceAction";
final static String STOP_SERVICE = "";
final static int RQS_STOP_SERVICE = 1;
NotifyServiceReceiver notifyServiceReceiver;
private static final int MY_NOTIFICATION_ID = 1;
private NotificationManager notificationManager;
private Notification myNotification;
Timer timer;
TimerTask timer_task;
Handler handler;
#Override
public void onCreate() {
// TODO Auto-generated method stub
notifyServiceReceiver = new NotifyServiceReceiver();
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
MyTimerTask myTask = new MyTimerTask();
Timer myTimer = new Timer();
myTimer.schedule(myTask, 5000, 1500);
// TODO Auto-generated method stub
return Service.START_STICKY;
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
this.unregisterReceiver(notifyServiceReceiver);
super.onDestroy();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
public class NotifyServiceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
int rqs = arg1.getIntExtra("RQS", 0);
if (rqs == RQS_STOP_SERVICE) {
stopSelf();
}
}
}
class MyTimerTask extends TimerTask {
public void run() {
generateNotification(getApplicationContext(), "Hello");
}
}
private void generateNotification(Context context, String message) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
String appname = context.getResources().getString(R.string.app_name);
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
Notification notification;
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MainActivity.class), 0);
// To support 2.3 os, we use "Notification" class and 3.0+ os will use
// "NotificationCompat.Builder" class.
if (currentapiVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
notification = new Notification(icon, message, 0);
notification.setLatestEventInfo(context, appname, message,
contentIntent);
notification.flags = Notification.FLAG_AUTO_CANCEL;
notificationManager.notify((int) when, notification);
} else {
NotificationCompat.Builder builder = new NotificationCompat.Builder(
context);
notification = builder.setContentIntent(contentIntent)
.setSmallIcon(icon).setTicker(appname).setWhen(0)
.setAutoCancel(true).setContentTitle(appname)
.setContentText(message).build();
notificationManager.notify((int) when, notification);
}
}
}
This is my activity:
package com.example.servicesandroid;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent serviceIntent = new Intent(MainActivity.this,Androidservice.class);
startService(serviceIntent);
}
This is my Broadcast receiver when device reboots:
package com.example.servicesandroid;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class Boot_Completed extends BroadcastReceiver {
private final String BOOT_COMPLETED_ACTION = "android.intent.action.BOOT_COMPLETED";
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(intent.getAction().equals(BOOT_COMPLETED_ACTION)){
Intent myIntent = new Intent(context, Androidservice.class);
context.startService(myIntent);
}
}
}
This is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.servicesandroid"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="#drawable/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=".Androidservice"/>
<receiver android:name=".Boot_Completed" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
Please any one help me with this

how to put notification after some time

Hi I'd like to put notify to user to execute the application when application on background after 5 minutes.
So, I use onWindowFocusChanged to check my app is background or not. Please help me what should I do.This is my code. Please answer me with full code.
And I'd like to notify them with popup menu.
MainActivity.java
package com.myapp;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
.............//import is too long
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.myapp.R;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btnA = (Button)findViewById(R.id.btngetA);
btnA.setOnClickListener(new Button.OnClickListener(){
#Override
public void onClick(View v){
//TODO Auto-generated method stub
Intent intentA = new Intent(getApplicationContext(), gotoAActivity.class);
startActivity(intentA);
}
});
#Override
public void onWindowFocusChanged(boolean hasFocus) {
if (!hasFocus) {
new CountDownTimer(1000, 1) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
//timer finished
}
}.start();
}
super.onWindowFocusChanged(hasFocus);
}
this is notification. but I don't know where this codes should added..
public static void createService(Context context, CharSequence tickerMessage, CharSequence title,
CharSequence message, int icon, int id, Intent intent, long[] pattern, Boolean autoCancel) {
PendingIntent p = PendingIntent.getService(context, 0, intent, 0);
Notification n;
title="notice";
message="execute your app!!";
int apiLevel = Build.VERSION.SDK_INT;
if (apiLevel >= 11) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setContentTitle(title)
.setTicker(tickerMessage)
.setContentText(message)
.setSmallIcon(icon)
.setContentIntent(p)
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
if (pattern.length > 0) {
builder.setVibrate(pattern);
}
if (autoCancel != null) {
builder.setAutoCancel(autoCancel);
}
if (apiLevel >= 17) {
// Android 4.2+
n = builder.build();
}
else {
// Android 3.x
n = builder.getNotification();
}
}
else {
// Android 2.2+
n = new Notification(icon, tickerMessage, System.currentTimeMillis());
// Data
n.setLatestEventInfo(context, title, message, p);
}
NotificationManager nm = (NotificationManager)
context.getSystemService(Activity.NOTIFICATION_SERVICE);
nm.notify(id, n);
}
You should send the notification in onFinish() method but to be honest this code doesn't work at all. If your activity is in background can be killed by OS at anytime. What you could do is to set an alarm of 5 minutes in the onStop() callback of your activity and delete it in the onStart() callback. In this way if the activity is not started after 5 minutes you can do some work depending on what you want to do when the timer expires.

Categories

Resources