florent37 / Wear-Emmet

Emmet is an protocol based data-transfer for Android Wear
http://florent37.github.io/Emmet
Apache License 2.0
41 stars 11 forks source link

log: emmet end error #2

Closed croccio closed 9 years ago

croccio commented 9 years ago

i've implemented this library in my app. when i send request from smart watch to smartphone no problem. but when i send response from smartphone to android wear in log i see

    05-03 23:55:38.719  19540-19540/com.paybay.qui D/Emmet﹕ send error

i haven't put that log in my app, so i think it is your log. can you help me to identify that "error"? here you are my impl:

ANDROID WEAR
public class QUIWearActivity extends Activity implements WearProtocol {

protected Emmet emmet = new Emmet();
protected SmartphoneProtocol smartphoneProtocol;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    emmet.onCreate(this);

    smartphoneProtocol = emmet.createSender(SmartphoneProtocol.class);
    emmet.registerReceiver(WearProtocol.class, this);

}

@Override
protected void onDestroy() {
    super.onDestroy();
    emmet.onDestroy();
}

@Override
public void responseForCouponRequest(ResponseForCoupon responseForCoupon) {
    Toast.makeText(this, "ooooops", Toast.LENGTH_LONG).show();
}
}

public class CouponActivity extends QUIWearActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_coupon);

        smartphoneProtocol.askForCoupon();

        Toast.makeText(this, "ask", Toast.LENGTH_LONG).show();

        final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
        stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
            @Override
            public void onLayoutInflated(WatchViewStub stub) {

            }
        });
    }

    @Override
    public void responseForCouponRequest(ResponseForCoupon responseForCoupon) {
        Toast.makeText(this, "responseForCouponRequest", Toast.LENGTH_LONG).show();
    }
}
SMARTPHONE

public class WearService extends EmmetWearableListenerService implements SmartphoneProtocol {

    private final static String TAG = WearService.class.getCanonicalName();

    private Emmet emmet;

    private WearProtocol sender;

    @Override
    public void onCreate() {
        super.onCreate();
        getEmmet().registerReceiver(SmartphoneProtocol.class, this);
        sender = getEmmet().createSender(WearProtocol.class);
        Toast.makeText(WearService.this, "onCreate", Toast.LENGTH_LONG).show();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startid) {
        return START_STICKY;
    }

    @Override
    public void askForCoupon() {

        Toast.makeText(this, "askForCoupon", Toast.LENGTH_LONG).show();

        verifyUser(new UserVerification() {
            @Override
            public void userVerification(Verification status) {
                final ResponseForCoupon responseForCoupon = new ResponseForCoupon();
                switch (status) {
                    case NOT_ACTIVATED:
                        Toast.makeText(WearService.this, "NOT_ACTIVATED", Toast.LENGTH_LONG).show();
                        responseForCoupon.setResponseType(QUIWearResponseType.USER_NOT_ACTIVATED);
                        sender.responseForCouponRequest(responseForCoupon);
                        break;
                    case VALID:
                        Toast.makeText(WearService.this, "VALID", Toast.LENGTH_LONG).show();

                        QuiApi.services().getUserCoupons(new IQuiUserCouponsCallback() {
                            @Override
                            public void onGetCouponsSuccess(List<QUICoupon> coupons) {
                                Toast.makeText(WearService.this, "onGetCouponsSuccess", Toast.LENGTH_LONG).show();
                                responseForCoupon.setResponseType(QUIWearResponseType.OK);
                                responseForCoupon.setCouponList(coupons);
                                sender.responseForCouponRequest(responseForCoupon);
                            }

                            @Override
                            public void onGetCouponsError(List<QUICoupon> coupons, RetrofitError error) {
                                Toast.makeText(WearService.this, "onGetCouponsError", Toast.LENGTH_LONG).show();
                                responseForCoupon.setResponseType(QUIWearResponseType.ERROR);
                                responseForCoupon.setCouponList(coupons);
                                sender.responseForCouponRequest(responseForCoupon);
                            }

                            @Override
                            public void onGetChachedCoupons(List<QUICoupon> coupons) {
                                Toast.makeText(WearService.this, "onGetChachedCoupons", Toast.LENGTH_LONG).show();
                                responseForCoupon.setResponseType(QUIWearResponseType.ERROR);
                                responseForCoupon.setCouponList(coupons);
                                sender.responseForCouponRequest(responseForCoupon);
                            }

                            @Override
                            public void onUserNotLogged() {
                                Toast.makeText(WearService.this, "onUserNotLogged", Toast.LENGTH_LONG).show();
                                responseForCoupon.setResponseType(QUIWearResponseType.USER_NOT_LOGGED);
                                sender.responseForCouponRequest(responseForCoupon);
                            }
                        });
                        break;
                    case UNDEFINED:
                    case INVALID:
                        Toast.makeText(WearService.this, "INVALID", Toast.LENGTH_LONG).show();
                        responseForCoupon.setResponseType(QUIWearResponseType.USER_NOT_LOGGED);
                        sender.responseForCouponRequest(responseForCoupon);
                        break;
                }
            }
        });
    }
}
PROTOCOL

