How to get Wechat authorization token? - android

Target: get token which I need to send to the app server
Problem: registered returns true, requests done returns true, but onReq and onRespdid not get called. Here is the code:
public class WeChatActivity extends Activity implements IWXAPIEventHandler {
private static final String APP_ID = ;
private IWXAPI api;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_signin);
api = WXAPIFactory.createWXAPI(this, APP_ID, true);
api.handleIntent(getIntent(), this);
regToWx();
getAuthToken();
}
private void regToWx() {
api.handleIntent(getIntent(), this);
boolean registered = api.registerApp(APP_ID);
L.e(this, "registered: " + registered);
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
api.handleIntent(intent, this);
}
public void getAuthToken() {
SendAuth.Req req = new SendAuth.Req();
req.scope = "post_timeline";
req.state = "none";
boolean requestDone = api.sendReq(req);
L.e(this, "request done: " + requestDone);
SendAuth.Resp resp = new SendAuth.Resp();
requestDone = api.sendResp(resp);
L.e(this, "request done: " + requestDone);
}
#Override
public void onReq(BaseReq baseReq) {
L.e(this, "scope: " + ((SendAuth.Req) baseReq).scope);
}
#Override
public void onResp(BaseResp baseResp) {
L.e(this, "token: " + ((SendAuth.Resp) baseResp).token);
}
}
Log cat output:
D/MicroMsg.SDK.WXApiImplV10﹕ check signature:308202eb30820254a003020...
D/MicroMsg.SDK.WXApiImplV10﹕ pass
D/MicroMsg.SDK.WXApiImplV10﹕ register app cn.wegazine.wegazine
D/MicroMsg.SDK.MMessage﹕ send mm message, intent=Intent { act=com.tencent.mm.plugin.openapi.Intent.ACTION_HANDLE_APP_REGISTER (has extras) }, perm=com.tencent.mm.permission.MM_MESSAGE
E/WeChatActivity﹕ registered: true
D/MicroMsg.SDK.WXApiImplV10﹕ check signature:308202eb30820...
D/MicroMsg.SDK.WXApiImplV10﹕ pass
D/MicroMsg.SDK.MMessageAct﹕ send mm message, intent=Intent { flg=0x18000000 cmp=com.tencent.mm/.plugin.base.stub.WXEntryActivity (has extras) }
E/WeChatActivity﹕ request done: true
D/MicroMsg.SDK.WXApiImplV10﹕ check signature:308202eb30820...
D/MicroMsg.SDK.WXApiImplV10﹕ pass
D/MicroMsg.SDK.MMessageAct﹕ send mm message, intent=Intent { flg=0x18000000 cmp=com.tencent.mm/.plugin.base.stub.WXEntryActivity (has extras) }
E/WeChatActivity﹕ request done: true

