NotificationListenerService in androidTv - android

I am working on an android app which will run in androidTv(currently i am using MiBox for my testing purposes)
The requirement is like i need capture the number active notifications received by the android OS and show it somewhere in the APP.
Service which i've written:
package org.libsdl.app;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Notification;
import android.app.Notification.Action;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import org.haxe.lime.HaxeObject;
public class AndroidNotificationListener extends NotificationListenerService {
private static final int EVENT_UPDATE_CURRENT_NOS = 0;
public static List<StatusBarNotification[]> mCurrentNotifications = new
ArrayList<StatusBarNotification[]>();
public static int mActiveNotificationsCount = 0;
public static StatusBarNotification mPostedNotification;
public static StatusBarNotification mRemovedNotification;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
return super.onBind(intent);
}
#Override
public boolean onUnbind(Intent mIntent) {
return super.onUnbind(mIntent);
}
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
updateCurrentNotifications();
mPostedNotification = sbn;
// Get the text from notification
// CharSequence notificationText = sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT);
// Show a toast with your Notification Text
// Toast.makeText(getApplicationContext(), notificationText, Toast.LENGTH_SHORT).show();
}
#Override
public void onNotificationRemoved(StatusBarNotification sbn) {
updateCurrentNotifications();
mRemovedNotification = sbn;
}
public void onListenerConnected() {
// Add some prints here to check if our service is connected to OS or not?
}
private void updateCurrentNotifications() {
try {
StatusBarNotification[] activeNos = getActiveNotifications();
if (mCurrentNotifications.size() == 0) {
mCurrentNotifications.add(null);
}
mCurrentNotifications.set(0, activeNos);
mActiveNotificationsCount = activeNos.length;
} catch (Exception e) {
System.out.println("Anil : AndroidNotificationListener : Should not be here!!");
e.printStackTrace();
}
}
public static StatusBarNotification[] getCurrentNotifications() {
if (mCurrentNotifications.size() == 0) {
return null;
}
return mCurrentNotifications.get(0);
}
}
AndroidManifest.xml part is:
<service
android:name="org.libsdl.app.AndroidNotificationListener"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
android:enabled="true" >
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
Same service is working for my phone but in my androidTv(MiBox) it is not working.
and as in phone we have settings from where we can enable/disable our app to receive notifications the same option is not available in MiBox.
My MiBox has Android M and my phone has Android N. am i missing something which i should know before running this service in Android service?
So my question is about why this service is not working in androidTv?
any help on this will be much appreciated..

I've found the reason why my dummy app worked on my phone and did not work on miBox.
On my phone, when i installed the dummy app it asked for permission to receive the notification and when i gave the permission it started to receive permission.
On miBox, we do not have any way to give permission to our app to receive notification.
In short, the app was not able to receive the notification on miBox because the app did not have the permission because or listener/app to receive the notification was attached.
and there are no way we can attach the listener for notification to our app in android tvs. But we can do it only when the app is signed as a system app.

if (verifyNotificationPermission()) {
//You have the permission to listen to the System Notification
} else {
//can ask for permission if it not yet granted
// show dialog why you need this permission and if
// user is ok with the permission then call
//openNotificationPermissionPanel
}
fun openNotificationPermissionPanel(){
//Below code will open side panel and will show list of apps and there is a way to unable and disable the Permission
startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));
}
// fun to check if your launcher app has permission or not
fun verifyNotificationPermission(): Boolean? {
val theList = Settings.Secure.getString(
activity.getContentResolver(),
"enabled_notification_listeners"
)
val theListList = theList.split(":").toTypedArray()
val me = ComponentName(activity, NotificationService::class.java).flattenToString()
for (next in theListList) {
if (me == next) {
return true
}
}
return false
}

Related

How to get the battery level in background and announce it?

