My Problem as follows:
Since I added into webview "file:///android_asset/index.html" to load from, it crashes at startService(new Intent(this, TimeService.class));. If startService commented out. It works fine. When it is used, but I give webview a address like www.google.de, everything works fine. I am using API Level 26 for developing. Unfortunately I can not resolve this issue by now.
Java Code:
MainActivity.webView.loadUrl("file:///android_asset/index.html");
MainActivity.webView.getSettings().setJavaScriptEnabled(true);
MainActivity.webView.getSettings().setUseWideViewPort(true);
MainActivity.webView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
//tel nummer support
if (url.startsWith("tel:") || url.startsWith("sms:") || url.startsWith("smsto:") || url.startsWith("mms:") || url.startsWith("mmsto:"))
{
Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse(url));
startActivity(intent);
return true;
}
//email support
if(url.startsWith("mailto:")){
Intent i = new Intent(Intent.ACTION_SENDTO, Uri.parse(url));
startActivity(i);
}
view.loadUrl(url);
return true;
}
});
startService(new Intent(this, TimeService.class));
Crash message:
FATAL EXCEPTION: Thread-6
Process: com.feuerwehrmautern.ffmautern, PID: 3656
android.os.FileUriExposedException: file:///android_asset/index.html exposed beyond app through Intent.getData()
at android.os.StrictMode.onFileUriExposed(StrictMode.java:1978)
at android.net.Uri.checkFileUriExposed(Uri.java:2371)
at android.content.Intent.prepareToLeaveProcess(Intent.java:10247)
at android.content.Intent.prepareToLeaveProcess(Intent.java:10201)
at android.app.PendingIntent.getActivity(PendingIntent.java:347)
at android.app.PendingIntent.getActivity(PendingIntent.java:309)
at com.feuerwehrmautern.ffmautern.TimeService.sendNotification(TimeService.java:241)
at com.feuerwehrmautern.ffmautern.TimeService.notificationStuff(TimeService.java:133)
at com.feuerwehrmautern.ffmautern.TimeService.access$100(TimeService.java:41)
at com.feuerwehrmautern.ffmautern.TimeService$TimeDisplayTimerTask$1$2.run(TimeService.java:223)
at java.lang.Thread.run(Thread.java:764)
Service Classs sendNotification
public synchronized void sendNotification(String headtext, String bodytext) {
synchronized(TimeService.class) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(Preferences.HOMEPAGE));
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
if (notificationID > 999) {
notificationID = 1;
}
NotificationManager mNotificationManager;
Notification notification;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = Preferences.ANDROID_CHANNEL_NAME;
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(Preferences.CHANNEL_ID, name, importance);
channel.setDescription(Preferences.CHANNEL_DESCRIPTION);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
mNotificationManager = getSystemService(NotificationManager.class);
mNotificationManager.createNotificationChannel(channel);
notification = new Notification.Builder(TimeService.this, Preferences.CHANNEL_ID)
.setContentIntent(pendingIntent)
.setContentTitle(headtext)
.setContentText(bodytext)
.setSmallIcon(R.drawable.ic_launcher)
.setStyle(new Notification.BigTextStyle().bigText(bodytext))
.build();
} else {
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notification = new Notification.Builder(TimeService.this)
.setContentIntent(pendingIntent)
.setContentTitle(headtext)
.setContentText(bodytext)
.setSmallIcon(R.drawable.ic_launcher)
.setStyle(new Notification.BigTextStyle().bigText(bodytext))
.build();
Uri notificationRingtone = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notificationRingtone);
r.play();
}
mNotificationManager.notify(new Random().nextInt(99999 + 1), notification);
// System.out.println("Notification " + headtext + " notification NR: " + notificationID);
incrementNotificationID();
}
}
Starting from api v24 file: scheme is forbidden. Check this solution.
Related
I recently started learning about Firebase and its capabilities and I am very impressed about how easy it is to implement. But I run into a very funny issue. I tried to use Firebase functions to send notifications to a specific user when data is written to the real-time database. I combed the whole internet to find a solution and still got nothing. Even the logs in the functions tab aren't showing up. I think I am not seeing something. Please help.
index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.sendNotification = functions.database.ref('/Hotel_Complaints/Users/{usersId}/')
.onWrite((change,context) =>{
var user_id = context.params.usersId;
console.log(user_id);
// Grab the current value of what was written to the Realtime Database.
var eventSnapshot = change.after.val();
var device_token = admin.database().ref('/Hotel_Staff/'+user_id+'/device_token').once('value');
return device_token.then(result => {
var token_id = result.val();
console.log(token_id);
var str = eventSnapshot.issue_description;
var payload = {
notification: {
title: eventSnapshot.staff_name,
body: str,
}
};
// Send a message to devices subscribed to the provided topic.
return admin.messaging().sendToDevice(token_id, payload).then(function (response) {
// See the MessagingTopicResponse reference documentation for the
// contents of response.
console.log("Successfully sent message:", response);
return;
})
.catch(function (error) {
console.log("Error sending message:", error);
});
});
});
FirebaseMessagingService.java
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
String info_body = remoteMessage.getNotification().getBody();
String info_title = remoteMessage.getNotification().getTitle();
String click_action = "Home";
showNotification(info_body, info_title, click_action);
}
private void showNotification(String info_body, String info_title, String click_action) {
Intent intent;
switch (click_action) {
case "Home":
intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
break;
default:
intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
break;
}
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
int notificationId = 1;
String channelId = "channel-01";
String channelName = "Channel Name";
String GROUP_KEY_WORK_EMAIL = "com.softwaremongul.reporttrackingsystem";
int importance = NotificationManager.IMPORTANCE_HIGH;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel mChannel = new NotificationChannel(
channelId, channelName, importance);
assert notificationManager != null;
notificationManager.createNotificationChannel(mChannel);
}
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_stat_name)
.setContentTitle(info_title)
.setContentText(info_body)
.setAutoCancel(true)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setGroup(GROUP_KEY_WORK_EMAIL)
.setStyle(new NotificationCompat.BigTextStyle().bigText(info_body));
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntent(intent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
notificationManager.notify(notificationId, mBuilder.build());
}
}
And finally the database
SNAPSHOT
Functions Console Log
I want to just Generate a notification after save Video.
for this i'll try below code :
public void stopRecordingVideo() {
ContentValues values = new ContentValues();
values.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
values.put(MediaStore.MediaColumns.DATA, file.toString());
activity.getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
Toast.makeText(activity, "Video saved: " + file, Toast.LENGTH_SHORT).show();
//Log.v(TAG, "Video saved: " + getVideoFile(context));
Log.v(TAG, "Video saved: " + file);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(activity)
.setSmallIcon(R.drawable.ic_launcher_background) // notification icon
.setContentTitle("Notification!") // title for notification
.setContentText("Hello word") // message for notification
.setAutoCancel(true); // clear notification after click
Intent intent = new Intent(activity, RecorderActivity.class);
PendingIntent pi = PendingIntent.getActivity(activity,0,intent, PendingIntent.FLAG_UPDATE_CURRENT);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mBuilder.setContentIntent(pi);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
} else{
// do something for phones running an SDK before lollipop
}
try{
mMediaRecorder.stop();
mMediaRecorder.release();
}catch(RuntimeException stopException){
//handle cleanup here
}
try {
mSession.stopRepeating();
} catch (CameraAccessException e) {
e.printStackTrace();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
setup2Record();
} else {
finish(); //just blows up anyway.
}
}
Video save perfectly in Storage and Toast msg also show. but only notification not generated please help for this solution.
Solution:
On Android 8.0 (Oreo) you must have something called as a NotificationChannel So try the below implementation:
Step1: Create Notification Channel
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = getString(R.string.channel_name);
String description = getString(R.string.channel_description);
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
Finally: Then your Notification:
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(activity)
.setSmallIcon(R.drawable.ic_launcher_background) // notification icon
.setContentTitle("Notification!") // title for notification
.setContentText("Hello word") // message for notification
.setAutoCancel(true); // clear notification after click
Intent intent = new Intent(activity, RecorderActivity.class);
PendingIntent pi = PendingIntent.getActivity(activity,0,intent, PendingIntent.FLAG_UPDATE_CURRENT);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mBuilder.setContentIntent(pi);
notificationManager.notify(1, mBuilder.build());
Try this, Hope it helps.
I have given my couple of days to solve this issue. My app is getting crash whose android version is 8.1. It is working perfectly fine in Android Version 8.0.
I followed the link mentioned below for the solution and tried many solutions given in this link but my application is not opening.
startForeground fail after upgrade to Android 8.1
I check the Android version in FirebaseMessageService class and create the channel for Oreo version but below given error is showing everytime
android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification: Notification(channel=null pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x40 color=0x00000000 vis=PRIVATE)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:171)
at android.app.ActivityThread.main(ActivityThread.java:6649)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)
Here below is my code. Please help me to rectify this problem
public class MyFirebaseMessagingService extends FirebaseMessagingService
{
private NotificationManager notifManager;
Context mContext;
Random random = new Random();
int m = random.nextInt(9999 - 1000) + 1000;
#Override
public void onMessageReceived(RemoteMessage remoteMessage)
{
sendNotification();
}
public void sendNotification()
{
Intent intent = new Intent(this, Home.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, m /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT);
String channelId = getString(R.string.default_notification_channel_id);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.app_icon)
.setContentTitle("Logipace")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(message))
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
notificationBuilder.setDefaults(Notification.DEFAULT_SOUND);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
NotificationChannel channel = new NotificationChannel(channelId, "LOGIPACE", NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(m /* ID of notification */, notificationBuilder.build());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
}
Below is the code which I used in the onCreate() method of my Activity class.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
// Create channel to show notifications.
String channelId = getString(R.string.default_notification_channel_id);
String channelName = getString(R.string.default_notification_channel_name);
NotificationManager notificationManager =
getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(new NotificationChannel(channelId,
channelName, NotificationManager.IMPORTANCE_LOW));
}
Help me to resolve this issue.
Put your logic inside onMessageReceived: Check Firebase quickstart sample.
public void onMessageReceived(RemoteMessage remoteMessage) {
// Handle data payload of FCM messages.
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
Map<String, String> params = remoteMessage.getData();
JSONObject object = new JSONObject(params);
if (/* Check if data needs to be processed by long running job */ true) {
// For long-running tasks (10 seconds or more) use Firebase Job Dispatcher.
scheduleJob();
} else {
// Handle message within 10 seconds
final String msg = object.getString("msg");
sendNotification(msg);
handleNow();
}
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
}
private void sendNotification(String messageBody) {
Intent intent = new Intent(this, Home.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
String channelId = getString(R.string.default_notification_channel_id);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_stat_ic_notification)
.setContentTitle(getString(R.string.fcm_message))
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
I tried to put PendingIntent Notification in my android project but i had this error it says wrong first argument found android view.View.OnClickListener required android content,context.
Am going to show the code error , the "this" under else notification has its error.
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
Notification noti = new Notification.Builder(this)
this error
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int targetId = view.getId();
if (targetId == R.id.button) {
Toast.makeText(getApplicationContext(), "You have " + numMessages++ + " message", Toast.LENGTH_SHORT).show();
} else {
if (numMessages > 0) {
Intent intent = new Intent();
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
Notification noti = new Notification.Builder(this)
.setTicker("You Have " + numMessages++ + " message")
.setContentTitle("OneDiver")
.setContentText("Content")
.setSmallIcon(R.drawable.ic_od_icon_24dp)
.setContentIntent(pIntent).getNotification();
noti.flags = Notification.FLAG_AUTO_CANCEL;
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, noti);
}
}
If this code is in an activity, say YourActivity.class, you need to replace "this" with "YourActivity.this". Because in an OnClickListener, "this" is referring to the OnClickListener instead of the activity.
My application is receiving GCM notifications. I have different type of notifications and at some point the user can have more than one notification in the status bar. However I need to know which one exactly he clicked on. In the GCM onMessage Im setting them with
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.notify(Integer.parseInt(notification_id), notification);
I need to get that notification_id after the click on the notification. I am pretty sure that's something simple but I couldnt find any info about it.
Here are the onMessage from GCMIntentService
#Override
protected void onMessage(Context context, Intent data) {
String content_title;
String content_text;
String event_id;
String content_info;
String url;
String match_id;
// Message from PHP server
content_title = data.getStringExtra("content_title");
content_text = data.getStringExtra("content_text");
content_info = data.getStringExtra("content_info") + "'";
event_id = data.getStringExtra("event_id");
match_id = data.getStringExtra("match_id");
url = data.getStringExtra("url");
NOTIFICATION_URL = url;
// Open a new activity called GCMMessageView
Intent intent = new Intent(this, GCMMessageView.class);
// Pass data to the new activity
intent.putExtra("message", content_title);
intent.putExtra("url", url);
// Starts the activity on notification click
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Options opts = new Options();
opts.inDither = true;
opts.inScaled = false;
/* Flag for no scalling */
// Create the notification with a notification builder
Notification notification = new NotificationCompat.Builder(this)
.setSmallIcon(drawable_small).setLargeIcon(drawable_big)
.setWhen(System.currentTimeMillis()).setTicker(content_title)
.setContentTitle(content_title).setContentInfo(content_info)
.setContentText(content_text).setContentIntent(pIntent)
.getNotification();
// Remove the notification on click
notification.ledARGB = 0xff00ff00;
notification.ledOnMS = 300;
notification.ledOffMS = 1000;
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
notification.flags |= Notification.FLAG_AUTO_CANCEL;
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.notify(Integer.parseInt(match_id), notification);
try {
Uri notification2 = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(),
notification2);
r.play();
} catch (Exception e) {
}
{
// Wake Android Device when notification received
PowerManager pm = (PowerManager) context
.getSystemService(Context.POWER_SERVICE);
final PowerManager.WakeLock mWakelock = pm.newWakeLock(
PowerManager.FULL_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP, "GCM_PUSH");
mWakelock.acquire();
// Timer before putting Android Device to sleep mode.
Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
mWakelock.release();
}
};
timer.schedule(task, 5000);
}
}
And there`s the on click
String msg;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if (intent.hasExtra("url"))
msg = intent.getExtras().getString("url");
Log.e("URL", msg);
setContentView(R.layout.activity_main);
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(msg
+ "?device_id="
+ GCMIntentService.DEVICE_REGISTRATION_ID.toString()));
startActivity(browserIntent);
// Toast.makeText(getApplicationContext(),
// GCMIntentService.DEVICE_REGISTRATION_ID, Toast.LENGTH_LONG).show();
}
You can go through the below code, You have to ser Notification object as per your need.
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;
Intent intent = new Intent(context, NotificationActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("message", YOUR_DATA);
int requestID = (int) System.currentTimeMillis();
PendingIntent contentIntent = PendingIntent.getActivity(context, requestID,
intent, 0);
if (currentapiVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
notification = new Notification(icon, message, when);
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(when)
.setAutoCancel(true).setContentTitle(appname)
.setContentText(message).build();
notificationManager.notify((int) when, notification);
}
When user click on any notification, it will re-direct to NotificationActivity class.
In this activity, in OnCreate() method you can get your data that is set.
Intent intent = getIntent();
if (intent.hasExtra("message"))
String msg = intent.getExtras().getString("message");
I think it will help.