I've face the same problem and solved with two steps.
First check if you've successfully jumped to the wechat app and authorized.
If not, check if you're using the same signing key that you signed to wechat.
(ex. if you signed with the release key and compile with debug key, then wechat app won't open)
Second, by wechat document, the class name should be WXEntryActivity and should be put under a package named wxapi under the package with the name you registered at wechat.
Example in the document: If you register with "net.sourceforge.simcpux", the project structure should look like this
Also, add api.HandleIntent(getIntent(), this) after sendReq and sendResp
Not sure if the classname is neccessary, but I'm sure you can call sendReq in other class and process response with WXEntryActivity
Hope this is helpful.

had the same issue! Edwards answer helped a lot.
WxEntryActivity needs to be in the package with the name you registered at wechat!
Especially when you have multiple build variants (debug, release):
Wechat login - do not receive token

onReq and onResp will be called in WXEntryActivity.java within JAVA reflection
Suppose package name io.github.you
You should create a directory named wxapi,then create a WXEntryActivity.java
You get io.github.you.wxapi.WXEntryActivity.java
In AndroidManifest.xml
<activity
android:name=".wxapi.WXEntryActivity"
android:exported="true"
android:label="#string/title_activity_wxentry"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.NoDisplay" >
In WXEntryActivity.java
public class WXEntryActivity implements IWXAPIEventHandler{
#Override
public void onReq(BaseReq arg0) {
SendAuth.Resp r = (SendAuth.Resp)resp;
String code = r.code;
}
#Override
public void onResp(BaseResp arg0) {
// TODO Auto-generated method stub
}
}
Good Luck

Related

How to restrict bound service to be called by particular packages

I have written a bound service and I would like this service to be only called from particular app. I do not want other apps to be able to make calls to this service.
The options I know so far are:
Use a permission. There seems to be 3 secured permission, dangerous, signature and signatureOrSystem. Unfortunately, none of these permissions will work for me as I don't want users to accept this permission also both app does not have same signature and these are not system app.
Get app name on service bind or when making a call to service. I looked up a way to do this on stackoverflow here. This unfortunately does not works for me as it always returns the app ID in which the service resides.
Is there any other option for me or I can use the above mentioned options with some change to achieve the desired requirement.
Bound Service Code
public class SampleCommsService extends Service {
private static Messenger messanger;
#Override
public IBinder onBind(Intent intent) {
Log.e("TEST", "package intent: " + intent.getPackage());
String callingApp = MyApplication.getAppContext().getPackageManager().getNameForUid(Binder.getCallingUid());
Log.e("TEST", "onBind - package name: " + callingApp);
return getMyBinder();
}
private synchronized IBinder getMyBinder() {
if (messanger == null) {
messanger = new Messenger(new SettingsProcessor());
}
return messanger.getBinder();
}
class SettingsProcessor extends Handler {
private static final int GET_SETTINGS_REQUEST = 1;
private static final int UPDATE_SETTINGS_RESPONSE = 2;
private static final String SETTINGS = "settings";
#Override
public void handleMessage(Message msg) {
String callingApp = MyApplication.getAppContext().getPackageManager().getNameForUid(Binder.getCallingUid());
Log.e("TEST", "handle message - package name: " + callingApp);
switch (msg.what) {
case GET_SETTINGS_REQUEST:
sendSettingsValue(msg);
break;
default:
super.handleMessage(msg);
}
}
private void sendSettingsValue(Message msg) {
try {
Message resp = Message.obtain(null, UPDATE_SETTINGS_RESPONSE);
Bundle bundle = new Bundle();
bundle.putBoolean(SETTINGS, MyApplication.isSettingsEnabled());
resp.setData(bundle);
msg.replyTo.send(resp);
} catch (RemoteException e) {
// ignore
}
}
}
}
Output on calling api:
02-01 15:21:03.138 7704-7704/my.service.package E/TEST: package intent: null
02-01 15:21:03.139 7704-7704/my.service.package E/TEST: onBind - package name: my.service.package
02-01 15:21:12.429 7704-7704/my.service.package E/TEST: handle message - package name: my.service.package
OK, I was able to solve this problem based on a given answer here. The answer given in the link obviously does not works, but you can get the app ID from the Handler used for the bound service.
class SettingsProcessor extends Handler {
#Override
public void handleMessage(Message msg) {
String callingApp = MyApplication.getAppContext().getPackageManager().getNameForUid(msg.sendingUid);
Log.e("TEST", "handle message - package name: " + callingApp);
}
}
Instead of Binder.getCallingUid(), I am using msg.sendingUid and it works fine for me.

WeChat InApp payment screen shows up only for first time

I'm trying to implement WeChat InApp payments in our app. But we are struggling to make it work.
I will try to sum it up real quick.
Given user is not logged in, WeChat login screen show up every time.
Given user is logged in, when clicked on pay button for a first time, WeChat order info screen shows up, but when clicked back, and clicked on pay button again (in our app), WeChat screen doesn’t show up.
We did implemented WXPayEntryActivity but neither onCreate, onNewIntent nor onResp are called. And yes, this activity is sending broadcast but neither toast nor log shows up.
I tried call registerApp on application started, I tried it just before creating payment req.
Did anybody come across this issue?
Can WeChat help me directly?
Want to see some code?
This is my payment class
public class WXInAppPayment {
public void startPayment(AppCompatActivity activity, PaymentDataResponse data) {
IWXAPI api = getApi(activity);
if (api.isWXAppInstalled()) {
api.sendReq(getPayRequest(data));
} else {
// Showing toast
}
}
public WXReceiver getReceiver() {
// returning BR for wechat payments
return new WXReceiver();
}
public IntentFilter getIntentFilter() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Constants.WE_CHAT_BR_ID);
return intentFilter;
}
private IWXAPI getApi(AppCompatActivity activity) {
final IWXAPI api = WXAPIFactory.createWXAPI(activity, null);
api.registerApp(Constants.WE_CHAT_APP_ID);
return api;
}
private PayReq getPayRequest(PaymentDataResponse data) {
PayReq request = new PayReq();
request.appId = dataFromAPI.appId;
request.partnerId = dataFromAPI.partnerId;
request.prepayId = dataFromAPI.prepayId;
request.packageValue = dataFromAPI.packageValue;
request.nonceStr = dataFromAPI.nonceStr;
request.timeStamp = dataFromAPI.timestimeStampamp;
request.sign = dataFromAPI.sign;
return request;
}
}
And this is WXPayEntryActivity. In manifest:
<activity android:name=".wxapi.WXPayEntryActivity"
android:label="#string/app_name"
android:exported="true"/>
And class:
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
private final String TAG = getClass().getSimpleName();
private IWXAPI api;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
api = WXAPIFactory.createWXAPI(this, Constants.WE_CHAT_APP_ID);
api.handleIntent(getIntent(), this);
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
api.handleIntent(intent, this);
}
#Override
public void onReq(BaseReq baseReq) {
Log.e(TAG, "onReq: " + baseReq.transaction);
}
#Override
public void onResp(BaseResp baseResp) {
Log.e(TAG, "onResp: " + baseResp.errStr + " " + baseResp.errCode);
Intent intent = new Intent(Constants.WE_CHAT_BR_ID);
intent.putExtra("error_code", baseResp.errCode);
intent.putExtra("error_string", baseResp.errStr);
sendBroadcast(intent);
finish();
}
}
I went through same issue... Your code look fine.
lets cover the scenario:
This is normal ... if user is not logged in.. Wechat App will
redirect to login screen
"Only first time payment passed" happened due to wrong packageName. consider these checks:
You need to use ApplicationId not packageName
WhiteSpace
Debug buildType by default has suffix: .debug to applicatonId
Check AppSign which is MD5 of cert you sign with.. Be careful not to use the default one for debug buildType.
Try to reassign ApplicationId and AppSign it again.(that was our issue 😞) due to hidden WS not visible.
Contact Wechat team support.. they have logs to payment.

