Question

I am trying to trigger a button click on smartwatch and then change the text in host application in android phone. I tried to send a broadcast intent to the broadcast receiver and start a service which include a method that change the text in host application. However, the changeText() method seems not working. I am able to start a service but not able to change the text. Please see what is wrong in my code. It would be nice if you could give a brief example on how to send broadcast intent from the smartwatch to the host application in best practice.

My control extension class

class SampleControlSmartWatch2 extends ControlExtension {
    // Other code

    public void onObjectClick(ControlObjectClickEvent event) { 
        Intent intent = new Intent(SampleExtensionService.INTENT_ACTION_BROADCAST);
        intent.putExtra("Name", "something");
        mContext.sendBroadcast(intent);
    }      
}

My broadcast receiver

public class ExtensionReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(final Context context, final Intent intent) {
        intent.setClass(context, HostService.class);
        context.startService(intent);      
    }
}

My host application service

public class HostService extends Service {
    // Other code

    @Override
    public void onCreate() {
        super.onCreate();
        changeText();        
    }

    public void changeText() {
        LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
        View layoutHost = inflater.inflate(R.layout.activity_main, null);       
        TextView textView = (TextView) layoutHost.findViewById(R.id.textToBeChanged);
        Log.i(TAG, textView.getText().toString());     // It shows "Original"
        textView.setText("Changed Text");
        Log.i(TAG, textView.getText().toString());     // It shows "Changed Text"
    }
}

My AndroidManifest.xml

<application
    <!-- Other attribute -->

    <service android:name="com.sony.samplecontrolnotification.SampleExtensionService" />
    <service android:name="com.sony.samplecontrolnotification.HostService" />

    <receiver android:name="com.sony.samplecontrolnotification.ExtensionReceiver" >
        <intent-filter>
            <action android:name="com.sony.samplecontrolnotification.BROADCAST" />      
            <!-- Other action -->                
        </intent-filter>
    </receiver>
</application>
Was it helpful?

Solution

Not sure if it is the best way but this is how I solved it:

In my activity:

private MyService mService;
final Messenger mMessenger = new Messenger(new IncomingHandler(this));

@Override
protected void onStart() {
    super.onStart();
    Intent intent = new Intent(this, MyService.class);
    bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}

private ServiceConnection mConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName className, IBinder service) {
        LocalBinder binder = (LocalBinder) service;
        mService = binder.getService();
        mService.RegisterMessenger(mMessenger);
        mBound = true;
    }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        mBound = false;
    }
};

public static class IncomingHandler extends Handler {
    private final WeakReference<MyActivity> activity; 

    IncomingHandler(MyActivity activity) {
        this.activity = new WeakReference<MyActivity>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
        MyActivity dialog = activity.get();
        Bundle data = msg.getData();

        //TODO: update view here
    }
};


In my service:

private ArrayList<Messenger> messengers = new ArrayList<Messenger>();

public class LocalBinder extends Binder {
    public MyService getService() {
        return MyService.this;
    }
}

public void RegisterMessenger(Messenger messenger)
{       
    messengers.add(messenger);
}

public class MyReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        for (Messenger messenger : messengers)
        {           
            Message m = new Message();
            Bundle data = new Bundle();
            //TODO: add data to the message here

            messenger.send(m);
        }
    }
}

There are some parts missing (unregistering messenger, unbinding service) but this should be the main part.

If you have problems registering the BroadcastReceiver, this post can help: https://stackoverflow.com/a/10851904/3047078

Maybe you can even do it without the service by just creating a BroadcastReceiver as inner class of your activity.

OTHER TIPS

Easy way, how to send event to your application activity is by using Intent:

private void sendEventToActivity(String anyData) {
    Intent intent = new Intent(mContext, YourActivity.class);

    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

    intent.putExtra("anyData", anyData);

    mContext.startActivity(intent);
}

And then override onNewIntent for your Activity:

@Override
protected void onNewIntent(Intent intent) {
    String anyData = intent.getStringExtra("anyData");
}

This way it communicates with running activity or create a new one, if not running yet.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top