In my app, I want to get the battery level in the background because I want to announce it in the text to speech when the battery level is low or when the battery is full or at any level. I have used the broadcast receivers and can get the battery level but don't know how to get it in the background.
Anyone can help?
The thing that you want to achieve can be done via intent Service, if you dig in the docs you can find it yourself, here is the link Intent Service, This type of intent can be fired in the background and can be used to perform various simple operations such as yours, because they don't have any interface but rather just operations executed in background.
Also here is a video guide Background Services which you can use for yourself to get battery percentage and announce it after a certain condition
Edit 2:
(Nothing Required in XML as this is a background process/operation)
This is a code to get the battery percentage and announce it using Text to speech in broadcast receiver,
MainActivity.java
package com.example.text_to_speech;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent=new Intent(this,myBackgroundProcess.class);
intent.setAction("BackgroundProcess");
PendingIntent pendingIntent=PendingIntent.getBroadcast(this,0,intent,0);
AlarmManager alarmManger= (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManger.setRepeating(AlarmManager.RTC_WAKEUP,0,10,pendingIntent);//change this time based on your liking which will fire the intent
}
}
customerclass- myBackgroundProcess.java
package com.example.text_to_speech;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.BatteryManager;
import android.speech.tts.TextToSpeech;
import android.util.Log;
import java.util.Locale;
import static android.content.Context.BATTERY_SERVICE;
public class myBackgroundProcess extends BroadcastReceiver {
private TextToSpeech mTTS;
#Override
public void onReceive(Context context, Intent intent) {
mTTS = new TextToSpeech(context.getApplicationContext(), new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status != TextToSpeech.ERROR) {
int result = mTTS.setLanguage(Locale.US);
if (result == TextToSpeech.LANG_MISSING_DATA
|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.e("TTS", "Language not supported");
} else {
BatteryManager bm = (BatteryManager) context.getSystemService(BATTERY_SERVICE);
int batLevel = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
if(batLevel==100 || batLevel<=10 || batLevel==50)
speak(context,batLevel);
}
} else {
Log.e("TTS", "Initialization failed");
}
}
});
}
public void speak(Context context, int batlevel)
{
mTTS.setPitch(10);
mTTS.setSpeechRate(1);
String text=String.valueOf(batlevel);
mTTS.speak(text, TextToSpeech.QUEUE_FLUSH, null);
}
}
In Android Manifest Register the receiver and add intent filter to it as shown below (below application tag)
<receiver android:name=".myBackgroundProcess"
android:enabled="true"
android:exported="true"
>
<intent-filter>
<action android:name="BackgroundProcess"/>
</intent-filter>
</receiver>

Get Incoming call number in Android not working for Android Pie(9.0)

This is the code I used to do my work, but unfortunately It doesn't work for my device with Android Pie(9.0). But It works for device with Android Naugat(7.0). I already enabled the phone permission for the app using device App Settings. Can you give me a solution for this?
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
if(extras!=null){
String state = extras.getString(TelephonyManager.EXTRA_STATE);
if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){
String phoneNo = extras.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
Toast.makeText(context, "You Got A Call From " + phoneNo, Toast.LENGTH_SHORT).show();
}
}
}
}

How to post a notification with no icon but with led enabled?

Hi fellow Android coders !
I'm currently writing an application that uses the new Android 4.3 notification listener to change the notification led color when a notification is received, and am facing a problem, probably due to my lack of knowledge about how notifications work.
So far, it is working quite well. When the user switch off the screen, I create a notification, with a custom led color, and I remove it when the screen is switched ON. My problem is that when the user switch the screen back ON, he can see my notification icon on the status bar for half a second just before it is removed. Not that big of a deal, but as a nit-picker, I can't help but try a way to avoid this ugly behavior. I know that some apps succeed as doing this - LightFlow for example.
My first idea was to play with the priority of the notification and using Notification.PRIORITY_MIN nearly worked : the notification icon is not displayed on the status bar but appears when the bar is expanded.
I unfortunately discovered that notifications with minimum priority doesn't toggle the notification led when the screen is off !
I then tried to create a notification with no icon, but it is not supported by the framework - that's actually a good thing.
And now I'm out of idea.
Can someone help my find a way to create a notification that doesn't appear on the status bar but still toggles the LED on ?
Or maybe should I remove my notification before the screen is actually switched ON but I can't find a way to do this either...
If someone can help me on this one, it would make my day !
Here is the code source of my application :
Main activity :
package com.nightlycommit.coloration;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
Service listener
package com.nightlycommit.coloration;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.service.notification.StatusBarNotification;
/**
* Created by Eric on 08/08/13.
*/
public class NotificationListenerService extends android.service.notification.NotificationListenerService {
private final String TAG = getClass().getSimpleName();
#Override
public void onCreate() {
super.onCreate();
// REGISTER RECEIVER THAT HANDLES SCREEN ON AND SCREEN OFF LOGIC
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenStateReceiver();
registerReceiver(mReceiver, filter);
}
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
String text = "Notification posted !";
}
#Override
public void onNotificationRemoved(StatusBarNotification sbn) {
String text = "Notification removed !";
}
}
Screen state receiver :
package com.nightlycommit.coloration;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
/**
* Created by Eric on 12/08/13.
*/
public class ScreenStateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
String action = intent.getAction();
if (action != null) {
if (action.equals(Intent.ACTION_SCREEN_OFF)) {
Notification.Builder builder = new Notification.Builder(context);
builder.setLights(Color.argb(255,255,0,0), 500, 500);
builder.setContentText("TEST");
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setOngoing(true);
// builder.setPriority(Notification.PRIORITY_MIN);
notificationManager.notify(777, builder.build());
} else if (action.equals(Intent.ACTION_SCREEN_ON)) {
notificationManager.cancel(777);
}
}
}
}
Thanks by advance,
Eric.

Broadcast Receiver onReceive method not called when screen/cpu goes off

