I'm creating a notification management app and I want to get the contents of notifications which other apps show. currently I use codes like this :
statusBarNotification.getNotification().extras.getString(Notification.EXTRA_TITLE);
and this :
statusBarNotification.getNotification().extras.getString(Notification.EXTRA_TEXT);
to read the title and text of notifications. but after a few hours I couldn't find a way to get the image which comes along with the notification's text. for example a profile picture which is showed in Whatsapp's notification. I know it's not the Small or Large icons, I checked a few times.
So if anyone could help in any way, it would be much appreciated
I assume you use NotificationListenerService to listen to notification from other app.
In you NotificationService class, extract icon ressource id in extra Notification.EXTRA_SMALL_ICON and access the other app package ressources to get the Drawable.
Notification.EXTRA_PICTURE contains the large image sent in the notification :
public class NotificationService extends NotificationListenerService {
Context context;
#Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
#Override
public void onNotificationPosted(StatusBarNotification statusBarNotification) {
// a notification is posted
String pack = statusBarNotification.getPackageName();
Bundle extras = statusBarNotification.getNotification().extras;
int iconId = extras.getInt(Notification.EXTRA_SMALL_ICON);
try {
PackageManager manager = getPackageManager();
Resources resources = manager.getResourcesForApplication(pack);
Drawable icon = resources.getDrawable(iconId);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
if (extras.containsKey(Notification.EXTRA_PICTURE)) {
// this bitmap contain the picture attachment
Bitmap bmp = (Bitmap) extras.get(Notification.EXTRA_PICTURE);
}
}
#Override
public void onNotificationRemoved(StatusBarNotification statusBarNotification) {
//call when notification is removed
}
}
Related
I'm working on an Android app (Java; minSdkVersion 21) and using One Signal to receive notifications. The One Signal notification will send a payload with enough data to build an Episode object which the setNotificationOpened handler will use to navigate to a particular episode in the app.
I'm doing this in MainActivity (the app has this one activity, everything else is fragments):
#Override
protected void onCreate(Bundle savedInstanceState) {
...
OneSignal.setNotificationOpenedHandler(
new OneSignal.OSNotificationOpenedHandler() {
#Override
public void notificationOpened(OSNotificationOpenedResult result) {
OSNotification notification = result.getNotification();
try {
String notificationType = (String) notification.getAdditionalData().get("type");
if (notificationType.equals("episode")) {
Episode episode = NotificationHandler.setUpEpisode(notification.getAdditionalData()); // returns an episode object
Bundle bundle = new Bundle();
bundle.putSerializable("episode", episode);
bundle.putString("title", episode.getName());
navController.navigate(R.id.action_global_episodeFragment, bundle);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
...
This setup works fine when the app is in the background. The user clicks on the notification, the app comes to the foreground and navigates to the appropriate episode. However, when the app is closed and the user clicks on the notification, the app is never launched.
I initially tried to put this handler in the AppController instead of MainActivity but couldn't find a way of navigating since R was not available at this point.
How can I get the above code to also work in cases where the app is closed?
}
I tried to send id of an image from an activity to another activity. But unfortunately stopped. But i couldn't find any solution. This is my main activity. I kept all image id in a class Utils.
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Intent intent=new Intent(MainActivity.this,SendActivity.class);
intent.putExtra("id",Utils.THUMBNAIL_IDS[position]);
startActivity(intent);
}
});
And this is my sendActivity from where i tried to share this image to messenger:
Intent intent = getIntent();
position=getIntent().getExtras().getInt("id");
Now the code to share to messenger:
private void onMessengerButtonClicked() {
// The URI can reference a file://, content://, or android.resource. Here we use
// android.resource for sample purposes.
Uri uri = Uri.parse("android.resource://com.example.amit.bengalistickerfun/drawable/" +
MainActivity.mAdapter.getItem(position));
// Create the parameters for what we want to send to Messenger.
ShareToMessengerParams shareToMessengerParams =
ShareToMessengerParams.newBuilder(uri, "image/jpeg")
.setMetaData("{ \"image\" : \"tree\" }")
.build();
// Sharing from an Activity
MessengerUtils.shareToMessenger(this, 0, shareToMessengerParams);
if (mPicking) {
// If we were launched from Messenger, we call MessengerUtils.finishShareToMessenger to return
// the content to Messenger.
MessengerUtils.finishShareToMessenger(this, shareToMessengerParams);
} else {
// Otherwise, we were launched directly (for example, user clicked the launcher icon). We
// initiate the broadcast flow in Messenger. If Messenger is not installed or Messenger needs
// to be upgraded, this will direct the user to the play store.
MessengerUtils.shareToMessenger(
this,
REQUEST_CODE_SHARE_TO_MESSENGER,
shareToMessengerParams);
}
Can anybody help me?
I would suggest to put try catch block here , so that you can catch the exception. if any
try to observe log-cat and view the errors
try using android inbuilt logging class to see the logs
Post your error logs here ,so that we can see the issue and provide our inputs accordingly.
I need to implement functionality to display application news/announcements for all users.
I will do it rarely so push notification is not for me.
Are there any library or sample, how to implement this fast and easy? Or better will be to implement it in next way:
When application starts - read html file on server, if file was updated after the last attempt - display content of file in popup.
All you need is to load an html, or better, a simple text file containing the notification index like:
in yourdomain.com/notificationnumber.txt
contains
"4"
Check in your applications, probably simply using SharedPreferences for the last displayed version. Then load all notification, for example:
yourdomain.com/notification3.html
yourdomain.com/notification4.html
Display them and store the index number to know which notifcations have been shown to the user. There are no special libraries needed for such a task.
If the announcements are not very frequent, then checking the html file on the server each time the application is launched is good enough.
I feel like it depends on the styling options, which your notifications require:
if no rich styling is needed, you could simply check an XML-file, Text-file or similar for some notification information (Texts, notification coded) as bjornson proposed and then just show an AlertDialog with the specific information.
If you require rich styling, you may need to load the content from a server by utilizing a WebView. So for example your app's frontpage could partly consist of a WebView that in specific cases shows the news, which you intend to present to the user. Please note, that the WebView-technique is/was used by Facebook to update certain parts of their apps without the troubles of releasing a new version in the various App Stores.
I have used an rss-feed from a wordpress blog for this, if there is a new entry, a webview is opened and the new entry is displayed. Instead of displaying the entry, one could just parse the data and display ist (using jdom or other libraries to read the html document) We use IntentService to check once every hour, but you could just do it once on strartup.
So the Service is build like this:
public class UpdateService extends IntentService
{
//INtent Services have a constructer where you have to pass a String to the super class.
public UpdateService()
{
super("UpdateService");
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
#Override
public void onCreate()
{
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
super.onStartCommand(intent, flags, startId);
return Service.START_NOT_STICKY;
}
#Override
public void onDestroy()
{
super.onDestroy();
}
//This method downloads the file from a url and checks if its well formed. It has its own thread because android does not allow access to the internet in the same thread
private void checkfornews()
{
final SAXBuilder builder = new SAXBuilder();
new Thread(new Runnable()
{
public void run()
{
// command line should offer URIs or file names
try
{
Document doc = builder.build(url);
Element root = doc.getRootElement();
readnews(root);
// If there are no well-formedness errors,
// then no exception is thrown
}
// indicates a well-formedness error
catch (JDOMException e)
{
}
catch (IOException e)
{
}
}
}).start();
}
}
//checking for the lateste link, if its a new one we have a new link to show
private void readnews(Element root)
{
List<Element> children = root.getChildren();
Iterator<Element> childrenIterator = children.iterator();
while(childrenIterator.hasNext())
{
Element child = childrenIterator.next();
List<Element> grandchildren = child.getChildren();
Iterator<Element> grandchildrenIterator = grandchildren.iterator();
int counter=0;
while(grandchildrenIterator.hasNext())
{
Element grandchild = grandchildrenIterator.next();
String name = grandchild.getName();
if(name.equals("item") && counter ==0)
{
String title="";
String link="";
String category="";
List<Element> ggc = grandchild.getChildren();
Iterator<Element> ggci= ggc.iterator();
while(ggci.hasNext())
{
Element ggch = ggci.next();
if((ggch.getName()).equals("title"))
{
title=ggch.getText();
}
if(ggch.getName().equals("link"))
{
link=ggch.getText();
}
if(ggch.getName().equals("category"))
{
category=ggch.getText();
}
}
if(category.equals("SoundOfTheCity"))
{
counter++;
Logging.i(TAG, "found some news");
String latestnews = prefs.getString("SOTCNews", "");
if(!(latestnews.equals(link)))
{
Logging.i(TAG, "and its new");
Editor edit = prefs.edit();
edit.putString("SOTCNews", link);
edit.commit();
showNotification(title, link);
}
}
}
}
}
}
private void showNotification(String title, String link)
{
//do what needs to be done with the new data
}
#Override
protected void onHandleIntent(Intent intent)
{
checkfornews();
scheduleNext();
}
private void scheduleNext()
{
int checkingDelay = UPDATE_DELAY;
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR, checkingDelay);
Intent intent = new Intent(this, UpdateService.class);
PendingIntent pendingIntent = PendingIntent.getService(this, UPDATEALARM, intent, 0);
AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
}
}
depending on the form of the html file you have to redo the readnews method and then the showNotification method.
If you don't want to have a backend like wordpress (or use a blog-like feature) you could just store the content of a static webpage instead of the url and if this content changes, use the showNotification method. This would probably do the trick and is a lot less work.
I would like to know the purpose of foloowing two files:
frameworks/base/core/java/android/app/IActivityWatcher.aidl
[description: Callback interface to watch the user's traversal through activities.]
frameworks/base/core/java/android/app/IProcessObserver.aidl
[no description]
I am trying to build an app wherein user can decide which apps can be run during particular period of time (say, from 10am till 4pm).
Is there any way where my app will get notified if one the apps specified by the user starts? This way my app can send kill command (I am assuming that root access is available.)
It seems that IActivityWatcher has been removed beginning with JellyBean, in order to monitor which Activity is running foreground, you can use IProcessObserver as following:
mActivityManagerNative = ActivityManagerNative.getDefault();
if (mActivityManagerNative != null) {
try {
mActivityManagerNative.registerProcessObserver(mProcessObserver);
} catch (RemoteException e) {
Log.e("TAG", "onCreate() RemoteException!");
}
}
private IProcessObserver.Stub mProcessObserver = new IProcessObserver.Stub() {
#Override
public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
doWhatUWantHere();
}
#Override
public void onImportanceChanged(int pid, int uid, int importance) {
}
#Override
public void onProcessDied(int pid, int uid) {
}
};
P.S.
You can use following code snippets to get the package name of foreground running Activity:
private String getForegroundPackage() {
ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List<RecentTaskInfo> taskInfo = am.getRecentTasks(1,
ActivityManager.RECENT_IGNORE_UNAVAILABLE);
return taskInfo.isEmpty()
? null : taskInfo.get(0).baseIntent.getComponent().getPackageName();
}
I'm making an accessibility service that includes notifications, I was wondering if it's possible to get the icon bitmap and "details" of the notifications, I know that the tickertext can provide the "title of the notification" but I would like to access the line that show the "details text" formerly the "getText" method of the contentview field of the notification.
It is possible to get more details and even reconstruct the Notification object. I haven't tested this, but it should work fine.
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
...
if (event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {
Parcelable parcelable = event.getParcelableData();
if (parcelable instanceof Notification) {
// Resource id within the package context of the notifying app.
int icon = ((Notification) parcelable).icon;
Resources res = getPackageManager().getResourcesForApplication(event.getPackageName());
Drawable image = res.getDrawable(icon);
}
}
}