Google Cloud Messaging register method provides a null value

As recommended in the available documentation I decided to implement an automatic update whenever there is an update of the version of my application.
For doing that I have a service that is running in the background performing several operations appart from the GCM update. This service is calling a class that performs all operations related to GCM.
So, basically, this is the call to performed in the Service:
try {
PackageInfo info = manager.getPackageInfo(this.getPackageName(), 0);
currentVersion = info.versionCode;
} catch (NameNotFoundException e) {
//Handle exception
}
if (registeredVersion != currentVersion) {
Log.i(ApplicationData.APP_TAG, TAG + ": New version, updating");
GcmUpdater upGcm = new GcmUpdater(getApplicationContext());
Boolean update = upGcm.getAndUpdate();
//We update the current version
if (update) {
prefs.setAppPrevVersion(currentVersion);
} else {
Log.e(ApplicationData.APP_TAG, TAG + ": GCM not updated");
}
} else {
Log.i(ApplicationData.APP_TAG, TAG + ": Same version, no GCM needed");
}
Ok, I think the key point in the previous code is that I am initiating the class called GcmUpdater is initiated using the application context given by the service.
The constructor of my class GcmUpdater is the following:
public GcmUpdater(Context cont) {
context = cont;
TAG = getClass().getName();
prefs = new StorePreferences(context);
}
Nothing special, as you can see I am calling the method inside GcmUpdater called getAndUpdate(), this method is the following one
public Boolean getAndUpdate() {
String new_regid = giveRegId();
return updateGCM(new_regid);
}
Ok, the problem is coming now, is the public function giveRegId()
public String giveRegId() {
try{
return new RegisterGCM().execute().get();
}catch(Exception ex){
ex.printStackTrace();
return null;
}
}
Which calls to the asyncronous task RegisterGCM....
public class RegisterGCM extends AsyncTask<Void,Void,String>
{
#Override
protected String doInBackground(Void... arg0)
{
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(context);
}
regid = gcm.register(ApplicationData.SENDER_ID);
Log.i(ApplicationData.APP_TAG, TAG +":Device registered, registration ID=" + regid);
} catch (IOException ex) {
Log.e(ApplicationData.APP_TAG, TAG + ": " + ex.getMessage());
}
return regid;
}
protected void onPostExecute(Boolean result) {
return ;
}
}
The problem I am facing is that the variable regid obtained is null and according to similar problems like this one or this other one, I should include the ApplicationContext, however that is passed as parameter in the constructor.
Moreover, the class RegisterGCM is used by my main activity and works. So my guess has been always that the way to call to register the GCM code is the one that is creating the problem, but is not clear why.
What am I doing wrong? I have not been able to find any explication of this problem in google.
Your sender ID is equals to Google Console Project Id?