I am working on an application that will notify me (by playing a ringtone) that battery level has reached certain level. Level is configurable. For this I have created an activity that starts a service which in turn registers a receiver for ACTION_BATTERY_CHANGED.
MyActivity -> MyService -> MyBrodcastReceiver [ACTION_BATTERY_CHANGED] -> onReceive() -> if(Battery Level <= MyValue) -> play ringtone
Everything works fine as long as screen is on but as soon as phone is locked and screen goes off or CPU sleeps the broadcast receiver’s onReceive method doesn’t get called and when I unlock phone again everything works. I verified this with logging.
Is it that onReceive method for ACTION_BATTERY_CHANGED gets called only when phone screen is on and stops when phone sleeps?
I even tried using Wake Lock in onReceive method but that didn’t work 
[I am testing with ICS (4.0.4)]
import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
public class BatteryMeterService extends Service {
private BatteryStatusReceiver batteryStatusReceiver;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
batteryStatusReceiver = new BatteryStatusReceiver(null);
registerReceiver(batteryStatusReceiver, intentFilter);
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(batteryStatusReceiver);
}
}
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.BatteryManager;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.util.Log;
import android.widget.TextView;
import com.amol.bm.BatteryMeterUtility.NotificationInfo;
public class BatteryStatusReceiver extends BroadcastReceiver {
private BatteryMeterUtility batteryMeterUtility;
public BatteryStatusReceiver() {
super();
}
#Override
public void onReceive(Context context, Intent intent) {
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
float fPct = (level / (float)scale) * 100;
int levelPct = (int)fPct;
boolean prefAlertLowBattery = sharedPrefs.getBoolean("prefAlertLowBattery", true);
if(prefAlertLowBattery) {
String prefAlertLowBatteryValue = sharedPrefs.getString("prefAlertLowBatteryValue", "20");
int lowBatteryValue = Integer.parseInt(prefAlertLowBatteryValue);
if(levelPct <= lowBatteryValue && iStatus != BatteryManager.BATTERY_STATUS_CHARGING) {
notificationInfo.icon = R.drawable.low_battery;
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "BM WakeLook");
wakeLock.acquire();
batteryMeterUtility.playAlertRingtone(alertRingtone);
wakeLock.release();
}
}
}
}
You should give WAKE_LOCK Permission to your service running in background so that even when the phone is Idle or goes off your service keeps on running. hope you got it let me know if unclear
Finally I used Alarm Manager with RTC_WAKEUP to solve this problem. http://developer.android.com/reference/android/app/AlarmManager.html

"Unable to start service Intent" error when starting service from an Activity in Android

I see the following error in DDMS when trying to use a CheckBox on my MyActivity" activity to start a service called "MyService":
W/ActivityManager( 73): Unable to start service Intent { cmp=com.example.android.myprogram/.MyService }: not found
I used the tutorial http://developer.android.com/resources/tutorials/views/hello-formstuff.html and added the provided code to the end of my onCreate() method. I have the classes specified separately in MyActivity.java and MyService.java.
package com.example.android.myprogram;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.CheckBox;
public class MyActivity extends Activity {
private static final String TAG = "MyActivity";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final CheckBox checkbox = (CheckBox) findViewById(R.id.checkbox);
checkbox.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Perform action on clicks, depending on whether it's now checked
if (((CheckBox) v).isChecked()) {
// TODO: Add code to START the service
Log.d(TAG, "startService from checkbox");
startService(new Intent(MyActivity.this, MyService.class));
} else {
// TODO: Add code to STOP the service
Log.d(TAG, "stopService from checkbox");
stopService(new Intent(MyActivity.this, MyService.class));
}
}
});
}
}
My manifest file does have the following in which I've also tried the full namespace, short name, using an intent-filter per another search, etc. I'm not saying what is there is correct. I just left it at a stopping point.
<service android:name=".MyService">
<intent-filter><action android:name="com.example.android.myprogram.MyService"></action>
</intent-filter>
</service>
And lastly, my service which I've decided to break down to it's bare minimum:
package com.example.android.myprogram;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
private static final String TAG = "MyService";
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Log.d(TAG, "onCreate");
//code to execute when the service is first created
}
#Override
public void onDestroy() {
Log.d(TAG, "onDestroy");
//code to execute when the service is shutting down
}
#Override
public void onStart(Intent intent, int startid) {
Log.d(TAG, "onStart");
//code to execute when the service is starting up
}
}
I'm very, very, very new to Java/Android programming and programming in general (but learning) so I'm sure this is user error and probably common sense to everyone else. Any suggestions would be great.
I kept digging around and, as I figured, I was making an obvious rookie error. In AndroidManifest.xml, I had the < service> declaration after < application> instead of nested inside it.
You need not to write intent filter because you are starting service explicitly.
If you are new to android use following link it will be very helpful for you.
It has service example too.
http://saigeethamn.blogspot.com/2009/08/android-developers-tutorial-for.html
see my answer in
Unable to start Service Intent
there's a good example
http://www.websmithing.com/2011/02/01/how-to-update-the-ui-in-an-android-activity-using-data-from-a-background-service/comment-page-1/
clean up the line in your manifest.xml
<intent-filter>
<action android:name="com.example.android.myprogram.MyService">
</action>
</intent-filter>

Categories

Resources