Tôi đang cố gắng tạo ứng dụng Android tương tác với Google App Engine để tải và lưu các thực thể trong kho dữ liệu của google. Tôi nghĩ rằng tôi có cấu hình chính xác, nhưng tôi không biết liệu tôi có thể tải lên ứng dụng của mình để kiểm tra nó hay không, nó chỉ bị treo vĩnh viễn và sau đó cung cấp cho tôi lỗi này:Không thể kết nối Google Datastore với Ứng dụng Android trong Android Studio
SEVERE: Endpoints configuration not updated. The app returned an error when the Google Cloud Endpoints server attempted to communicate with it.
Tuy nhiên, nếu tôi thay đổi số phiên bản sau đó phiên bản mới xuất hiện trong bảng điều khiển trực tuyến của tôi ngay cả sau khi nhận được thông báo này. Tôi đã đọc tất cả tài liệu của Google về Datastore và không thể tìm ra điều gì sai. Tôi đã gặp vấn đề này trong một tháng và không thể tìm được giải pháp. Tôi đọc ở đâu đó rằng nếu ứng dụng có lỗi, nó sẽ không được tải lên vì vậy tôi sẽ bao gồm tất cả các mã của tôi. Tôi cũng không thực sự biết những gì tôi đang làm một thậm chí không chắc chắn nếu tôi đang đi đúng hướng vì sao điều này không hiệu quả, vì vậy nếu bạn nhận thấy bất cứ điều gì ngu ngốc, bạn nên vui lòng cho tôi biết. Cảm ơn bạn trước, bạn sẽ là anh hùng của tôi và thần của tôi nếu bạn có thể sửa lỗi này cho tôi.
Đây là thiết bị đầu cuối của tôi:
package com.polo.backend.endpoints;
/**
* Created by sagesmith on 4/16/16.
*
* Is used to interact with the server
*/
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiNamespace;
import com.google.api.server.spi.response.ConflictException;
import com.google.api.server.spi.response.NotFoundException;
import com.googlecode.objectify.Ref;
import com.polo.backend.services.ObjcfyService;
import com.polo.backend.entities.Event;
import com.polo.backend.entities.User;
import java.util.List;
import javax.inject.Named;
/**
*
*/
@Api(
name = "userEndpoint",
version = "v1",
namespace = @ApiNamespace(
ownerDomain = "backend.polo.com",
ownerName = "backend.polo.com",
packagePath = ""
)
)
public class UserEndpoint {
/**
* Registers the two entities used in this class
*/
public UserEndpoint(){
ObjcfyService.register(User.class);
ObjcfyService.register(Event.class);
}
@ApiMethod(name = "insertUser")
/**
* Inserts a new {@code User} into the data store
*/
public void insertUser(User user) throws ConflictException, NotFoundException{
if(getUser(user.getUsername()) != null){
throw new ConflictException("Object already exists");
}
}
/**
*
* @param user
* @throws NotFoundException
*/
@ApiMethod(name = "updateUser")
public void updateUser(User user) throws NotFoundException{
if(getUser(user.getUsername()) != null) {
ObjcfyService.objectify().save().entity(user).now();
}
}
/**
*
* @param username
* @throws NotFoundException
*/
@ApiMethod(name = "removeUser")
public void removeUser(@Named("username") String username) throws NotFoundException{
User record = getUser(username);
if(record != null){
ObjcfyService.objectify().delete().entity(record).now();
}
}
/**
*
* @param username
* @return
* @throws NotFoundException
*/
@ApiMethod(name = "getUser")
public User getUser(@Named("username") String username) throws NotFoundException{
User user = ObjcfyService.objectify().load().type(User.class).id(username).now();
if(user != null) {
List<Ref<User>> friendRefs = user.getFriendRefs();
List<Ref<Event>> repeatingEventRefs = user.getRepeatingEventRefs();
List<Ref<Event>> nonRepeatingEventRefs = user.getNonRepeatingEventRefs();
for (Ref<User> friendRef : friendRefs) {
user.addFriend(friendRef.get());
}
for (Ref<Event> repeatingEventRef : repeatingEventRefs) {
user.addRepeatingEvent(repeatingEventRef.get());
}
for (Ref<Event> nonRepeatingEventRef : nonRepeatingEventRefs) {
user.addNonRepeatingEvent(nonRepeatingEventRef.get());
}
} else{
throw new NotFoundException("User not found");
}
return user;
}
}
Đây là thực thể của tôi User:
package com.polo.backend.entities;
/**
* Created by sagesmith on 4/16/16.
*/
import com.google.api.server.spi.config.AnnotationBoolean;
import com.google.api.server.spi.config.ApiResourceProperty;
import com.googlecode.objectify.Ref;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Index;
import com.googlecode.objectify.annotation.Load;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
@Entity
public class User {
@Id private String username = null;
@Index private String firstName = null;
@Index private String lastName = null;
@Nullable private String status = null;
@Nullable private String location = null;
@Load @Nullable private List<Ref<User>> friendRefs = new ArrayList<>();
@Load @Nullable private List<Ref<Event>> nonRepeatingEventRefs = new ArrayList<>();
@Load @Nullable private List<Ref<Event>> repeatingEventRefs = new ArrayList<>();
@Nullable public List<User> friends = new ArrayList<>();
@Nullable public List<Event> nonRepeatingEvents = new ArrayList<>();
@Nullable public List<Event> repeatingEvents = new ArrayList<>();
/**
*Returns the first name from the {@code User}
*
* @return the first name of the {@code User} as a {@code String}
*/
public String getFirstName(){
return firstName;
}
/**
* Returns the last name from the {@code User}
*
* @return the last name of the {@code User} as a {@code String}
*/
public String getLastName(){
return lastName;
}
/**
* Return the username from the user
*
* @return the username of the user as a String
*/
public String getUsername(){
return username;
}
/**
* Sets the username of the {@code User}
*
* @param username Username to set the {@code User}'s username to
*/
public void setUsername(String username){
this.username = username;
}
/**
* Sets the firstName of the {@code User}
*
* @param firstName First name to set the {@code User}'s first name to
*/
public void setFirstName(String firstName){
this.firstName = firstName;
}
/**
* Sets the lastName of the {@code User}
*
* @param lastName Last name to set the {@code User}'s last name to
*/
public void setLastName(String lastName){
this.lastName = lastName;
}
@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
/**
* Adds a friend to the {@code User}'s list of friends
*
* @param user User to add
*/
public void addFriendRef(User user){
friendRefs.add(Ref.create(user));
}
/**
* Returns the {@code User}'s friends
*
* @return {@code List<Users>} the friends of the {@code User}
*/
public List<User> getFriends(){
return friends;
}
/**
* Adds a friend to the users {@code List} of friends
*
* @param user {@code User} to add as a friend
*/
public void addFriend(User user){
friends.add(user);
}
@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
/**
* Returns a {@code List<Ref<User>>} of references to the {@code User}'s friends
*
* @return {@code List<Ref<User>>}
*/
public List<Ref<User>> getFriendRefs(){
return friendRefs;
}
@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
/**
* Returns a {@code List<Ref<Event>>} of references to the {@code User}'s repeating
* {@code Event}s
*
* @return {@code List<Ref<Event>>}
*/
public List<Ref<Event>> getRepeatingEventRefs(){
return repeatingEventRefs;
}
@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
/**
* Returns a {@code List<Ref<Event>>} of references to the {@code User}'s non repeating
* {@code Event}s
*
* @return {@code List<Ref<Event>>}
*/
public List<Ref<Event>> getNonRepeatingEventRefs(){
return nonRepeatingEventRefs;
}
@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
/**
* Sets the {@code User}'s status to a given {@code String}
*
* @param status {@code String} to set an {@code Users}'s status to
*/
public void setStatus(String status){
this.status = status;
}
/**
* Returns the {@code User}'s status as a {@code String}
*
* @return {@code String} status
*/
public String getStatus(){
return status;
}
/**
* Returns the {@code User}'s location as a {@code String}
*
* @return {@code String} location
*/
public String getLocation(){
return location;
}
/**
* Sets the {@code User}'s location to a given {@code String}
*
* @param location {@code String} to set an {@code Users}'s location to
*/
public void setLocation(String location){
this.location = location;
}
@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
/**
* Adds a repeating {@code Event} to the {@code User}'s schedule
*
* @param event {@code Event} to add to the {@code User}'s schedule
*/
public void addRepeatingEvent(Event event){
repeatingEventRefs.add(Ref.create(event));
}
@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
/**
* Adds a non repeating {@code Event} to the user's schedule
*
* @param event Event to add to the the user's schedule
*/
public void addNonRepeatingEvent(Event event){
nonRepeatingEventRefs.add(Ref.create(event));
}
/**
* Returns a {@code List<Event>} of repeating {@code Event}s from the user's schedule
*
* @return List<Event> repeatingEvents from user's schedule
*/
public List<Event> getRepeatingEvents(){
return repeatingEvents;
}
/**
* Returns a list of nonRepeatingEvents from the user's schedule
*
* @return List<Event> repeatingEvents from user's schedule
*/
public List<Event> getNonRepeatingEvents(){
return nonRepeatingEvents;
}
}
và đơn vị tổ chức sự kiện của tôi:
package com.polo.backend.entities;
import com.googlecode.objectify.annotation.Entity;
/**
* Created by sagesmith on 5/3/16.
*/
@Entity
public class Event {
private Integer startIndex;
private Integer endIndex;
private Byte[] color;
public Event(Integer startIndex, Integer endIndex, Byte red, Byte green, Byte blue){
this.startIndex = startIndex;
this.endIndex = endIndex;
color = new Byte[]{red, green, blue};
}
}
và ObjectifyService tôi:
package com.polo.backend.services;
/**
* Created by sagesmith on 4/16/16.
*/
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyFactory;
import com.googlecode.objectify.ObjectifyService;
public class ObjcfyService {
public static void register(Class<?> eClass){
ObjectifyService.register(eClass);
}
public static Objectify objectify(){
return ObjectifyService.ofy();
}
public static ObjectifyFactory objectifyFactory(){
return ObjectifyService.factory();
}
}
Sau đây là tôi appengine-web.xml, tôi đã thay thế APPID tôi với my_id vì những lý do rõ ràng:
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>my_id</application>
<version>1</version>
<threadsafe>true</threadsafe>
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
</system-properties>
Đây là web.xml của tôi
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<servlet>
<servlet-name>SystemServiceServlet</servlet-name>
<servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
<init-param>
<param-name>services</param-name>
<param-value>com.polo.backend.endpoints.UserEndpoint</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SystemServiceServlet</servlet-name>
<url-pattern>/_ah/spi/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
Cuối cùng ở đây là AsyncTask tôi sử dụng để liên lạc với kho dữ liệu từ ứng dụng Android của tôi, tôi đã thay thế ID ứng dụng của mình bằng my_id lần nữa:
package com.polo.client;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.extensions.android.json.AndroidJsonFactory;
import com.polo.StaticAssets;
import com.polo.activity.Home;
import com.polo.backend.userEndpoint.UserEndpoint;
import com.polo.backend.userEndpoint.model.User;
import java.io.IOException;
/**
* Created by sagesmith on 4/17/16.
*/
public class UserAsyncTask extends AsyncTask<Void, Void, User>{
private static UserEndpoint userApiService = null;
private Home context;
private String username;
/**
*
* @param context
*/
public UserAsyncTask(Home context){
this.context = context;
username = StaticAssets.getUserName(context);
}
/**
*
* @param params
* @return
*/
@Override
protected User doInBackground(Void... params){
if(userApiService == null){
UserEndpoint.Builder builder = new UserEndpoint.Builder(
AndroidHttp.newCompatibleTransport(),
new AndroidJsonFactory(),
null
)
.setRootUrl("https://my_id.appspot.com/_ah/api/");
userApiService = builder.build();
}
User user = null;
try{
user = userApiService.getUser(username).execute();
} catch (IOException e){
Log.e("User not found", e.getMessage());
}
return user;
}
/**
*
* @param result
*/
@Override
protected void onPostExecute(User result) {
if(result!=null)
Toast.makeText(context, result.getFirstName(), Toast.LENGTH_LONG).show();
}
}
Tôi hỏi một đồng nghiệp và ông nghĩ rằng nó là một cái gì đó để làm với bất cứ điều gì tương đương với Java là cho app.yaml –