Android No Activity found to handle intent

I am basing my app off the foursquare-oAuth-sample app posted at Foursquare oAuth sample
Have made changes to MyActivity pretty much similar to the sample code but still getting this, can someone point out what I need to change, the code is as below
public class MyActivity extends FragmentActivity {
private static final int REQUEST_CODE_FSQ_CONNECT = 200;
private static final int REQUEST_CODE_FSQ_TOKEN_EXCHANGE = 201;
/**
* Obtain your client id and secret from:
* https://foursquare.com/developers/apps
*/
private static final String CLIENT_ID = "";
private static final String CLIENT_SECRET = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
ensureUi();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.my, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Update the UI. If we already fetched a token, we'll just show a success
* message.
*/
private void ensureUi() {
boolean isAuthorized = !TextUtils.isEmpty(ExampleTokenStore.get().getToken());
TextView tvMessage = (TextView) findViewById(R.id.tvMessage);
tvMessage.setVisibility(isAuthorized ? View.VISIBLE : View.GONE);
Button btnLogin = (Button) findViewById(R.id.btnLogin);
btnLogin.setVisibility(isAuthorized ? View.GONE : View.VISIBLE);
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Start the native auth flow.
Intent intent = FoursquareOAuth.getConnectIntent(MyActivity.this, CLIENT_ID);
// If the device does not have the Foursquare app installed, we'd
// get an intent back that would open the Play Store for download.
// Otherwise we start the auth flow.
if (FoursquareOAuth.isPlayStoreIntent(intent)) {
toastMessage(MyActivity.this, getString(R.string.app_not_installed_message));
startActivity(intent);
} else {
startActivityForResult(intent, REQUEST_CODE_FSQ_CONNECT);
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE_FSQ_CONNECT:
onCompleteConnect(resultCode, data);
break;
case REQUEST_CODE_FSQ_TOKEN_EXCHANGE:
onCompleteTokenExchange(resultCode, data);
break;
default:
super.onActivityResult(requestCode, resultCode, data);
}
}
private void onCompleteConnect(int resultCode, Intent data) {
AuthCodeResponse codeResponse = FoursquareOAuth.getAuthCodeFromResult(resultCode, data);
Exception exception = codeResponse.getException();
if (exception == null) {
// Success.
String code = codeResponse.getCode();
performTokenExchange(code);
} else {
if (exception instanceof FoursquareCancelException) {
// Cancel.
toastMessage(this, "Canceled");
} else if (exception instanceof FoursquareDenyException) {
// Deny.
toastMessage(this, "Denied");
} else if (exception instanceof FoursquareOAuthException) {
// OAuth error.
String errorMessage = exception.getMessage();
String errorCode = ((FoursquareOAuthException) exception).getErrorCode();
toastMessage(this, errorMessage + " [" + errorCode + "]");
} else if (exception instanceof FoursquareUnsupportedVersionException) {
// Unsupported Fourquare app version on the device.
toastError(this, exception);
} else if (exception instanceof FoursquareInvalidRequestException) {
// Invalid request.
toastError(this, exception);
} else {
// Error.
toastError(this, exception);
}
}
}
private void onCompleteTokenExchange(int resultCode, Intent data) {
AccessTokenResponse tokenResponse = FoursquareOAuth.getTokenFromResult(resultCode, data);
Exception exception = tokenResponse.getException();
if (exception == null) {
String accessToken = tokenResponse.getAccessToken();
// Success.
toastMessage(this, "Access token: " + accessToken);
// Persist the token for later use. In this example, we save
// it to shared prefs.
ExampleTokenStore.get().setToken(accessToken);
// Refresh UI.
ensureUi();
} else {
if (exception instanceof FoursquareOAuthException) {
// OAuth error.
String errorMessage = ((FoursquareOAuthException) exception).getMessage();
String errorCode = ((FoursquareOAuthException) exception).getErrorCode();
toastMessage(this, errorMessage + " [" + errorCode + "]");
} else {
// Other exception type.
toastError(this, exception);
}
}
}
/**
* Exchange a code for an OAuth Token. Note that we do not recommend you
* do this in your app, rather do the exchange on your server. Added here
* for demo purposes.
*
* #param code
* The auth code returned from the native auth flow.
*/
private void performTokenExchange(String code) {
Intent intent = FoursquareOAuth.getTokenExchangeIntent(this, CLIENT_ID, CLIENT_SECRET, code);
startActivityForResult(intent, REQUEST_CODE_FSQ_TOKEN_EXCHANGE);
}
public static void toastMessage(Context context, String message) {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
public static void toastError(Context context, Throwable t) {
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
}
Error Log
Here is the exception i am getting, can someone please point out why is it not able to find the activity to handle intent? Thank you
08-13 23:15:23.137 2754-2754/com.example.panaceatechnologysolutions.farhansfoursquareapp E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.panaceatechnologysolutions.farhansfoursquareapp, PID: 2754
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=market://details?id=com.example.panaceatechnologysolutions.farhansfoursquareapp&referrer=utm_source=foursquare-android-oauth&utm_term=CLIENT_ID }
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1691)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1482)
at android.app.Activity.startActivityForResult(Activity.java:3711)
at android.app.Activity.startActivityForResult(Activity.java:3669)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:840)
at android.app.Activity.startActivity(Activity.java:3914)
at android.app.Activity.startActivity(Activity.java:3882)
at com.example.panaceatechnologysolutions.farhansfoursquareapp.MyActivity$1.onClick(MyActivity.java:90)
at android.view.View.performClick(View.java:4598)
at android.view.View$PerformClick.run(View.java:19268)
at android.os.Handler.handleCallback(Handler.java:738)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5070)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:836)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:631)
08-13 23:15:30.157 2754-2765/com.example.panaceatechnologysolutions.farhansfoursquareapp I/art﹕ Heap transition to ProcessStateJankImperceptible took 7.253732ms saved at least 72KB
Ok so based on Rohans reply I checked, since I was doing this on the Emulator, this snippet from the Foursquare oAuth library I have in my project cannot create the intent based on the context and client Id. I am not sure why it returns null and as a result redirects me to the Google play store to install foursquare on my emulator. I have registered my app with foursquare and am using the registered client Id and the rest of the parameters used by this function are the ones in Foursquare oAuth Java class. If someone has worked with this library or can point out why it can't find the intent please let me know as I have been stuck on this for a couple of days.
This is the line of code like Rohan pointed out calling the Foursquare oAuth Java class in MyActivity class
Intent intent = FoursquareOAuth.getConnectIntent(MyActivity.this, CLIENT_ID);
And this is the getConnectIntent method in the Foursquare oAuth Java Class
public static Intent getConnectIntent(Context context, String clientId) {
Uri.Builder builder = new Uri.Builder();
builder.scheme(URI_SCHEME);
builder.authority(URI_AUTHORITY);
builder.appendQueryParameter(PARAM_CLIENT_ID, clientId);
builder.appendQueryParameter(PARAM_VERSION, String.valueOf(LIB_VERSION));
builder.appendQueryParameter(PARAM_SIGNATURE, getSignatureFingerprint(context));
Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
if (isIntentAvailable(context, intent)) {
return intent;
}
return getPlayStoreIntent(clientId);
}
it redirects you to play store becuase "isIntentAvailable is false" and it calls "getPlayStoreIntent" which redirects you to play store.
inside isIntentAvailable method
private static boolean isIntentAvailable(Context context, Intent intent) {
PackageManager packageManager = context.getPackageManager();
List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(
intent, PackageManager.MATCH_DEFAULT_ONLY);
return resolveInfo.size() > 0;
}
this method return true if a suitable package is found.
also check your client id is not null and is correct
Yes Rohan...you are right it is false because the intent wasnt returning anything from isIntentAvailable, but the real reason why that was not returning an intent back was because since I am using the emulator, the package manager is apparently looking for a foursquare.apk package installed which it didnt find. I didnt Foursquare anywhere indicate that their apk has to be installed which is not included as part of the oAuth Library which they provide in the link above on the sample project. I guess they assume you are using an Android device for testing and not the emulator. These are the steps to use oAuth from Foursquare on Android emulator from Android studio or Eclipse im guessing as well.
1) Download the Foursquare APK http://www.apk4fun.com/apk/6395/
2) As a pre-requisite open Android SDK Manager in Android studio and make sure Google API's are downloaded and installed, these are needed by Foursquare
3) copy the foursquare.apk file in the /Applications/sdk/platform-tools folder
4) install the apk using the adb tool in the folder like shown in this link How to install an apk on the emulator in Android Studio?
5) and now your app can use the emulator to contact foursquare and you will not be redirected to install the app on the emulator!
-Note, I noticed I had to reinstall the "foursquare.apk" when i closed down Android studio and the emulator the next day. But was easy since i knew what to do, Hopefully this saves someone else the frustration as it took me a couple of days to figure this out :)

