I set up broadcast reciever for restarting my foreground service after reboot.
I have two devices and it works on Meizu M1 note (android 5.1) but doesn't work on Samsung A8 (android 9). Looking for reason in restrictions after Oreo and seems like it ok, but just in case https://developer.android.com/about/versions/oreo/background.html
On the second one broadcast reciever called, but service not started after reboot.
Service tracks location and uses startForeground() with Notification for correct work.
Also tried to add Worker to restart service after reboot, but seems like work missing after that.
Please, geve any suggestions why my reciever doesn't run service.
Thanks.
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.tracker">
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:name=".ui.di.App"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:isolatedProcess="true"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<receiver android:name="com.example.tracker.ui.broadcast.ServiceRestart">
<intent-filter>
<action android:name="restartService" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.ACTION_BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<service
android:name="com.example.tracker.ui.service.TrackerService"
android:enabled="true" />
<service
android:name="com.example.tracker.ui.worker.RestartIntentService"
android:enabled="true" />
<activity android:name=".ui.screen.main.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Reciever:
public class ServiceRestart extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("Broadcast Listened", "Service tried to stop");
Toast.makeText(context, "Broadcast: ServiceRestart launched " + intent.getAction(), Toast.LENGTH_LONG).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(new Intent(context, TrackerService.class));
} else {
context.startService(new Intent(context, TrackerService.class));
}
}
}
Service:
public class TrackerService extends Service implements LocationListener {
public static final String TAG = "TrackerService";
private static final int PROCESS_ID = 1024;
private static final int INTERVAL = 120; //seconds
private ConnectivityManager connectivityManager;
private PeriodicWorkRequest workRequest;
private PeriodicWorkRequest restartTrackerRequest;
private DbFirebaseModel dbFirebaseModel = new DbFirebaseModel();
private ServiceHandler mServiceHandler;
private static final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message message) {
}
}
public void onCreate() {
super.onCreate();
HandlerThread mHandlerThread = new HandlerThread("TrackerService.HandlerThread");
mHandlerThread.start();
mServiceHandler = new ServiceHandler(mHandlerThread.getLooper());
}
public TrackerService() {
super();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
addNotificationAndStartForeground();
addWorkers();
mServiceHandler.post(() -> {
connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
runLocationTransfer();
});
Log.d(TAG, "===== SERVICE START");
return START_STICKY;
}
private void addWorkers() {
workRequest = new PeriodicWorkRequest.Builder(
FirebaseWorker.class, 15, TimeUnit.MINUTES, 2, TimeUnit.MINUTES)
.build();
WorkManager.getInstance(this).enqueueUniquePeriodicWork(
FirebaseWorker.TAG,
ExistingPeriodicWorkPolicy.REPLACE,
workRequest);
restartTrackerRequest = new PeriodicWorkRequest.Builder(
TrackerRestartWorker.class, 15, TimeUnit.MINUTES, 2, TimeUnit.MINUTES
).build();
WorkManager.getInstance(this).enqueueUniquePeriodicWork(
TrackerRestartWorker.TAG,
ExistingPeriodicWorkPolicy.REPLACE,
restartTrackerRequest);
}
private void addNotificationAndStartForeground() {
String name = getString(R.string.app_name);
String description = "Service running...";
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
Notification.Builder notificationBuilder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
Integer.toString(PROCESS_ID), "Tracker", NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("Notify me when location tracking");
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);
notificationBuilder = new Notification.Builder(this, Integer.toString(PROCESS_ID));
notificationBuilder.setContentTitle(name)
.setContentText(description)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentIntent(pendingIntent);
notificationManager.notify(PROCESS_ID, notificationBuilder.build());
} else {
notificationBuilder = new Notification.Builder(this);
notificationBuilder.setContentTitle(name)
.setContentText(description)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentIntent(pendingIntent);
}
startForeground(PROCESS_ID, notificationBuilder.build());
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "===== SERVICE STOP");
if (FirebaseAuth.getInstance().getCurrentUser() == null) {
WorkManager.getInstance(this).cancelWorkById(workRequest.getId());
WorkManager.getInstance(this).cancelWorkById(restartTrackerRequest.getId());
Log.d(TAG, "===== WORKERS STOP");
}
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.d(TAG, "TASK REMOVED");
Toast.makeText(this, "LOCATION TASK REMOVED", Toast.LENGTH_SHORT).show();
super.onTaskRemoved(rootIntent);
}
private void runLocationTransfer() {
LocationRequest locationRequest = new LocationRequest();
locationRequest.setPriority(LocationRequest.PRIORITY_LOW_POWER);
locationRequest.setInterval(INTERVAL * 1000);
locationRequest.setFastestInterval(INTERVAL * 1000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(locationRequest);
LocationSettingsRequest locationSettingsRequest = builder.build();
SettingsClient settingsClient = LocationServices.getSettingsClient(this);
settingsClient.checkLocationSettings(locationSettingsRequest);
try {
getFusedLocationProviderClient(this).requestLocationUpdates(locationRequest, new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
onLocationChanged(locationResult.getLastLocation());
}
},
Looper.myLooper());
} catch (SecurityException e) {
e.printStackTrace();
}
}
#Override
public void onLocationChanged(#NonNull Location location) {
if (FirebaseAuth.getInstance().getCurrentUser() == null) {
stopSelf();
Log.d(TAG, "====== SERVICE STOPPED by itself");
} else if (connectivityManager.getActiveNetworkInfo() != null
&& connectivityManager.getActiveNetworkInfo().isConnected()) {
dbFirebaseModel.saveLocation(location);
// test using sound notifications
try {
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
} catch (Exception e) {
e.printStackTrace();
}
Toast.makeText(this, "LOCATION ------ LATITUDE: " + location.getLatitude() + " LONGITUDE: " + location.getLongitude(), Toast.LENGTH_SHORT).show();
} else {
saveToLocalStorage(location);
}
}
private void saveToLocalStorage(Location location) {
Hawk.init(this).build();
String userId = Objects.requireNonNull(
FirebaseAuth.getInstance().getCurrentUser()
).getUid();
LocationData locationData = new LocationData(userId, location);
long count = 0;
if (Hawk.count() > count) {
count = Hawk.count();
}
while (Hawk.contains(String.valueOf(count))) {
count++;
}
Hawk.put(String.valueOf(count), locationData);
Log.d(TAG, "HAWK /// Saved to local storage. COUNT = " + Hawk.count());
}
}
Following steps helped me solve it:
Remove and reinstall app
Change manifest according to this
<receiver android:name="com.foxminded.tracker.ui.broadcast.ServiceRestart"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="restartService" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Here added "android.intent.action.LOCKED_BOOT_COMPLETED" and android:exported="true" android:enabled="true"
Related
I have to launch the app on receiving notifications. The following piece of code works fine when the app is killed and notification is received. But I want When Notification received App Open Automatically Without Click On Notification. App Lunch Automatically in all cases if my mobile is locked too.
Please Help Me. Here Is My Code.
MainActivity.Java
public class MainActivity extends AppCompatActivity {
private static final String TAG="PushNotification";
private static final String CHANNEL_ID = "101";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
createNotificationChannel();
subscribeToTopic();
getToken();
}
private void getToken()
{
FirebaseMessaging.getInstance().getToken().addOnCompleteListener(new OnCompleteListener<String>() {
#Override
public void onComplete(#NonNull Task<String> task) {
if(!task.isSuccessful()){
Log.d(TAG,"OnComplete: Faileed to get the Token");
}
String token=task.getResult();
Log.d(TAG, "onComplete: " + token);
}
});
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "firebaseNotifChannel";
String description = "Receve Firebase notification";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
private void subscribeToTopic() {
FirebaseMessaging.getInstance().subscribeToTopic("resulttime")
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Toast.makeText(MainActivity.this, "Hello", Toast.LENGTH_SHORT).show();
}
});
}
}
MyFireBaseServices.java
public class MyFirebaseServices extends FirebaseMessagingService {
private static final String TAG ="PushNotification";
private static final String CHANNEL_ID = "101";
#Override
public void onMessageReceived(#NonNull RemoteMessage remoteMessage) {
showNotification(remoteMessage.getNotification().getTitle(),remoteMessage.getNotification().getBody());
}
private void showNotification(String title,String message){
Intent intent = new Intent(this, Result.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_baseline_notifications_24)
.setContentTitle(title)
.setContentText(message)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
// Set the intent that will fire when the user taps the notification
.setContentIntent(pendingIntent)
.setAutoCancel(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
// notificationId is a unique int for each notification that you must define
notificationManager.notify(1, builder.build());
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.link.fcmpuchtest">
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE"/>
<application
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.FcmPuchTest">
<activity android:name=".Result"
android:parentActivityName=".MainActivity">
</activity>
<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=".MyFirebaseServices">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
</manifest>
My Php Code Is
<?php
function notify($to,$data){
$api_key="AAAAjW65hDI:APA91bE4cXuCdMf9pPDVHqjjpjelkjirj']9099hUqOX0SOXzi5GEc3mdPwRqsG8bgqz0S3EnpoQtWCaj2_wbF39I57Tyxo4EAeJ2pSo_IVJPc_fQp7hiuNFGYTjkbnJHUIOK7HTioU";
$ch = curl_init();
$url="https://fcm.googleapis.com/fcm/send";
$fields=json_encode(array('to'=>$to,'notification'=>$data));
// Generated by curl-to-PHP: http://incarnate.github.io/curl-to-php/
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, ($fields));
$headers = array();
$headers[] = 'Authorization: key ='.$api_key;
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
}
$to="/topics/resulttime";
$data=array(
'title'=>'Greetings Result',
'body'=>'Hi, From PHP Script'
);
notify($to,$data);
echo "Notification Sent";
?>
I have Already Use This Code But Not Working
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
startActivity(new Intent(this, MainActivity.class));
}
}
I am building basic calling app using TelecomManager, ConnectionService and Connection. But, When an there is an incoming call, my incomingActivity UI is not showing up. Below is the sample code so far.
In my MainActivity.java
Intent intent = new Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER);
intent.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, getPackageName());
startActivity(intent);
// ================================================================
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
TelecomManager manager = (TelecomManager) getSystemService(TELECOM_SERVICE);
// new ComponentName(getPackageName(), CallHandler.TAG), "myCallHandlerId");
PhoneAccountHandle phoneAccountHandle = new PhoneAccountHandle(
new ComponentName(getApplicationContext(), CallHandler.TAG), "myCallHandlerId");
PhoneAccount phoneAccount = PhoneAccount
.builder(phoneAccountHandle, "myCallHandlerId")
.setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
.build();
manager.registerPhoneAccount(phoneAccount);
Log.i("Phone Account", "" + manager.getPhoneAccount(phoneAccountHandle));
Log.i("Phone Account", "" + manager.getPhoneAccount(phoneAccountHandle).isEnabled());
Log.i("Phone Account", "" + manager.getPhoneAccount(phoneAccountHandle).getClass());
Log.i("Phone Account isEnabled", "" + phoneAccount.isEnabled());
Bundle bundle = new Bundle();
Uri uri = Uri.fromParts(PhoneAccount.SCHEME_TEL, "555555555", null);
bundle.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, uri);
bundle.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
// manager.addNewIncomingCall(phoneAccountHandle, bundle);
Log.i("Permitted", "" + manager.isIncomingCallPermitted(phoneAccountHandle));
if(manager.isIncomingCallPermitted(phoneAccountHandle)){
Log.i("Call", "Incoming");
manager.addNewIncomingCall(phoneAccountHandle, bundle);
}
}
In my CallHandler.java
#RequiresApi(api = Build.VERSION_CODES.M)
public class CallHandler extends ConnectionService{
public static final String TAG = CallHandler.class.getName();
#RequiresApi(api = Build.VERSION_CODES.N_MR1)
#Override
public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
Log.i("CallHandler","onCreateIncomingConnection");
// return super.onCreateIncomingConnection(connectionManagerPhoneAccount, request);
Context context = getApplicationContext();
Log.i("Context","" + context);
Log.i("Context","" + context.getPackageName());
Log.i("Context","" + getBaseContext());
Log.i("Context","" + context.getClass().getName());
Log.i("Context","" + context.getClass().getSimpleName());
CallConnection callConnection = new CallConnection(context);
callConnection.setInitializing();
callConnection.setActive();
callConnection.setCallerDisplayName("Manik", TelecomManager.PRESENTATION_ALLOWED);
// callConnection.setConnectionProperties(Connection.PROPERTY_SELF_MANAGED);
// callConnection.setConnectionCapabilities(Connection.CAPABILITY_HOLD & Connection.CAPABILITY_SUPPORT_HOLD);
return callConnection;
}
#Override
public void onCreateIncomingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
super.onCreateIncomingConnectionFailed(connectionManagerPhoneAccount, request);
}
#Override
public void onCreateOutgoingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
super.onCreateOutgoingConnectionFailed(connectionManagerPhoneAccount, request);
}
#Override
public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
return super.onCreateOutgoingConnection(connectionManagerPhoneAccount, request);
}
}
In my CallConnection.java
#RequiresApi(api = Build.VERSION_CODES.M)
public class CallConnection extends Connection {
private Context context;
#RequiresApi(api = Build.VERSION_CODES.N_MR1)
public CallConnection(Context con) {
context = con;
setConnectionProperties(PROPERTY_SELF_MANAGED);
setAudioModeIsVoip(true);
}
#Override
public void onAnswer(int videoState) {
super.onAnswer(videoState);
Log.i("Call","Answered");
}
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onShowIncomingCallUi() {
Log.i("Call","Incoming Call");
super.onShowIncomingCallUi();
// MainActivity con = new MainActivity();
// Context context = con.getApplicationContext();
NotificationChannel channel = new NotificationChannel("channel", "Incoming Calls",
NotificationManager.IMPORTANCE_HIGH);
channel.setImportance(NotificationManager.IMPORTANCE_HIGH);
// other channel setup stuff goes here.
// We'll use the default system ringtone for our incoming call notification channel. You can
// use your own audio resource here.
Uri ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
channel.setSound(ringtoneUri, new AudioAttributes.Builder()
// Setting the AudioAttributes is important as it identifies the purpose of your
// notification sound.
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build());
// NotificationManager mgr = context.getSystemService(NotificationManager.class);
// mgr.createNotificationChannel(channel);
// Create an intent which triggers your fullscreen incoming call user interface.
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION | Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(context, IncomingCallScreenActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, 0);
Log.i("Intent1","" + intent);
Log.i("Intent2","" + intent.getPackage());
Log.i("Intent3","" + intent.getType());
Log.i("Intent4","" + intent.getData());
Log.i("Intent5","" + intent.getDataString());
Log.i("Intent6","" + intent.getAction());
Log.i("Intent7","" + intent.getCategories());
Log.i("Intent8","" + intent.getExtras());
Log.i("Pending Intent","" + pendingIntent);
Log.i("Pending Intent","" + pendingIntent.getCreatorPackage());
// Build the notification as an ongoing high priority item; this ensures it will show as
// a heads up notification which slides down over top of the current content.
final Notification.Builder builder = new Notification.Builder(context);
builder.setOngoing(true);
builder.setPriority(Notification.PRIORITY_HIGH);
// Set notification content intent to take user to fullscreen UI if user taps on the
// notification body.
builder.setContentIntent(pendingIntent);
// Set full screen intent to trigger display of the fullscreen UI when the notification
// manager deems it appropriate.
builder.setFullScreenIntent(pendingIntent, true);
// Setup notification content.
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle("Your notification title");
builder.setContentText("Your notification content.");
// Set notification as insistent to cause your ringtone to loop.
Notification notification = builder.build();
notification.flags |= Notification.FLAG_INSISTENT;
// Use builder.addAction(..) to add buttons to answer or reject the call.
NotificationManager notificationManager = context.getSystemService(
NotificationManager.class);
notificationManager.notify("Call Notification", 37, notification);
// context.startActivity(intent);
}
}
All the log messages inside onCreateIncomingConnection() and onShowIncomingCallUi() are showing up when the app launches, and not when there is an incoming call.
All the permissions in AndroidManifest.xml
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
<!--
Needed only if your calling app reads numbers from the `PHONE_STATE`
intent action.
-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<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/AppTheme">
<activity android:name=".IncomingCallScreenActivity"></activity>
<activity android:name=".CallScreenActivity" />
<activity android:name=".ContactsActivity" />
<activity android:name=".LogsActivity" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="tel" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service
android:name=".CallHandler"
android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE">
<intent-filter>
<action android:name="android.telecom.ConnectionService" />
</intent-filter>
</service>
</application>
Any help would be appreciated. Thanks
I'm trying to send a push notification to all devices from firebase but at first i tried only in my phone, it doesn't work, after that i tried in another phone and it doesn't work either. Finally with the 3rd one it work and it work at the second one magically. What i have to do to the push notifications work in all devices?
Manifest ->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.startingandroid.firebasecloudmessaging">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".SplashActivity" android:label="">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity" android:label="FCM"></activity>
<service
android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service
android:name=".MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
</application></manifest>
MyFirebaseInstanceIDService ->
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static final String TAG = "MyFirebaseIIDService";
#Override
public void onTokenRefresh() {
//Getting registration token
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
//Displaying token in logcat
Log.e(TAG, "Refreshed token: " + refreshedToken);
}
private void sendRegistrationToServer(String token) {
//You can implement this method to store the token on your server
//Not required for current project
} }
MyFirebaseMessagingService ->
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "StartingAndroid";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//It is optional
Log.e(TAG, "From: " + remoteMessage.getFrom());
Log.e(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
//Calling method to generate notification
sendNotification(remoteMessage.getNotification().getTitle(),remoteMessage.getNotification().getBody());
}
//This method is only generating push notification
private void sendNotification(String title, String messageBody) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}}
SplashActivity
public class SplashActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
getSupportActionBar().hide();
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_splash);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i = new Intent(SplashActivity.this,
MainActivity.class);
startActivity(i);
finish();
}
}, 4000);
}}
I have a broadcast receiver which detects oncoming notifications when the app is open and in background but when the recent app is cleared the receiver is not working please suggest me ideas.
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentService.class.getName());
JSONObject json = new JSONObject();
try {
json.putOpt("userid", StorePreference.GetSharedPreferenceDetails(context, "memberid"));
json.putOpt("rid",StorePreference.GetSharedPreferenceDetails(context, "partnerid"));
json.putOpt("message", "Received");
BoundService.getInstance().onlinestatus(json);
} catch (Exception e) {
e.printStackTrace();
}
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
Manifest decleration:
<receiver
android:name="com.twogether.receivers.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name = "com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.google.android.gcm.demo.app" />
</intent-filter>
</receiver>
Try to register your receiver in manifest, use GcmListenerService to receive messages.
google example https://github.com/googlesamples/google-services has example to do this.
<!-- gcm_receiver, this is android source-->
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.myapp.gcm" />
</intent-filter>
</receiver>
<!-- gcm_listener service -->
<service
android:name="com.qblinks.qmote.GcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
// Use this service to receive message
public class GcmListenerService extends com.google.android.gms.gcm.GcmListenerService {
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
Log.v(TAG, "From: " + from);
Log.v(TAG, "Message: " + message);
sendNotification(message);
}
private void sendNotification(String message) {
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification)
.setContentTitle("this is title")
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))//multi line
.setSound(defaultSoundUri); // ring or vibrate if no ring
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(Const.NOTIFICATION_GCM /* ID of notification */, notificationBuilder.build());
}
}
When the app is close you need to wake the app up, means you need to have the permission to do that
<uses-permission android:name="android.permission.WAKE_LOCK" />
and after you can set:
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
manager.set(AlarmManager.RTC, System.currentTimeMillis() + 5000, yourIntent);
I have tried to simplify my code as much as possible, basically hte issue is that the ActivityRecognitionIntentService appears to be called a couple of times, then stalls out. It appears to be related to the requestCode in the PendingIntent, but I am not sure, can someone please advise me as to what is going wrong? Thanks.
Dashboard.java
public class Dashboard extends Activity implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener {
private BroadcastReceiver receiver;
private TextView tvActivity;
private GoogleApiClient mGoogleApiClient;
//String Locationp = "null";
//private LocationRequest mLocationRequest;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
tvActivity = (TextView) findViewById(R.id.tvActivity);
int resp =GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if(resp == ConnectionResult.SUCCESS){
// Create a GoogleApiClient instance
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(ActivityRecognition.API)
//.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
else{
Toast.makeText(this, "Please install Google Play Service.", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onConnected(Bundle arg0) {
Intent i = new Intent(this, ActivityRecognitionIntentService.class);
PendingIntent mActivityRecognitionPendingIntent = PendingIntent.getService(this, 2000, i, PendingIntent.FLAG_UPDATE_CURRENT);
Log.e("MAIN", "Connected to ActRec");
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(mGoogleApiClient, 1000, mActivityRecognitionPendingIntent);
}
#Override
public void onConnectionSuspended(int arg0) {
Log.e("MAIN", "Connection suspended to ActRec");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e("MAIN", "Not Connected to ActRec");
}
ActivityRecognitionIntentService.java
public class ActivityRecognitionIntentService extends IntentService {
public ActivityRecognitionIntentService() {
super("ActivityRecognitionIntentService");
}
protected void onHandleIntent(Intent intent) {
if (ActivityRecognitionResult.hasResult(intent)) {
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
DetectedActivity mostProbAct = result.getMostProbableActivity();
int confidence = mostProbAct.getConfidence();
String mostProbActName = getActivityName(mostProbAct.getType());
Intent i = new Intent("com.xxx.abc.ACTIVITY_RECOGNITION_DATA");
i.putExtra("act", mostProbActName);
i.putExtra("confidence", confidence);
Log.e("ARS", mostProbActName + "," + confidence);
//sendBroadcast(i);
} else
Log.e("ARS", "Intent had no ActivityRecognitionData");
}
private String getActivityName(int activityType) {
switch (activityType) {
case DetectedActivity.IN_VEHICLE:
return "in_vehicle";
case DetectedActivity.ON_BICYCLE:
return "on_bicycle";
case DetectedActivity.ON_FOOT:
return "on_foot";
case DetectedActivity.STILL:
return "still";
case DetectedActivity.UNKNOWN:
return "unknown";
case DetectedActivity.TILTING:
return "tilting";
}
return "unknown";
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tigerblood.com.node" >
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version"/>
<service android:enabled="true" android:name="com.xxx.abc.ActivityRecognitionIntentService"></service>
<activity
android:name="com.tigerblood.node.Dashboard"
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>
</manifest>