I discovered this battery widget in github https://github.com/onlinux/AndroidBatteryWidget. I want create the same graph that there is in the application. The problem is that this is a widget and the things are a little bit differents. The widget has a class https://github.com/onlinux/AndroidBatteryWidget/blob/master/src/fr/free/onlinux/AndroidBatteryWidget/AndroidBatteryWidgetProvider.java with a service UpdateService class. Thinking i don't need the widget provider, i take only the service and i created a new class called UpdateService.java like this:
package com.mypackage.app;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.IBinder;
import android.util.Log;
import android.widget.RemoteViews;
import android.app.PendingIntent;
import android.app.Service;
public static class UpdateService extends Service {
public final static String TAG = "Bat";
//private static final String TAG = AndroidBatteryWidgetProvider.class.getSimpleName();
public static Boolean debug = true;
BatteryInfo mBI = null;
public void updateWidget(Context context, Intent batteryIntent){
if (debug) Log.i(TAG,"---------- updateWidget");
SimpleDateFormat formatter = new SimpleDateFormat(" HH:mm:ss ");
RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.androidbatterywidget_layout);
updateViews.setTextViewText(R.id.level, "waiting!");
final int status = batteryIntent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN);
final int plugged = batteryIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
final int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
updateViews.setTextViewText(R.id.level, "" + level + " %" );
updateViews.setTextViewText(R.id.time, formatter.format(new Date()));
final int temperature = batteryIntent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1);
String tempString= String.format("%.0f°C", new Float(temperature/10));
if (debug) Log.d(TAG,"BAT:" + tempString + " " + level + "%");
updateViews.setTextViewText(R.id.temperature, tempString );
final int voltage = batteryIntent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1);
Intent i = new Intent(context, AndroidBatteryActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
/* updateViews.setTextViewText(R.id.voltage, "" + voltage + " mV" );
updateViews.setOnClickPendingIntent(R.id.layout ,
PendingIntent.getActivity(context, 0,
new Intent(context, AndroidBatteryActivity.class),Intent.FLAG_ACTIVITY_NEW_TASK));
ComponentName myComponentName = new ComponentName(context, AndroidBatteryWidgetProvider.class);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(myComponentName, updateViews); */
//Second, update database in a thread
new Thread (new Runnable(){
public void run(){
final Context c=getApplicationContext();
DBHelper db = new DBHelper(c);
db.record( level, status, plugged );
db.deleteOldEntries();
db.close();
if (debug) Log.i( TAG, "---------- Add record: " + level + " time: "+ Calendar.getInstance().getTimeInMillis() );
}
}).start();
}
public void handleCommand(Intent intent){
if(mBI == null)
{
mBI = new BatteryInfo(this);
// IntentFilter mIntentFilter = new IntentFilter();
// mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
// registerReceiver(mBI, mIntentFilter);
// After registering mBI, another update is immediately processed.
// So, skip double update processing.
return;
}
//update widget views and database
updateWidget(getApplicationContext(), intent);
}
#Override
public void onStart(Intent intent, int startId) {
handleCommand(intent);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (debug)
Log.d(TAG, "----------------- onStartCommand");
handleCommand(intent);
// The service has to be running otherwise the broadcast ACTION_BATTERY_CHANGED wont be received anymore
// thats why it returns START_STICKY
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
try{
if(mBI != null) {
if (debug)
Log.d(TAG, "----------------- onDestroy: unregisterReceiver(mBI)" );
unregisterReceiver(mBI);
}
}catch(Exception e)
{Log.e(TAG, "", e);}
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
}
and in my MainActivity i created a button if clicked go to graph, so onclick
Intent intent = new Intent(context, UpdateService.class);
context.startService(intent);
Now, what happen is that i can see from the logCat the receiver and the service goes well. But clicking the button in the application nothing happen. The app exit and none activity starts. In the Manifest i wrote
<service android:name=".UpdateService" />
<receiver android:name=".BatteryInfo" android:label="BatteryInfo">
<intent-filter>
<action android:name="android.intent.action.BATTERY_CHANGED" />
</intent-filter>
</receiver>
<activity
android:name=".AndroidBatteryActivity"
android:label="#string/app_name" >
</activity>
<activity android:name="org.achartengine.GraphicalActivity" >
</activity>
EDIT: I try to edit a little bit the code and now aadding this part
Intent i = new Intent(context, AndroidBatteryActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
Start the Activity AndroidBatteryActivity but is all black and nothing appear. If The AndroidBatteryActivity is this one:
public class AndroidBatteryActivity extends Activity {
public Intent intent ;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
intent = new BatteryChart().execute(this);
startActivity(intent);
finish();
}
public void myfinish(){
Log.i("AndroidBatteryActivity", "finish");
finish();
}
}
and BatteryChart is the class with graph with achartengine.
. How can i adapt the code in mine? How can i start the graph? What i have to change? Thanks
Its possible that you may have figured out the answer by now, but anyways here is how to do it :
public class MyBatteryReceiver extends Service {
private int batterylevel = 0;
private String batteryStatus = "";
public final static String TAG = "Bat";
public static Boolean debug = true;
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
batterylevel = intent.getIntExtra("level", 0);
final int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
final int status = intent.getIntExtra("status",
BatteryManager.BATTERY_STATUS_UNKNOWN);
String strStatus;
if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
batteryStatus = "Charging";
} else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) {
batteryStatus = "Discharging";
} else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING) {
batteryStatus = "Not charging";
} else if (status == BatteryManager.BATTERY_STATUS_FULL) {
batteryStatus = "Full";
} else {
batteryStatus = "";
}
new Thread (new Runnable(){
public void run(){
final Context c=getApplicationContext();
DBHelper db = new DBHelper(c);
db.record( batterylevel, status, plugged );
db.deleteOldEntries();
db.close();
if (debug) Log.i( TAG, "---------- Add record: " + batterylevel + " time: "+ Calendar.getInstance().getTimeInMillis() );
}
}).start();
}
}
};
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(myReceiver, intentFilter);
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unregisterReceiver(myReceiver);
}
}
This is your Activity
public class AndroidBatteryActivity extends Activity {
public Intent intent ;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_battery_chart);
intent = new BatteryChart().execute(this);
startActivity(intent);
finish();
}
public void myfinish(){
Log.i("AndroidBatteryActivity", "finish");
finish();
}
}
You need to Start the service from where you prefer
Intent intent = new
Intent(YourActivity.this,yourpackagename.MyBatteryReceiver.class);
YourActivity.this.startService(intent);
And this tag in Manifest
<service
android:name="yourpackagename.MyBatteryReceiver"
android:label="MyBatteryReceiver" >
<intent-filter>
<action android:name="android.intent.action.BATTERY_CHANGED" />
</intent-filter>
</service>
Just change the class name from MyBatteryReceiver to UpdateService for your code
Related
I am building an android app with eclipse and I have a widget that displays a listview that has a button in each for for capturing row item and saving to sqlite db. I am trying to figure out how to update the list whenever the user updates the list in the main app or if they click the refresh imageview I have on the widget. Below are the following classes/files used for the widget. I tried searching everywhere and all the solutions don't seem to work for a listview widget with a service. Any help is greatly appreciated!
WidgetProvider.class
public class WidgetProvider extends AppWidgetProvider {
DBHelper pdh;
public static final String ACTION_TOAST = "actionToast";
public static final String ACTION_BUTTON = "actionButton";
public static final String EXTRA_ITEM_POSITION = "extraItemPosition";
SimpleDateFormat sdfFinal = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat stf = new SimpleDateFormat("HH:mm");
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int N = appWidgetIds.length;
for (int i = 0; i < N; ++i) {
RemoteViews remoteViews = updateWidgetListView(context, appWidgetIds[i]);
Intent intent = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
Intent clickIntentRefresh = new Intent(context, WidgetProvider.class);
clickIntentRefresh.setAction(ACTION_BUTTON);
PendingIntent clickPendingIntentRefresh = PendingIntent.getBroadcast(context, 0, clickIntentRefresh, 0);
Intent clickIntent = new Intent(context, WidgetProvider.class);
clickIntent.setAction(ACTION_TOAST);
PendingIntent clickPendingIntent = PendingIntent.getBroadcast(context, 0, clickIntent, 0);
remoteViews.setOnClickPendingIntent(R.id.ivRefresh,clickPendingIntentRefresh);
remoteViews.setOnClickPendingIntent(R.id.button1, pendingIntent);
remoteViews.setPendingIntentTemplate(R.id.listViewWidget, clickPendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (ACTION_TOAST.equals(intent.getAction())) {
String s = intent.getStringExtra(EXTRA_ITEM_POSITION);
pdh = new DBHelper(context);
Calendar cal = Calendar.getInstance();
String strDateStamp = sdfFinal.format(cal.getTime());
String strTimeStamp = stf.format(cal.getTime());
pdh.insertRecord(s, null, strDateStamp, strTimeStamp);
Toast.makeText(context, "Saved!", Toast.LENGTH_SHORT).show();
} else if (ACTION_BUTTON.equals(intent.getAction())) {
Toast.makeText(context, "Refresh Clicked!", Toast.LENGTH_SHORT).show();
}
}
private RemoteViews updateWidgetListView(Context context, int appWidgetId) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
Intent svcIntent = new Intent(context, WidgetService.class);
svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
svcIntent.setData(Uri.parse(svcIntent.toUri(Intent.URI_INTENT_SCHEME)));
remoteViews.setRemoteAdapter(R.id.listViewWidget, svcIntent);
remoteViews.setEmptyView(R.id.listViewWidget, R.id.empty_view);
return remoteViews;
}
}
WidgetService.class
public class WidgetService extends RemoteViewsService {
/*
* So pretty simple just defining the Adapter of the listview here Adapter is
* ListProvider
*/
#Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
return (new ListProvider(this.getApplicationContext(), intent));
}
}
ListProvider.class
public class ListProvider implements RemoteViewsFactory {
public static final String EXTRA_ITEM_POSITION = "extraItemPosition";
private ArrayList<ListItem> listItemList = new ArrayList<ListItem>();
private Context context = null;
private Intent intent;
public ListProvider(Context context, Intent intent) {
this.intent = intent;
this.context = context;
intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
populateListItem();
}
private void populateListItem() {
try {
DBHelper pdh = new DBHelper(context);
listItemList.clear();
SQLiteDatabase db = pdh.getReadableDatabase();
String[] columns = new String[] { "Categories" };
Cursor c = db.query("tblCategories", columns, null, null, null, null, "Categories asc");
int categoriesInt = c.getColumnIndex("Categories");
int totalCategories = c.getCount();
for (int i = 0; i < totalCategories; i++) {
c.moveToPosition(i);
ListItem listItem = new ListItem();
listItem.heading = c.getString(categoriesInt);
listItemList.add(listItem);
}
c.close();
db.close();
pdh.close();
} catch (Exception ex) {
}
}
#Override
public int getCount() {
return listItemList.size();
}
#Override
public long getItemId(int position) {
return position;
}
/*
* Similar to getView of Adapter where instead of View we return RemoteViews
*
*/
#Override
public RemoteViews getViewAt(int position) {
try {
final RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.list_row);
ListItem listItem = (ListItem) listItemList.get(position);
remoteView.setTextViewText(R.id.heading, listItem.heading);
Intent fillIntent = new Intent();
fillIntent.putExtra(EXTRA_ITEM_POSITION, listItem.heading);
remoteView.setOnClickFillInIntent(R.id.button1, fillIntent);
return remoteView;
} catch (Exception ex) {
return null;
}
}
#Override
public RemoteViews getLoadingView() {
// TODO Auto-generated method stub
return null;
}
#Override
public int getViewTypeCount() {
// TODO Auto-generated method stub
return 1;
}
#Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
}
#Override
public void onDataSetChanged() {
// TODO Auto-generated method stub
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
}
}
ListItem.class
public class ListItem {
public String heading;
}
AndroidManifest.xml
<receiver android:name=".WidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/widgetinfo" />
</receiver>
<service
android:name=".WidgetService"
android:permission="android.permission.BIND_REMOTEVIEWS" />
i need to start a service whenever the user wants, its the same service with only different input data. I tried with workmanager and using threads libraries, its important to say that is a long running task. Down below is my code
MainActivity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void startThread(View view){
Value1 = findViewById(R.id.Value1);
Value2 = findViewById(R.id.Value2);
String value1 = Value1.getText().toString();
String Value2 = Value2.getText().toString();
Intent service = new Intent(this, servicio.class);
service.putExtra("value1", value1);
service.putExtra("value2", value2);
startService(service);
service file
public class servicio extends Service {
private static final String TAG = "service";
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String rapida = intent.getStringExtra("value1");
String lenta = intent.getStringExtra("value2");
int value = Integer.parseInt(rapida);
int to = Integer.parseInt(lenta);
for (int i = value; i<to; i++){
Log.d(TAG, "number: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Intent notificationintent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationintent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Counting")
.setContentText("from" + rapida + "to" + lenta)
.setSmallIcon(R.drawable.ic_android)
.setContentIntent(pendingIntent)
.build();
startForeground(new Random().nextInt(), notification);
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
i need to make to run multiple of this at the same time no matter with what.
I am developing android app which work as battery indicator, open activity when battery low or full.
It works fine when i call finish() in Main activity from onCreate event after start of service.
but when i comment finish method it open activity multiple times, which i open from BroadCast receiver.
Here is MainActivity Code:
public class Main extends Activity {
private MyService service;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if (service == null) {
Intent i = new Intent(this, MyService.class);
startService(i);
}
finish();
}}
Here is my service code:
I think i am doing something wrong when i start Activity.
At line
getApplication().startActivity(intent);
Complete Service Code is:
public class MyService extends Service{
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("MyService", "onStartCommand");
// do not receive all available system information (it is a filter!)
final IntentFilter battChangeFilter = new IntentFilter(
Intent.ACTION_BATTERY_CHANGED);
// register our receiver
this.registerReceiver(this.batteryChangeReceiver, battChangeFilter);
return super.onStartCommand(intent, flags, startId);
}
private final BroadcastReceiver batteryChangeReceiver = new BroadcastReceiver() {
#Override
public void onReceive(final Context context, final Intent intent) {
checkBatteryLevel(intent);
}
};
private void checkBatteryLevel(Intent batteryChangeIntent) {
// some calculations
final int currLevel = batteryChangeIntent.getIntExtra(
BatteryManager.EXTRA_LEVEL, -1);
final int maxLevel = batteryChangeIntent.getIntExtra(
BatteryManager.EXTRA_SCALE, -1);
final int percentage = (int) Math.round((currLevel * 100.0) / maxLevel);
if(percentage==100)
{
Intent intent = new Intent(getBaseContext(), Last.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(intent);
}
if(percentage==15)
{
Intent intent = new Intent(getBaseContext(), Last.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(intent);
}
}}
And this is my last "Last.cs" activity which is opening multiple time.
but it works fine when i call finish() into Main Activity.
public class Last extends Activity {
Button btnCancel;
Uri notification;
Ringtone r;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_last);
notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
btnCancel = (Button) findViewById(R.id.stopsound);
btnCancel.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
r.stop();
}
});
} }
Make your Last activity launchMode as singleTask in Manifest
<activity
android:name=".Last"
android:configChanges="orientation|screenSize"
android:launchMode="singleTask"
>
</activity>
I have found this Serial Port example:
MainActivity.java
package com.felhr.serialportexample;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.lang.ref.WeakReference;
import java.util.Set;
public class MainActivity extends AppCompatActivity {
/*
* Notifications from UsbService will be received here.
*/
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case UsbService.ACTION_USB_PERMISSION_GRANTED: // USB PERMISSION GRANTED
Toast.makeText(context, "USB Ready", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_USB_PERMISSION_NOT_GRANTED: // USB PERMISSION NOT GRANTED
Toast.makeText(context, "USB Permission not granted", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_NO_USB: // NO USB CONNECTED
Toast.makeText(context, "No USB connected", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_USB_DISCONNECTED: // USB DISCONNECTED
Toast.makeText(context, "USB disconnected", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_USB_NOT_SUPPORTED: // USB NOT SUPPORTED
Toast.makeText(context, "USB device not supported", Toast.LENGTH_SHORT).show();
break;
}
}
};
private UsbService usbService;
private TextView display;
private EditText editText;
private MyHandler mHandler;
private final ServiceConnection usbConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
usbService = ((UsbService.UsbBinder) arg1).getService();
usbService.setHandler(mHandler);
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
usbService = null;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHandler = new MyHandler(this);
display = (TextView) findViewById(R.id.textView1);
editText = (EditText) findViewById(R.id.editText1);
Button sendButton = (Button) findViewById(R.id.buttonSend);
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!editText.getText().toString().equals("")) {
String data = editText.getText().toString();
if (usbService != null) { // if UsbService was correctly binded, Send data
display.append(data);
usbService.write(data.getBytes());
}
}
}
});
}
#Override
public void onResume() {
super.onResume();
setFilters(); // Start listening notifications from UsbService
startService(UsbService.class, usbConnection, null); // Start UsbService(if it was not started before) and Bind it
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(mUsbReceiver);
unbindService(usbConnection);
}
private void startService(Class<?> service, ServiceConnection serviceConnection, Bundle extras) {
if (!UsbService.SERVICE_CONNECTED) {
Intent startService = new Intent(this, service);
if (extras != null && !extras.isEmpty()) {
Set<String> keys = extras.keySet();
for (String key : keys) {
String extra = extras.getString(key);
startService.putExtra(key, extra);
}
}
startService(startService);
}
Intent bindingIntent = new Intent(this, service);
bindService(bindingIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}
private void setFilters() {
IntentFilter filter = new IntentFilter();
filter.addAction(UsbService.ACTION_USB_PERMISSION_GRANTED);
filter.addAction(UsbService.ACTION_NO_USB);
filter.addAction(UsbService.ACTION_USB_DISCONNECTED);
filter.addAction(UsbService.ACTION_USB_NOT_SUPPORTED);
filter.addAction(UsbService.ACTION_USB_PERMISSION_NOT_GRANTED);
registerReceiver(mUsbReceiver, filter);
}
/*
* This handler will be passed to UsbService. Data received from serial port is displayed through this handler
*/
private static class MyHandler extends Handler {
private final WeakReference<MainActivity> mActivity;
public MyHandler(MainActivity activity) {
mActivity = new WeakReference<>(activity);
}
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case UsbService.MESSAGE_FROM_SERIAL_PORT:
String data = (String) msg.obj;
mActivity.get().display.append(data);
break;
}
}
}
}
and UsbService.java
package com.felhr.serialportexample;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import com.felhr.usbserial.CDCSerialDevice;
import com.felhr.usbserial.UsbSerialDevice;
import com.felhr.usbserial.UsbSerialInterface;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
public class UsbService extends Service {
public static final String ACTION_USB_READY = "com.felhr.connectivityservices.USB_READY";
public static final String ACTION_USB_ATTACHED = "android.hardware.usb.action.USB_DEVICE_ATTACHED";
public static final String ACTION_USB_DETACHED = "android.hardware.usb.action.USB_DEVICE_DETACHED";
public static final String ACTION_USB_NOT_SUPPORTED = "com.felhr.usbservice.USB_NOT_SUPPORTED";
public static final String ACTION_NO_USB = "com.felhr.usbservice.NO_USB";
public static final String ACTION_USB_PERMISSION_GRANTED = "com.felhr.usbservice.USB_PERMISSION_GRANTED";
public static final String ACTION_USB_PERMISSION_NOT_GRANTED = "com.felhr.usbservice.USB_PERMISSION_NOT_GRANTED";
public static final String ACTION_USB_DISCONNECTED = "com.felhr.usbservice.USB_DISCONNECTED";
public static final String ACTION_CDC_DRIVER_NOT_WORKING = "com.felhr.connectivityservices.ACTION_CDC_DRIVER_NOT_WORKING";
public static final String ACTION_USB_DEVICE_NOT_WORKING = "com.felhr.connectivityservices.ACTION_USB_DEVICE_NOT_WORKING";
public static final int MESSAGE_FROM_SERIAL_PORT = 0;
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private static final int BAUD_RATE = 9600; // BaudRate. Change this value if you need
public static boolean SERVICE_CONNECTED = false;
private IBinder binder = new UsbBinder();
private Context context;
private Handler mHandler;
private UsbManager usbManager;
private UsbDevice device;
private UsbDeviceConnection connection;
private UsbSerialDevice serialPort;
private boolean serialPortConnected;
/*
* Data received from serial port will be received here. Just populate onReceivedData with your code
* In this particular example. byte stream is converted to String and send to UI thread to
* be treated there.
*/
private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {
#Override
public void onReceivedData(byte[] arg0) {
try {
String data = new String(arg0, "UTF-8");
if (mHandler != null)
mHandler.obtainMessage(MESSAGE_FROM_SERIAL_PORT, data).sendToTarget();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
};
/*
* Different notifications from OS will be received here (USB attached, detached, permission responses...)
* About BroadcastReceiver: http://developer.android.com/reference/android/content/BroadcastReceiver.html
*/
private final BroadcastReceiver usbReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context arg0, Intent arg1) {
if (arg1.getAction().equals(ACTION_USB_PERMISSION)) {
boolean granted = arg1.getExtras().getBoolean(UsbManager.EXTRA_PERMISSION_GRANTED);
if (granted) // User accepted our USB connection. Try to open the device as a serial port
{
Intent intent = new Intent(ACTION_USB_PERMISSION_GRANTED);
arg0.sendBroadcast(intent);
connection = usbManager.openDevice(device);
serialPortConnected = true;
new ConnectionThread().run();
} else // User not accepted our USB connection. Send an Intent to the Main Activity
{
Intent intent = new Intent(ACTION_USB_PERMISSION_NOT_GRANTED);
arg0.sendBroadcast(intent);
}
} else if (arg1.getAction().equals(ACTION_USB_ATTACHED)) {
if (!serialPortConnected)
findSerialPortDevice(); // A USB device has been attached. Try to open it as a Serial port
} else if (arg1.getAction().equals(ACTION_USB_DETACHED)) {
// Usb device was disconnected. send an intent to the Main Activity
Intent intent = new Intent(ACTION_USB_DISCONNECTED);
arg0.sendBroadcast(intent);
serialPortConnected = false;
serialPort.close();
}
}
};
/*
* onCreate will be executed when service is started. It configures an IntentFilter to listen for
* incoming Intents (USB ATTACHED, USB DETACHED...) and it tries to open a serial port.
*/
#Override
public void onCreate() {
this.context = this;
serialPortConnected = false;
UsbService.SERVICE_CONNECTED = true;
setFilter();
usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
findSerialPortDevice();
}
/* MUST READ about services
* http://developer.android.com/guide/components/services.html
* http://developer.android.com/guide/components/bound-services.html
*/
#Override
public IBinder onBind(Intent intent) {
return binder;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
UsbService.SERVICE_CONNECTED = false;
}
/*
* This function will be called from MainActivity to write data through Serial Port
*/
public void write(byte[] data) {
if (serialPort != null)
serialPort.write(data);
}
public void setHandler(Handler mHandler) {
this.mHandler = mHandler;
}
private void findSerialPortDevice() {
// This snippet will try to open the first encountered usb device connected, excluding usb root hubs
HashMap<String, UsbDevice> usbDevices = usbManager.getDeviceList();
if (!usbDevices.isEmpty()) {
boolean keep = true;
for (Map.Entry<String, UsbDevice> entry : usbDevices.entrySet()) {
device = entry.getValue();
int deviceVID = device.getVendorId();
int devicePID = device.getProductId();
if (deviceVID != 0x1d6b && (devicePID != 0x0001 || devicePID != 0x0002 || devicePID != 0x0003)) {
// There is a device connected to our Android device. Try to open it as a Serial Port.
requestUserPermission();
keep = false;
} else {
connection = null;
device = null;
}
if (!keep)
break;
}
if (!keep) {
// There is no USB devices connected (but usb host were listed). Send an intent to MainActivity.
Intent intent = new Intent(ACTION_NO_USB);
sendBroadcast(intent);
}
} else {
// There is no USB devices connected. Send an intent to MainActivity
Intent intent = new Intent(ACTION_NO_USB);
sendBroadcast(intent);
}
}
private void setFilter() {
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_USB_PERMISSION);
filter.addAction(ACTION_USB_DETACHED);
filter.addAction(ACTION_USB_ATTACHED);
registerReceiver(usbReceiver, filter);
}
/*
* Request user permission. The response will be received in the BroadcastReceiver
*/
private void requestUserPermission() {
PendingIntent mPendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
usbManager.requestPermission(device, mPendingIntent);
}
public class UsbBinder extends Binder {
public UsbService getService() {
return UsbService.this;
}
}
/*
* A simple thread to open a serial port.
* Although it should be a fast operation. moving usb operations away from UI thread is a good thing.
*/
private class ConnectionThread extends Thread {
#Override
public void run() {
serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection);
if (serialPort != null) {
if (serialPort.open()) {
serialPort.setBaudRate(BAUD_RATE);
serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
serialPort.setParity(UsbSerialInterface.PARITY_NONE);
serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
serialPort.read(mCallback);
// Everything went as expected. Send an intent to MainActivity
Intent intent = new Intent(ACTION_USB_READY);
context.sendBroadcast(intent);
} else {
// Serial port could not be opened, maybe an I/O error or if CDC driver was chosen, it does not really fit
// Send an Intent to Main Activity
if (serialPort instanceof CDCSerialDevice) {
Intent intent = new Intent(ACTION_CDC_DRIVER_NOT_WORKING);
context.sendBroadcast(intent);
} else {
Intent intent = new Intent(ACTION_USB_DEVICE_NOT_WORKING);
context.sendBroadcast(intent);
}
}
} else {
// No driver for given device, even generic CDC driver could not be loaded
Intent intent = new Intent(ACTION_USB_NOT_SUPPORTED);
context.sendBroadcast(intent);
}
}
}
}
In this app you can type a string, send it and it will print it. What I want to do is send that input through an FTDI to a pc where it is visible in PuTTy. I'm new to this so I have no idea where in the code this has to be changed.
It seeems very old but I solved that by adding in Handle message handler case UsbService.SYNC_READ:
and actually i found that data coming from the serial.
I'm trying to use MediaSessionCompat in order to add lock screen player controls and meta data for my app. Everything I tried doesn't work. The lock screen doesn't show any controls or meta data while playing. Please see my current code below and any help is appreciated.
StreamService.java:
public class StreamService extends Service implements MediaPlayer.OnCuePointReceivedListener, MediaPlayer.OnStateChangedListener,
MediaPlayer.OnInfoListener, AudioManager.OnAudioFocusChangeListener {
private WifiManager.WifiLock wifiLock;
private static String LOG_TAG = "StreamService";
public static final String BROADCAST_PLAYER_STATE = "com.test.BROADCAST_PLAYER_STATE";
public static final String BROADCAST_PLAYER_META = "com.test.BROADCAST_PLAYER_META";
public static final String BROADCAST_PLAYER_ALBUM = "com.test.BROADCAST_PLAYER_ALBUM";
public static final int NOTIFICATION_ID = 999999;
private MediaSessionCompat mediaSession;
private boolean audioInterrupted = false;
public StreamService() {
}
#Override
public void onCreate(){
super.onCreate();
setupMediaPlayer();
setupMediaSession();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public boolean onUnbind(Intent intent){
releasePlayer();
return false;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
private void setupMediaPlayer() {
// Recreate player
Bundle playerSettings = (BrandedApplication.getContext().getmTritonPlayer() == null) ? null : BrandedApplication.getContext().getmTritonPlayer().getSettings();
Bundle inputSettings = createPlayerSettings();
if (!Utility.bundleEquals(inputSettings, playerSettings)) {
releasePlayer();
createPlayer(inputSettings);
}
// Start the playback
play();
}
private void setupMediaSession() {
ComponentName receiver = new ComponentName(getPackageName(), RemoteReceiver.class.getName());
mediaSession = new MediaSessionCompat(this, "StreamService", receiver, null);
mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
.setState(PlaybackStateCompat.STATE_PAUSED, 0, 0)
.setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PAUSE)
.build());
mediaSession.setMetadata(new MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, "Test Artist")
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, "Test Album")
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, "Test Track Name")
.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, 10000)
.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART,
BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
//.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, "Test Artist")
.build());
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.requestAudioFocus(new AudioManager.OnAudioFocusChangeListener() {
#Override
public void onAudioFocusChange(int focusChange) {
// Ignore
}
}, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
mediaSession.setActive(true);
}
synchronized private void play() {
audioInterrupted = false;
BrandedApplication.getContext().getmTritonPlayer().play();
if(wifiLock != null) {
wifiLock.acquire();
}
if(mediaSession != null) {
mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
.setState(PlaybackStateCompat.STATE_PLAYING, 0, 1.0f)
.setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE).build());
}
}
synchronized private void stop() {
BrandedApplication.getContext().getmTritonPlayer().stop();
if(wifiLock != null) {
wifiLock.release();
}
if(mediaSession != null) {
mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
.setState(PlaybackStateCompat.STATE_PAUSED, 0, 0.0f)
.setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE).build());
}
}
private void createPlayer(Bundle settings)
{
BrandedApplication.getContext().setmTritonPlayer(new TritonPlayer(this, settings));
wifiLock = ((WifiManager) getSystemService(Context.WIFI_SERVICE))
.createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock");
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
BrandedApplication.getContext().getmTritonPlayer().setOnCuePointReceivedListener(this);
BrandedApplication.getContext().getmTritonPlayer().setOnInfoListener(this);
BrandedApplication.getContext().getmTritonPlayer().setOnStateChangedListener(this);
}
protected void releasePlayer() {
if (BrandedApplication.getContext().getmTritonPlayer() != null) {
if(BrandedApplication.getContext().isPlaying()) {
stop();
}
BrandedApplication.getContext().getmTritonPlayer().release();
BrandedApplication.getContext().setmTritonPlayer(null);
}
stopForeground(true);
}
protected Bundle createPlayerSettings() {
// Player Settings
Bundle settings = new Bundle();
// AAC
settings.putString(TritonPlayer.SETTINGS_STATION_MOUNT, getResources().getString(R.string.station_stream_mount) + "AAC");
// MP3
//settings.putString(TritonPlayer.SETTINGS_STATION_MOUNT, mountID);
settings.putString(TritonPlayer.SETTINGS_STATION_BROADCASTER, getResources().getString(R.string.app_name));
settings.putString(TritonPlayer.SETTINGS_STATION_NAME, getResources().getString(R.string.app_name));
return settings;
}
#Override
public void onCuePointReceived(MediaPlayer mediaPlayer, Bundle bundle) {
//System.out.println("TRITON PLAYER BUNDLE " + bundle);
String trackName = "";
String artistName = "";
if(bundle != null) {
if(bundle.containsKey("cue_title") && bundle.containsKey("track_artist_name")) {
if (!bundle.getString("cue_title").isEmpty()) {
trackName = bundle.getString("cue_title");
}
if (!bundle.getString("track_artist_name").isEmpty()) {
artistName = bundle.getString("track_artist_name");
}
}
}
// broadcast out the meta data
Intent i = new Intent(BROADCAST_PLAYER_META);
i.putExtra("trackName", trackName);
i.putExtra("artistName", artistName);
sendBroadcast(i);
// send notification and start as foreground service
PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(), MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
Bitmap icon = BitmapFactory.decodeResource(getResources(),
R.drawable.logo);
String tickerString = "";
String contentString = "Playing";
if(!artistName.isEmpty() && !trackName.isEmpty()) {
tickerString = artistName + " - " + trackName;
contentString += ": " + artistName + " - " + trackName;
}
Intent pauseIntent = new Intent(BROADCAST_PLAYER_PAUSE);
PendingIntent pausePendingIntent = PendingIntent.getBroadcast(this, 0, pauseIntent, 0);
NotificationCompat.Builder notification = new NotificationCompat.Builder(this)
.setContentTitle(getResources().getString(R.string.app_name))
.setTicker(tickerString)
.setContentText(contentString)
.setSmallIcon(R.drawable.ic_launcher)
//.setAutoCancel(true)
//.setLargeIcon(
// Bitmap.createScaledBitmap(icon, 128, 128, false))
.addAction(R.drawable.ic_media_pause, "Pause", pausePendingIntent)
.setContentIntent(pi)
.setStyle(new android.support.v7.app.NotificationCompat.MediaStyle()
//.setShowActionsInCompactView(0)
.setMediaSession(mediaSession.getSessionToken()))
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setOngoing(true);
//notification.setPriority(Notification.PRIORITY_MIN);
notification.setPriority(Notification.PRIORITY_DEFAULT);
startForeground(NOTIFICATION_ID, notification.build());
}
#Override
public void onInfo(MediaPlayer mediaPlayer, int i, int i1) {
}
#Override
public void onStateChanged(MediaPlayer mediaPlayer, int state) {
Log.i(LOG_TAG, "onStateChanged: " + TritonPlayer.debugStateToStr(state));
// broadcast out the player state
Intent i = new Intent(BROADCAST_PLAYER_STATE);
i.putExtra("state", state);
sendBroadcast(i);
}
#Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
// resume playback
System.out.println("AUDIO FOCUS GAIN");
if(audioInterrupted) {
audioInterrupted = false;
if (BrandedApplication.getContext().getmTritonPlayer() == null) {
setupMediaPlayer();
} else if (!BrandedApplication.getContext().isPlaying()) {
setupMediaPlayer();
}
}
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
case AudioManager.AUDIOFOCUS_LOSS:
System.out.println("AUDIO FOCUS LOSS");
// Lost focus for an unbounded amount of time: stop playback and release media player
if (BrandedApplication.getContext().isPlaying()) {
audioInterrupted = true;
releasePlayer();
}
break;
}
}
#Override
public void onDestroy() {
System.out.println("SERVICE STOPPED");
releasePlayer();
mediaSession.release();
}
}
And here's RemoteReceiver.java:
public class RemoteReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
final KeyEvent event = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (event != null && event.getAction() == KeyEvent.ACTION_DOWN) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
context.startService(new Intent(context, StreamService.class));
break;
}
}
}
}
}
Okay, from the additional information you provided, I believe I know what the issue is. In Android 5.0 Lock Screen Controls were removed. They are now implemented via the Notification API. So try adding the following to your notification builder.
notification.setStyle(new NotificationCompat.MediaStyle()
.setShowActionsInCompactView(0)
.setMediaSession(mediaSession));
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
That should place it on your lock screen. I would also suggest changing the Notification.PRIORITY_DEFAULT as well as include an action to your notification otherwise you won't be able to control the playback.
I know this post is late but if anyone is still facing the issue.This will show up in your lock screen also.
Here is the code for notification builder class-
import android.annotation.SuppressLint;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.media.MediaPlayer;
import android.media.session.MediaSessionManager;
import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.RequiresApi;
import android.support.v4.app.NotificationCompat;
import android.support.v4.media.session.MediaControllerCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.util.Log;
import org.json.JSONException;
public class MediaPlayerService extends Service {
private static final String CHANNEL_ID = "my_channel_01";
public static final String ACTION_PLAY = "action_play";
public static final String ACTION_PAUSE = "action_pause";
public static final String ACTION_NEXT = "action_next";
public static final String ACTION_PREVIOUS = "action_previous";
public static final String ACTION_STOP = "action_stop";
public static final String ACTION_NOTHING = "action_previous";
private NotificationManager notificationManager;
NotificationManager mNotificationManager;
private MediaPlayer mMediaPlayer;
private MediaSessionManager mManager;
private MediaSessionCompat mSession;
private MediaControllerCompat mController;
private MediaPlayerService mService;
String title = null;
String description = null;
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void handleIntent(Intent intent) {
if (intent == null || intent.getAction() == null)
return;
String action = intent.getAction();
if (action.equalsIgnoreCase(ACTION_PLAY)) {
mController.getTransportControls().play();
} else if (action.equalsIgnoreCase(ACTION_PAUSE)) {
mController.getTransportControls().pause();
} else if (action.equalsIgnoreCase(ACTION_PREVIOUS)) {
mController.getTransportControls().skipToPrevious();
} else if (action.equalsIgnoreCase(ACTION_NEXT)) {
mController.getTransportControls().skipToNext();
} else if (action.equalsIgnoreCase(ACTION_STOP)) {
mController.getTransportControls().stop();
}
}
private NotificationCompat.Action generateAction(int icon, String title, String intentAction) {
Intent intent = new Intent(getApplicationContext(), MediaPlayerService.class);
intent.setAction(intentAction);
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 1, intent, 0);
return new NotificationCompat.Action.Builder(icon, title, pendingIntent).build();
}
#SuppressLint("ServiceCast")
private void buildNotification(NotificationCompat.Action action) {
title = ""; // add variable to get current playing song title here
description =""; // add variable to get current playing song description here
Intent notificationIntent = new Intent(getApplicationContext(), HomeActivity.class); //specify which activity should be opened when widget is clicked (other than buttons)
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, 0);
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Notification channels are only supported on Android O+.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
//method to create channel if android version is android. Descrition below
createNotificationChannel();
}
Intent intent = new Intent(getApplicationContext(), MediaPlayerService.class);
intent.setAction(ACTION_STOP);
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 1, intent, 0);
final NotificationCompat.Builder builder;
//condition to check if music is playing
//if music is playing widget cant be dismissed on swipe
if(<add your method to check play status here>)
{
builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.logo2b)
.setLargeIcon(BitmapFactory.decodeResource(getApplication().getResources(), R.mipmap.ic_launcher))
.setContentTitle(title)
.setContentText(description)
.setDeleteIntent(pendingIntent)
.setContentIntent(contentIntent)
.setChannelId(CHANNEL_ID)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setOnlyAlertOnce(true)
.setColor(getResources().getColor(R.color.colorPrimary))
.setOngoing(true) //set this to true if music is playing widget cant be dismissed on swipe
.setStyle(new android.support.v4.media.app.NotificationCompat.MediaStyle()
// show only play/pause in compact view
.setShowActionsInCompactView(0, 1, 2));
}
//else if music is not playing widget can be dismissed on swipe
else
{
builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.logo2b)
.setLargeIcon(BitmapFactory.decodeResource(getApplication().getResources(), R.mipmap.ic_launcher))
.setContentTitle(title)
.setContentText(description)
.setDeleteIntent(pendingIntent)
.setContentIntent(contentIntent)
.setChannelId(CHANNEL_ID)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setOnlyAlertOnce(true)
.setColor(getResources().getColor(R.color.colorPrimary))
.setStyle(new android.support.v4.media.app.NotificationCompat.MediaStyle()
// show only play/pause in compact view
.setShowActionsInCompactView(0, 1, 2));
}
builder.addAction(generateAction(R.drawable.ic_skip_previous_white_24dp, "Previous", ACTION_PREVIOUS));
builder.addAction(action);
builder.addAction(generateAction(R.drawable.ic_skip_next_white_24dp, "Next", ACTION_NEXT));
//style.setShowActionsInCompactView(0,1,2);
// builder.setColor(getResources().getColor(R.color.app_orange_color));
notificationManager.notify(1, builder.build());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (mManager == null) {
try {
initMediaSessions();
} catch (RemoteException e) {
e.printStackTrace();
}
}
handleIntent(intent);
return super.onStartCommand(intent, flags, startId);
}
private void initMediaSessions() throws RemoteException {
mMediaPlayer = new MediaPlayer();
mSession = new MediaSessionCompat(getApplicationContext(), "simple player session");
mController = new MediaControllerCompat(getApplicationContext(), mSession.getSessionToken());
mSession.setCallback(new MediaSessionCompat.Callback() {
#Override
public void onPlay() {
super.onPlay();
//add you code for play button click here
//replace your drawable id that shows pauseicon buildNotification(generateAction(R.drawable.uamp_ic_pause_white_24dp, "Pause", ACTION_PAUSE));
}
#Override
public void onPause() {
super.onPause();
//add you code for pause button click here
//replace your drawable id that shows play icon buildNotification(generateAction(R.drawable.uamp_ic_play_arrow_white_24dp, "Play", ACTION_PLAY));
}
#Override
public void onSkipToNext() {
super.onSkipToNext();
//add you code for next button click here
buildNotification(generateAction(R.drawable.uamp_ic_pause_white_24dp, "Pause", ACTION_PAUSE));
}
#Override
public void onSkipToPrevious() {
super.onSkipToPrevious();
//add you code for previous button click here
buildNotification(generateAction(R.drawable.uamp_ic_pause_white_24dp, "Pause", ACTION_PAUSE));
}
#Override
public void onStop() {
super.onStop();
Log.e("MediaPlayerService", "onStop");
//Stop media player and dismiss widget here
NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(1);
Intent intent = new Intent(getApplicationContext(), MediaPlayerService.class);
stopService(intent);
}
#Override
public void onSeekTo(long pos) {
super.onSeekTo(pos);
}
}
);
}
#Override
public boolean onUnbind(Intent intent) {
mSession.release();
return super.onUnbind(intent);
}
//method to create notification channel on android Oreo and above
#RequiresApi(Build.VERSION_CODES.O)
private void createNotificationChannel() {
int notifyID = 1;
CharSequence name = "Player Widget";// The user-visible name of the channel. This channel name will be shown in settings.
if (notificationManager.getNotificationChannel(CHANNEL_ID) == null) {
NotificationChannel notificationChannel =
new NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_LOW);
notificationManager.createNotificationChannel(notificationChannel);
}
}
}
And fire these intents for actions to update widget when play status is changed from within the app:
Play-
//to change widgets current action button to play
Intent intent = new Intent(getApplicationContext(), MediaPlayerService.class);
intent.setAction(MediaPlayerService.ACTION_PAUSE);
startService(intent);
Pause-
//to change widgets current action button to pause
Intent intent = new Intent(getApplicationContext(), MediaPlayerService.class);
intent.setAction(MediaPlayerService.ACTION_PLAY);
startService(intent);
Excuse me if there are any unwanted import.All the best.