OnMessageReceived not called in WearableListenerService

I am working on android wear app using Eclipse IDE.I am using same package names for wear app and mobile app and i am packing wearable app manually according to google documentation.Everything is working fine.it is installed on Android wear emulator using usb debugging with phone.
My problem is when i am sending a message to wearable using following code
List<Node> nodeList=getNodes();
for(Node node : nodeList) {
Log.v(" ", "telling " + node.getId() );
PendingResult<MessageApi.SendMessageResult> result = Wearable.MessageApi.sendMessage(
mGoogleApiClient,
node.getId(),
START_ACTIVITY_PATH,
null
);
result.setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {
#Override
public void onResult(MessageApi.SendMessageResult sendMessageResult) {
Log.v(" ", "Phone: " + sendMessageResult.getStatus().getStatusMessage());
}
});
}
the OnPeerConnected method is running when devices are peered but OnMessageReceived never called in WearableListenerService.This is my WearableListenerService code:
public class DataLayerListenerService extends WearableListenerService {
private static final String TAG = "DataLayerSample";
private static final String START_ACTIVITY_PATH = "/start/MainActivity";
private static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received";
private static final String LOG_TAG = "log";
#Override
public void onPeerConnected(Node peer) {
super.onPeerConnected(peer);
String id = peer.getId();
String name = peer.getDisplayName();
Log.d(LOG_TAG, "Connected peer name & ID: " + name + "|" + id);
}
#Override
public void onDataChanged(DataEventBuffer dataEvents) {
System.out.println("Recevive message3");
}
#Override
public void onMessageReceived(MessageEvent messageEvent) {
System.out.println("service watch message1");
if (messageEvent.getPath().equals(START_ACTIVITY_PATH)) {
System.out.println("service watch message2");
Intent startIntent = new Intent(this, MainActivity.class);
startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startIntent);
}
}
}
Also a warning message in Logcat always appears :
app does not match record's app key: AppKey[com.myapp,c3f31717fa35401056c20a2798907f1232efa75e] != AppKey[com.myapp,f36e726eefc7e528db26a1c25f6fbf2f93dacd70]
If app key for both apps should be same then how can i create same app key for both the apps.
Any help is highly appreciated,
Thanks.
The error message you have:
app does not match record's app key:
AppKey[com.myapp,c3f31717fa35401056c20a2798907f1232efa75e] !=
AppKey[com.myapp,f36e726eefc7e528db26a1c25f6fbf2f93dacd70]
Indicated that your apps are signed with the different keys.
Package names of phone and wearable apps are the same - that is good, but they also need to share the same signature. This is the reason why messages cannot be delivered - wearable apps are recognized as "part of the same app" based on the package name and signature.
Please make sure that you have both apps signed with the same key. If you are testing the autoinstallation feature please make sure to uninstall the debug version of wearable app from watch emulator.
I had the same error, my fault was that the "wear" module's package name was not the same as the app's.
BAD:
[module: app] es.voghdev.myapp
[module: wear] es.voghdev.myapp.wear
GOOD:
[module: app] es.voghdev.myapp
[module: wear] es.voghdev.myapp
Made me waste so much time!! >:-(
Use an asyntask to send messages as they will block the ui thread. Also you need to call the await method. To get the apps to have the same key, you need to use build variants with gradle.
public class SendMessageTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
NodeApi.GetConnectedNodesResult nodes =
Wearable.NodeApi.getConnectedNodes(apiClient).await();
for (Node node : nodes.getNodes()) {
Wearable.MessageApi
.sendMessage(apiClient, node.getId(), "/start/MainActivity", null)
.await();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Toast.makeText(MainActivity.this, "Message Sent", Toast.LENGTH_SHORT).show();
}
}

Categories

Resources