In flutter, how can I register if the headset is suddenly unplugged - flutter

Android java offers to register a BroadcastReceiver checking for AudioManager.ACTION_AUDIO_BECOMING_NOISY, to listen to the system broadcasting an ACTION_AUDIO_BECOMING_NOISY message, when a sound is played but then the headset is unplugged or a Bluetooth device disconnected.
Is there a way to do this in flutter, to respond to the event that e.g. a headset is unplugged while playing sound?
With the hint in the answer below, I got this going, but only in DEBUG mode, not in a release ready APK. This is what I did:
Java:
public class MainActivity extends FlutterActivity {
public static final String STREAM = "XXX";
public static String TAG = "player/java file";
private IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
private BecomingNoisyReceiver myNoisyAudioStreamReceiver = null;
private class BecomingNoisyReceiver extends BroadcastReceiver {
final EventChannel.EventSink eventSink;
BecomingNoisyReceiver(EventChannel.EventSink eventSink){
super();
this.eventSink = eventSink;
}
#Override
public void onReceive(Context context, Intent intent) {
if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
Log.w(TAG, "Noisy Receiver activated");
eventSink.success("success");
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
new EventChannel(getFlutterView(), STREAM).setStreamHandler(
new EventChannel.StreamHandler() {
#Override
public void onListen(Object args, final EventChannel.EventSink events) {
Log.w(TAG, "adding listener");
myNoisyAudioStreamReceiver = new BecomingNoisyReceiver(events);
registerReceiver(myNoisyAudioStreamReceiver, intentFilter);
}
#Override
public void onCancel(Object args) {
Log.w(TAG, "cancelling listener");
unregisterReceiver(myNoisyAudioStreamReceiver);
}
}
);
}
}
And in Dart, in the class extending State:
static const platform = const EventChannel('XXX');
StreamSubscription _noisySubscription;
in initState():
_noisySubscription = null;
Whenever I need it:
if(_noisySubscription == null){
_noisySubscription = platform.receiveBroadcastStream().listen(_handleNoisy);
}
Whenever it needs to stop:
_noisySubscription.cancel().then((_){_noisySubscription = null;});
Any hint, how to fix this problem?

You can use EventChannel to communicate an event on native part (Android) to Dart part. Ref: https://medium.com/#svenasse/flutter-event-channels-89623ce6c017
(Pseudo) Sample Code (it's not in runable state, but hopefully it gives you idea):
Dart part
void _handleNoisy(noisyEvent) {
debugPrint("noisyEvent $noisyEvent");
}
static const stream =
const EventChannel('com.yourcompany.yourapp/ACTION_AUDIO_BECOMING_NOISY');
StreamSubscription _noisySubscription = stream.receiveBroadcastStream().listen(_handleNoisy);
Java part
public class MainActivity extends FlutterActivity {
public static final String STREAM = "com.yourcompany.yourapp/ACTION_AUDIO_BECOMING_NOISY";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new EventChannel(getFlutterView(), STREAM).setStreamHandler(
new EventChannel.StreamHandler() {
#Override
public void onListen(Object args, final EventChannel.EventSink dartEvents) {
Log.w(TAG, "adding listener");
noisyEvent = ... // Register
private class BecomingNoisyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
dartEvents.success("the payload you want to pass to dart")
}
}
}
}
#Override
public void onCancel(Object args) {
Log.w(TAG, "cancelling listener");
}
}
);
}
}

Related

Marshmallow does not show my custom analog clock widget