public interface WearProtocol {

    public void responseForCouponRequest(ResponseForCoupon responseForCoupon);

}

public interface SmartphoneProtocol {

public void askForCoupon();

}

@Parcel
public class ResponseForCoupon {

    QUIWearResponseType responseType;
    List<QUICoupon> couponList;

    public QUIWearResponseType getResponseType() {
        return responseType;
    }

    public void setResponseType(QUIWearResponseType responseType) {
        this.responseType = responseType;
    }

    public List<QUICoupon> getCouponList() {
        return couponList;
    }

    public void setCouponList(List<QUICoupon> couponList) {
        this.couponList = couponList;
    }

    @Override
    public String toString() {
        return "ResponseForCoupon{" +
                "responseType=" + responseType +
                ", couponList=" + couponList +
                '}';
    }
}

@Parcel
public enum QUIWearResponseType {

    OK("OK"), USER_NOT_ACTIVATED("USER_NOT_ACTIVATED"), USER_NOT_LOGGED("USER_NOT_LOGGED"), ERROR("ERROR");

    String code;

    QUIWearResponseType(String code){
        this.code=code;
    }

    public String getCode() {
        return code;
    }

    public static QUIWearResponseType getEnumByCode(String code) {
        for (QUIWearResponseType value : QUIWearResponseType.values()) {
            if (value.getCode().equals(code)) {
                return value;
            }
        }
        return null;
    }

}

QUICoupon model is a parcelable. to create parcel i use this lib https://github.com/johncarl81/parceler

florent37 commented 9 years ago

Ok I ever think to use parcelable in Emmet, but haven't implemented it yet, but I think it's time to add it.

For now I encode with gson when the type is not primary (not int,float,string,double...), but yes Parcelable is more efficient thant gson.

I'll try to add it as soon as possible, can you try to replace QUIWearResponseType with an String or Integer and try if it's working please ? It's just a small fix to continue your work until I continue the development of Emmet

croccio commented 9 years ago

