First please pay attention when you say unknown fields. In protobuf you can have unknown fields by definition but on the other hand - and I suppose this is your case - you can have fields that you not having in your current proto file.
In both situation you can easily access the values. Let say you have a proto message named foo.
You have to access the descriptor and get the fields from there by name, and lastly get the values exemplified like below:
Builder builder = foo.toBuilder();
FieldDescriptor field = builder.getDescriptorForType().findFieldByName("whatever field");
Object obj = builder.getField(field);
// if your field is int32 cast to int
int value = (int) obj
If you wish to write the 'unknown' value you could proceed the other way around:
Builder builder = foo.toBuilder();
FieldDescriptor field = builder.getDescriptorForType().findFieldByName("whatever field");
builder.setField(field, 100); // 100 is an example int value
Foo foo = builder.build();
In case if you really want to insert proto defined unknown fields you have to do something like:
UnknownFieldSet.Field seqField = UnknownFieldSet.Field
.newBuilder()
.addFixed32(100) // 100 is an example int value
.build();
UnknownFieldSet unkFieldSet = UnknownFieldSet
.newBuilder()
.addField(99, seqField) // 99 is a proto index number chosen by me
.build();
Foo message = foo.toBuilder().setUnknownFields(unkFieldSet).build();
Reading the defined unknown fields are again is done by the:
foo.toBuilder().getUnknownFields()....
I hope this helps.