I have created custom analog clock which I want to display in the widget. This analog clock is visible in Api 16+ but not visible in Marshmallow (Api 23). Marshmallow allowing to create the widget but does not display my analog clock on the home screen.
Is there any permission in marshmallow to show my custom analog widget??
This is my Widget Class
'public class Widget extends AppWidgetProvider {
private Intent mUpdateService;
#Override
public void onReceive(Context context, Intent intent) { if(intent.getAction().equals(AppWidgetManager.ACTION_APPWIDGET_DISABLED)) {
mUpdateService = new Intent();}else{
if (mUpdateService == null)
mUpdateService = new Intent(context, UpdateService.class);
context.startService(mUpdateService);
}
}
public static class UpdateService extends Service {
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
private boolean isScreenOn = true;
#Override
public void onReceive(Context context, Intent intent) {
String key = intent.getAction();
if (key.equals(Intent.ACTION_SCREEN_ON)) {
isScreenOn = true;
updateWidget();
} else if (key.equals(Intent.ACTION_SCREEN_OFF)) {
isScreenOn = false;
} else if (isScreenOn) {
updateWidget();
}
}
};
public RemoteViews mRemoteViews;
public WidgetAnalogClock widgetAnalogClock;
#Override
public void onCreate() {
mRemoteViews = new RemoteViews(getApplicationContext().getPackageName(), R.layout.widget_layout);
widgetAnalogClock = new WidgetAnalogClock(getApplicationContext());
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
registerReceiver(mReceiver, filter);
}
#Override
public void onDestroy() {
unregisterReceiver(mReceiver);}
#Override
public void onStart(Intent intent, int startId) {
updateWidget();}
private void updateWidget(){
WidgetAnalogClock myView=new WidgetAnalogClock(getApplicationContext());
mRemoteViews=new RemoteViews(getApplicationContext().getPackageName(),R.layout.widget_layout);
myView.measure(150, 150);
myView.layout(0, 0, 750, 750);
myView.setDrawingCacheEnabled(true);
Bitmap bitmap = myView.getDrawingCache();
mRemoteViews.setImageViewBitmap(R.id.customClock, bitmap);
AppWidgetManager.getInstName(this, Widget.class), mRemoteViews);
bitmap = myView.getDrawingCache();
mRemoteViews.setImageViewBitmap(R.id.customClock, bitmap);}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
}`

How to make my service run?

I want to start a service when the power is connected to my device and show a notification but my app is doing nothing or I do not what is happenig, so please help me, I am new in the android world, maybe I miss something, mi code is the following:
My manifest:
<receiver android:name="com.tlm.grhs_client.WiFiMonitor">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
</intent-filter>
</receiver>
My Broadcast Reciever:
public class WiFiMonitor extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if (info != null && info.getType() == ConnectivityManager.TYPE_WIFI) {
if (info.isConnected()) {
//iniciar servicio
Intent serviceIntent = new Intent(context, ClientService.class);
context.startService(serviceIntent);
}
else {
//parar servicio
Intent serviceIntent = new Intent(context, ClientService.class);
context.stopService(serviceIntent);
}
}
}
}
and my service class is this:
public class ClientService extends Service {
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
Toast.makeText(this, "Servicio fue creado", Toast.LENGTH_LONG).show();
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#SuppressLint("NewApi")
#Override
public void onStart(Intent intent, int startId) {
// Perform your long running operations here.
Toast.makeText(this, "Servicio iniciado", Toast.LENGTH_LONG).show();
Notification.Builder notiBuilder = new Notification.Builder(this);
notiBuilder.setContentTitle("Prueba");
notiBuilder.setContentText("Esto es una prueba");
Notification notificacion = notiBuilder.build();
NotificationManager manager = (NotificationManager) this.getSystemService(this.NOTIFICATION_SERVICE);
manager.notify(1, notificacion);
}
#Override
public void onDestroy() {
Toast.makeText(this, "Servicio destruido", Toast.LENGTH_LONG).show();
}
}
I turn on the wifi and establish the connection but the notification doesn't shows.
Android notifications in this manner require a small icon, along with a title and some text as per the documentation at http://developer.android.com/guide/topics/ui/notifiers/notifications.html
Add an icon but otherwise the code (on a quick glance) looks like it should work.

Android Check for Wireless connection upon Returning to Activity from Settings

My Android application is mainly a Webview (labeles WebViewActivity) that navigates a mobile website. I have a connection detector that opens another activity on every URL load if there is no wireless connection. From this next activity there is a button that opens up the Wireless Settings. Upon pressing the back button I would like for the second activity (labeled MainActivity) to refresh itself and continue back to whichever page my Webview had loaded. What do I need to change in the MainActivity.java to execute that?
My MainActivity:
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
// flag for Internet connection status
Boolean isInternetPresent = false;
// Connection detector class
ConnectionDetector cd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
}
#Override
protected void onRestart(){
if(checkConnection()){
Intent intent= new Intent(this, WebViewActivity.class);
startActivity(intent);
}
}
#Override
// Detect when the back button is pressed
public void onBackPressed() {
super.onBackPressed();
}
public void openSettings(View view){
Intent intent= new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS);
startActivity(intent);
}
public boolean checkConnection(){
// creating connection detector class instance
cd = new ConnectionDetector(getApplicationContext());
//Get Internet Status
isInternetPresent = cd.isConnectingToInternet();
if(!isInternetPresent)
return false;
return true;
}
}
My WebviewActivity:
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.net.Uri;
import android.os.Bundle;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class WebViewActivity extends Activity {
private WebView mWebView;
// flag for Internet connection status
Boolean isInternetPresent = false;
// Connection detector class
ConnectionDetector cd;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// TODO Auto-generated method stub
if (checkConnection()) {
mWebView = (WebView) findViewById(R.id.activity_main_webview);
// Enable Javascript
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
mWebView.loadUrl("http://my.fellowshipnwa.org/?publicapp");
// Force links and redirects to open in the WebView instead of in a browser
mWebView.setWebViewClient(new myWebClient());
} else {
openSplash();
}
}
#Override
// Detect when the back button is pressed
public void onBackPressed() {
if(mWebView.canGoBack()) {
mWebView.goBack();
} else {
// Let the system handle the back button
new AlertDialog.Builder(this)
.setTitle("Exit myFellowship App?")
.setMessage("Are you sure you want to exit?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes, new OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
WebViewActivity.super.onBackPressed();
}
}).create().show();
}
}
public class myWebClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if(!checkConnection()){
openSplash();
return true;
}else{
if( url.startsWith("tel:")){
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
startActivity(intent);
return true;
}
else if( url.startsWith("mailto:")){
Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse(url));
startActivity(intent);
return true;
}
}
return false;
}
}
public void openSplash(){
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
}
public boolean checkConnection(){
// creating connection detector class instance
cd = new ConnectionDetector(getApplicationContext());
//Get Internet Status
isInternetPresent = cd.isConnectingToInternet();
if(!isInternetPresent)
return false;
return true;
}
}
Any help is Greatly Appreciated! Even if it means telling me I goofed up on creating this question.
Thank you friends.
I played with it for a while and used a few other examples to piece together something that is working. One small hitch is if the user turns on a connection, but it is not quite connected when they return to the app it will stay on the ConnectorActivity. So I intercept the back button to check for a connection. If present, it will finish the current activity. Then, upon returning to the webview it will reload.
ConnectorActivity.java:
#Override
protected void onRestart(){
super.onRestart();
if(checkConnection()){
finish();
}
}
#Override
// Detect when the back button is pressed
public void onBackPressed() {
if(checkConnection()){
super.onBackPressed();
}
}
Piece from WebViewActivity.java:
#Override
protected void onRestart(){
super.onRestart();
mWebView.reload();
}

Clear SuggestBox on blur in GWT

I have a SuggestionBox in GWT. Is there a way to clear it when it blurs (unless the user made a selection, in which case an action should happen)?
Add a BlurHandler:
suggestionBox.getValueBox().addBlurHandler(new BlurHandler() {
#Override
public void onBlur(BlurEvent event) {
// your code goes here
}
});
Try this one using ValueChangeHandler:
Note: ValueChange event has same behavior as Blue event but it is fired only if value is changed in SuggestBox.
class MyMultiWordSuggestOracle extends MultiWordSuggestOracle {
private Set<String> values = new HashSet<String>();
#Override
public void add(String value) {
super.add(value);
values.add(value);
}
#Override
public void clear(){
super.clear();
values.clear();
}
public boolean contains(String value) {
return values.contains(value);
}
}
You code:
final MyMultiWordSuggestOracle oracle = new MyMultiWordSuggestOracle();
oracle.add("A");
oracle.add("AB");
oracle.add("BCD");
oracle.add("BCDE");
final SuggestBox suggestionBox = new SuggestBox(oracle);
suggestionBox.addValueChangeHandler(new ValueChangeHandler<String>() {
#Override
public void onValueChange(ValueChangeEvent<String> event) {
if (!oracle.contains(event.getValue())) {
suggestionBox.setValue("");
}
}
});

drop widget beyond the AbsolutePanel gwt dnd

I'm trying to drop my draggable widgets out of the boundary panel (AbsolutePanel). In my case draggable widgets is an image. And I want to drop it, so that there will be visible only a part of the image, but when I drop it, and some parts of image beyond absolute panel, it drop automatically within absolute panel.
I tried :
dragController.setBehaviorConstrainedToBoundaryPanel(false);
and thought it means that I can drop it where ever I want, but it doesn't work.
And the working solution :)
Here is my code:
public class myEntripointClass implement EntryPOint{
AbsolutePanel droper;
public void onModuleLoad() {
Panel main = new AbsolutePanel();
droper = new AbsolutePanel();
droper.setHeight("300px");
droper.setWidth("500px");
main.add(droper);
content=new AbsolutePanel();
bt = new Button("Drag and drop it");
content.add(bt);
lb = new Label("Label drag and drop");
content.add(lb);
main.add(content);
manageDnD();
RootPanel.get().add(main);
}
private void manageDnD() {
PickupDragController dragController = new PickupDragController(
(AbsolutePanel) content, true);
dragController.makeDraggable(bt);
dragController.makeDraggable(lb);
dragController.addDragHandler(new DragHandler() {
#Override
public void onPreviewDragStart(DragStartEvent event)
throws VetoDragException {}
#Override
public void onPreviewDragEnd(DragEndEvent event) throws VetoDragException {}
#Override
public void onDragStart(DragStartEvent event) {
}
#Override
public void onDragEnd(DragEndEvent event) {
// TODO Auto-generated method stub
DragContext context = event.getContext();
int x=context.mouseX;
int y= context.mouseY;
droper.add(context.selectedWidgets.get(0),x,y);
}
});
NameDropController dropController = new NameDropController(droper);
dragController.registerDropController(dropController);
dragController.setBehaviorDragProxy(true);
}
and my DropController class is:
public class NameDropController extends AbstractDropController{
public NameDropController(Widget dropTarget) {
super(dropTarget);
}
#Override
public void onDrop(DragContext context) {
int x=getDiff(getDropTarget().getAbsoluteLeft(), context.mouseX);
int y=getDiff(getDropTarget().getAbsoluteTop(), context.mouseY);
((AbsolutePanel)getDropTarget()).add(context.selectedWidgets.get(0),x,y);
System.out.print("("+context.mouseX+"::,::"+context.mouseY+")");
}
#Override
public void onMove(DragContext context){
}
private int getDiff(int val1,int val2){
return Math.abs(val1-val2);
}
}