it give me error :(

croccio commented 9 years ago

i replace it with integer

croccio commented 9 years ago

the list is very long. can this be a problem?

florent37 commented 9 years ago

I don't think so, gson can serialize/deserialize a list of 1000 elements or more. oh ! what's in QICoupon ?

croccio commented 9 years ago

package com.paybay.quiapi.model.answer;

import org.parceler.Parcel;

import java.util.Date; import java.util.List;

/**

@Parcel public class QUICoupon {

String ticketErpCode;
String barCodeUrl;
byte progTicketStatusTypeId;
String descTicketStatusType;
String ticketType;
Date expirationDate;
String title;
float value;
QUIPromotion promotionCampaign;
String progTicketValueTypeId;

public QUICoupon(){}

public String getTicketErpCode() {
    return ticketErpCode;
}

public void setTicketErpCode(String ticketErpCode) {
    this.ticketErpCode = ticketErpCode;
}

public String getBarCodeUrl() {
    return barCodeUrl;
}

public void setBarCodeUrl(String barCodeUrl) {
    this.barCodeUrl = barCodeUrl;
}

public byte getProgTicketStatusTypeId() {
    return progTicketStatusTypeId;
}

public void setProgTicketStatusTypeId(byte progTicketStatusTypeId) {
    this.progTicketStatusTypeId = progTicketStatusTypeId;
}

public String getDescTicketStatusType() {
    return descTicketStatusType;
}

public void setDescTicketStatusType(String descTicketStatusType) {
    this.descTicketStatusType = descTicketStatusType;
}

public String getTicketType() {
    return ticketType;
}

public void setTicketType(String ticketType) {
    this.ticketType = ticketType;
}

public Date getExpirationDate() {
    return expirationDate;
}

public void setExpirationDate(Date expirationDate) {
    this.expirationDate = expirationDate;
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public float getValue() {
    return value;
}

public void setValue(float value) {
    this.value = value;
}

public QUIPromotion getPromotionCampaign() {
    return promotionCampaign;
}

public void setPromotionCampaign(QUIPromotion promotionCampaign) {
    this.promotionCampaign = promotionCampaign;
}

public String getProgTicketValueTypeId() {
    return progTicketValueTypeId;
}

public void setProgTicketValueTypeId(String progTicketValueTypeId) {
    this.progTicketValueTypeId = progTicketValueTypeId;
}

}

croccio commented 9 years ago

i don't think the problem is in that class, because i can't send other custom object

florent37 commented 9 years ago

I don't know if gson can encode enums

croccio commented 9 years ago

i use classes without enums but with another custom object as property. i can use only simple object with "standard" object as object in sample

florent37 commented 9 years ago

ok, I'll try with a class containing another class as property

Class MySecondObject{ private String name; }

Class MyObject{ private MySecondObject mySecondObject; }

I come back to you ASAP

croccio commented 9 years ago

thank you very much! if your test is ok than i'll try to implement parcelable in a fork of lib (maybe parcelble don't give problem)

croccio commented 9 years ago

i make it works, but object's properties sended from smartphone to smart watch are null (on smartphone before send are with value)

florent37 commented 9 years ago

I'm now home I can work on Emmet, can you send me your objects witch have null values please, si I can test

florent37 commented 9 years ago

I made a small modification an it works on my sample, with

public class MyObject implements Serializable{
    private String name;

    private MySecondObject mySecondObject;
    private List<MySecondObject> list;

    public MyObject(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public MySecondObject getMySecondObject() {
        return mySecondObject;
    }

    public void setMySecondObject(MySecondObject mySecondObject) {
        this.mySecondObject = mySecondObject;
    }

    public List<MySecondObject> getList() {
        return list;
    }

    public void setList(List<MySecondObject> list) {
        this.list = list;
    }
}

and

public class MySecondObject implements Serializable {
    private String name;
    private int value;
    private float percent;

    public MySecondObject(String name, int value, float percent) {
        this.name = name;
        this.value = value;
        this.percent = percent;
    }

    public String getName() {
        return name;
    }

    public int getValue() {
        return value;
    }

    public float getPercent() {
        return percent;
    }
}
florent37 commented 9 years ago

I sent a new version, 1.0.1, can you check ?

croccio commented 9 years ago

Object is too big to push it via Google Play Services

i get it with another library, so i think problem could be this

florent37 commented 9 years ago

oh :/ try to send smaller objects containing just usefull informations / properties

croccio commented 9 years ago

you can close i've resolved

croccio commented 9 years ago

thank you :D