--- a/src/com/beem/project/beem/service/XmppConnectionAdapter.java Sun Aug 12 11:38:12 2012 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,768 +0,0 @@
-/*
- BEEM is a videoconference application on the Android Platform.
-
- Copyright (C) 2009 by Frederic-Charles Barthelery,
- Jean-Manuel Da Silva,
- Nikita Kozlov,
- Philippe Lago,
- Jean Baptiste Vergely,
- Vincent Veronis.
-
- This file is part of BEEM.
-
- BEEM is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- BEEM is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with BEEM. If not, see <http://www.gnu.org/licenses/>.
-
- Please send bug reports with examples or suggestions to
- contact@beem-project.com or http://dev.beem-project.com/
-
- Epitech, hereby disclaims all copyright interest in the program "Beem"
- written by Frederic-Charles Barthelery,
- Jean-Manuel Da Silva,
- Nikita Kozlov,
- Philippe Lago,
- Jean Baptiste Vergely,
- Vincent Veronis.
-
- Nicolas Sadirac, November 26, 2009
- President of Epitech.
-
- Flavien Astraud, November 26, 2009
- Head of the EIP Laboratory.
-
- */
-package com.beem.project.beem.service;
-
-import java.text.SimpleDateFormat;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Iterator;
-
-import org.jivesoftware.smack.ConnectionConfiguration;
-import org.jivesoftware.smack.ConnectionListener;
-import org.jivesoftware.smack.PacketListener;
-import org.jivesoftware.smack.PrivacyListManager;
-import org.jivesoftware.smack.RosterListener;
-import org.jivesoftware.smack.XMPPConnection;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.filter.PacketFilter;
-import org.jivesoftware.smack.packet.Message;
-import org.jivesoftware.smack.packet.Packet;
-import org.jivesoftware.smack.packet.Presence;
-import org.jivesoftware.smack.util.StringUtils;
-import org.jivesoftware.smackx.ChatStateManager;
-import org.jivesoftware.smackx.ServiceDiscoveryManager;
-import org.jivesoftware.smackx.packet.DiscoverInfo;
-
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.RemoteCallbackList;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.beem.project.beem.BeemApplication;
-import com.beem.project.beem.BeemIntent;
-import com.beem.project.beem.BeemService;
-import com.beem.project.beem.R;
-import com.beem.project.beem.providers.Messages;
-import com.beem.project.beem.service.aidl.IBeemConnectionListener;
-import com.beem.project.beem.service.aidl.IXmppConnection;
-import com.beem.project.beem.smack.avatar.AvatarCache;
-import com.beem.project.beem.smack.avatar.AvatarManager;
-import com.beem.project.beem.smack.pep.PepSubManager;
-import com.beem.project.beem.ui.Subscription;
-import com.beem.project.beem.utils.BeemBroadcastReceiver;
-import com.beem.project.beem.utils.Status;
-
-/**
- * This class implements an adapter for XMPPConnection.
- * @author darisk
- */
-public class XmppConnectionAdapter extends IXmppConnection.Stub {
-
- /**
- * Beem connection closed Intent name.
- */
-
- private static final int SMACK_PRIORITY_MIN = -128;
- private static final int SMACK_PRIORITY_MAX = 128;
- private static final String TAG = "XMPPConnectionAdapter";
- private final XMPPConnection mAdaptee;
- private final String mLogin;
- private final String mPassword;
- private String mResource;
- private String mErrorMsg;
- private int mPreviousPriority;
- private int mPreviousMode;
- private String mPreviousStatus;
- private ChatStateManager mChatStateManager;
- private final BeemService mService;
- private BeemApplication mApplication;
- private AvatarManager mAvatarManager;
- private PepSubManager mPepManager;
- private SharedPreferences mPref;
- private final RemoteCallbackList<IBeemConnectionListener> mRemoteConnListeners = new RemoteCallbackList<IBeemConnectionListener>();
- private final SubscribePacketListener mSubscribePacketListener = new SubscribePacketListener();
-
- //private final ConnexionListenerAdapter mConListener = new ConnexionListenerAdapter();
-
- /**
- * Constructor.
- * @param config Configuration to use in order to connect
- * @param login login to use on connect
- * @param password password to use on connect
- * @param service the background service associated with the connection.
- */
- public XmppConnectionAdapter(final ConnectionConfiguration config, final String login, final String password,
- final BeemService service) {
- this(new XMPPConnection(config), login, password, service);
- }
-
- /**
- * Constructor.
- * @param serviceName name of the service to connect to
- * @param login login to use on connect
- * @param password password to use on connect
- * @param service the background service associated with the connection.
- */
- public XmppConnectionAdapter(final String serviceName, final String login, final String password,
- final BeemService service) {
- this(new XMPPConnection(serviceName), login, password, service);
- }
-
- /**
- * Constructor.
- * @param con The connection to adapt
- * @param login The login to use
- * @param password The password to use
- * @param service the background service associated with the connection.
- */
- public XmppConnectionAdapter(final XMPPConnection con, final String login, final String password,
- final BeemService service) {
- mAdaptee = con;
- PrivacyListManager.getInstanceFor(mAdaptee);
- mLogin = StringUtils.parseName(login);
-
- mPassword = password;
- mService = service;
- Context ctx = mService.getApplicationContext();
- if (ctx instanceof BeemApplication) {
- mApplication = (BeemApplication) ctx;
- }
- mPref = mService.getServicePreference(login); // login is the jid
- try {
- mPreviousPriority = Integer.parseInt(mPref.getString("settings_key_priority", "0"));
- } catch (NumberFormatException ex) {
- mPreviousPriority = 0;
- }
- mResource = mPref.getString("settings_key_resource", "BEEM");
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void addConnectionListener(IBeemConnectionListener listen) throws RemoteException {
- if (listen != null)
- mRemoteConnListeners.register(listen);
- }
-
- @Override
- public boolean connect() throws RemoteException {
- if (mAdaptee.isConnected())
- return true;
- else {
- try {
- mAdaptee.connect();
- return true;
- } catch (XMPPException e) {
- Log.e(TAG, "Error while connecting", e);
- try {
- //TODO NIKITA DOES SOME SHIT !!! Fix this monstruosity
- String str = mService.getResources().getString(
- mService.getResources().getIdentifier(e.getXMPPError().getCondition().replace("-", "_"),
- "string", "com.beem.project.beem"));
- mErrorMsg = str;
- } catch (NullPointerException e2) {
- if (!"".equals(e.getMessage()))
- mErrorMsg = e.getMessage();
- else
- mErrorMsg = e.toString();
- }
- }
- return false;
- }
- }
-
- @Override
- public boolean login() throws RemoteException {
- if (mAdaptee.isAuthenticated())
- return true;
- if (!mAdaptee.isConnected())
- return false;
- try {
-
- this.initFeatures(); // pour declarer les features xmpp qu'on
- // supporte
-
- PacketFilter filter = new PacketFilter() {
-
- @Override
- public boolean accept(Packet packet) {
- if (packet instanceof Presence) {
- Presence pres = (Presence) packet;
- if (pres.getType() == Presence.Type.subscribe)
- return true;
- } else if (packet instanceof Message) {
- return true;
- }
- return false;
- }
- };
-
- mAdaptee.addPacketListener(mSubscribePacketListener, filter);
- mAdaptee.login(mLogin, mPassword, mResource);
-
- BeemService.StreamHandlingPacket enablePacket = new BeemService.StreamHandlingPacket("enable", "urn:xmpp:sm:2");
- enablePacket.addAttribute("resume", "true");
- mAdaptee.sendPacket(enablePacket);
-
- //mChatManager = new BeemChatManager(mAdaptee.getChatManager(), mService);
- //nikita: I commented this line because of the logs provided in http://www.beem-project.com/issues/321
- //Also, since the privacylistmanager isn't finished and used, it will be safer to not initialize it
- //mPrivacyListManager = new PrivacyListManagerAdapter(PrivacyListManager.getInstanceFor(mAdaptee));
- mService.initJingle(mAdaptee);
- discoverServerFeatures();
-
- mAdaptee.getRoster().addRosterListener(new SubscribeRosterListener());
-
- mApplication.setConnected(true);
- int mode = mPref.getInt(BeemApplication.STATUS_KEY, 0);
- String status = mPref.getString(BeemApplication.STATUS_TEXT_KEY, "");
- changeStatus(mode, status);
- return true;
- } catch (XMPPException e) {
- Log.e(TAG, "Error while connecting", e);
- mErrorMsg = mService.getString(R.string.error_login_authentication);
- return false;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public final void connectAsync() throws RemoteException {
- if (mAdaptee.isConnected() || mAdaptee.isAuthenticated())
- return;
- Thread t = new Thread(new Runnable() {
-
- @Override
- public void run() {
- try {
- connectSync();
- } catch (RemoteException e) {
- Log.e(TAG, "Error while connecting asynchronously", e);
- }
- }
- });
- t.start();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean connectSync() throws RemoteException {
- if (connect())
- return login();
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void changeStatusAndPriority(int status, String msg, int priority) {
- Presence pres = new Presence(Presence.Type.available);
- String m;
- if (msg != null)
- m = msg;
- else
- m = mPreviousStatus;
- pres.setStatus(m);
- mPreviousStatus = m;
- Presence.Mode mode = Status.getPresenceModeFromStatus(status);
- if (mode != null) {
- pres.setMode(mode);
- mPreviousMode = status;
- } else {
- pres.setMode(Status.getPresenceModeFromStatus(mPreviousMode));
- }
- int p = priority;
- if (priority < SMACK_PRIORITY_MIN)
- p = SMACK_PRIORITY_MIN;
- if (priority > SMACK_PRIORITY_MAX)
- p = SMACK_PRIORITY_MAX;
- mPreviousPriority = p;
- pres.setPriority(p);
- mAdaptee.sendPacket(pres);
- updateNotification(m);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void changeStatus(int status, String msg) {
- changeStatusAndPriority(status, msg, mPreviousPriority);
- }
-
- /**
- * Get the AvatarManager of this connection.
- * @return the AvatarManager or null if there is not
- */
- public AvatarManager getAvatarManager() {
- return mAvatarManager;
- }
-
- /**
- * get the previous status.
- * @return previous status.
- */
- public String getPreviousStatus() {
- return mPreviousStatus;
- }
-
- /**
- * get the previous mode.
- * @return previous mode.
- */
- public int getPreviousMode() {
- return mPreviousMode;
- }
-
- /**
- * Update the notification for the Beem status.
- * @param text the text to display.
- */
- private void updateNotification(String text) {
-
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean disconnect() {
- if (mAdaptee != null && mAdaptee.isConnected())
- mAdaptee.disconnect();
- return true;
- }
-
- /**
- * Get the Smack XmppConnection.
- * @return Smack XmppConnection
- */
- public XMPPConnection getAdaptee() {
- return mAdaptee;
- }
-
- /**
- * Returns true if currently authenticated by successfully calling the login method.
- * @return true when successfully authenticated
- */
- public boolean isAuthentificated() {
- return mAdaptee.isAuthenticated();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void removeConnectionListener(IBeemConnectionListener listen) throws RemoteException {
- if (listen != null)
- mRemoteConnListeners.unregister(listen);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getErrorMessage() {
- return mErrorMsg;
- }
-
-
- /**
- * Initialize the features provided by beem.
- */
- private void initFeatures() {
- ServiceDiscoveryManager.setIdentityName("Beem");
- ServiceDiscoveryManager.setIdentityType("phone");
- ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(mAdaptee);
- if (sdm == null)
- sdm = new ServiceDiscoveryManager(mAdaptee);
-
- sdm.addFeature("http://jabber.org/protocol/disco#info");
- //nikita: must be uncommented when the feature will be enabled
- //sdm.addFeature("jabber:iq:privacy");
- sdm.addFeature("http://jabber.org/protocol/caps");
- sdm.addFeature("urn:xmpp:avatar:metadata");
- sdm.addFeature("urn:xmpp:avatar:metadata+notify");
- sdm.addFeature("urn:xmpp:avatar:data");
- sdm.addFeature("http://jabber.org/protocol/nick");
- sdm.addFeature("http://jabber.org/protocol/nick+notify");
-
- mChatStateManager = ChatStateManager.getInstance(mAdaptee);
- BeemCapsManager caps = new BeemCapsManager(sdm, mAdaptee, mService);
- caps.setNode("http://www.beem-project.com");
- }
-
- /**
- * Discover the features provided by the server.
- */
- private void discoverServerFeatures() {
- try {
- // jid et server
- ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(mAdaptee);
- DiscoverInfo info = sdm.discoverInfo(mAdaptee.getServiceName());
- Iterator<DiscoverInfo.Identity> it = info.getIdentities();
- while (it.hasNext()) {
- DiscoverInfo.Identity identity = it.next();
- if ("pubsub".equals(identity.getCategory()) && "pep".equals(identity.getType())) {
- initPEP();
- }
- }
- } catch (XMPPException e) {
- // No Pep
- }
- }
-
- /**
- * Initialize PEP.
- */
- private void initPEP() {
- // Enable pep sending
- // API 8
- // mService.getExternalCacheDir()
- mPepManager = new PepSubManager(mAdaptee);
- AvatarCache avatarCache = new BeemAvatarCache(mService);
- mAvatarManager = new AvatarManager(mAdaptee, mPepManager, avatarCache, true);
- }
-
- /**
- * Listener for XMPP connection events. It will calls the remote listeners for connection events.
- * @author darisk
- */
- private class ConnexionListenerAdapter implements ConnectionListener {
-
- /**
- * Defaut constructor.
- */
- public ConnexionListenerAdapter() {
- }
-
- /**
- * {@inheritDoc}
- */
- /**
- * // * Listener. //
- */
- // private class MsgListener implements ChatStateListener {
- // /**
- // * Constructor.
- // */
- // public MsgListener() {
- // }
- //
- // @Override
- // public void processMessage(Chat chat, org.jivesoftware.smack.packet.Message message) {
- // Message msg = new Message(message);
- // Log.e(TAG, "Message : " + msg.getBody());
- // SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- // // note that we don't have to add an id as our table set id as autoincrement
- // ContentValues values = new ContentValues();
- // values.put(Messages.FROM, msg.getFrom());
- // values.put(Messages.MESSAGE_ID, "message id");
- // values.put(Messages.TO, msg.getTo());
- // values.put(Messages.TYPE, msg.getType());
- // values.put(Messages.SUBJECT, "SUBJECT");
- // values.put(Messages.BODY, msg.getBody());
- // values.put(Messages.THREAD, "THREAD");
- // values.put(Messages.EXTRAS, "EXTRAS");
- // values.put(Messages.IS_RECEIVE, true);
- // values.put(Messages.DATE_RECEIVE, dateFormat.format(new Date()));
- // values.put(Messages.DATE_READ, dateFormat.format(msg.getTimestamp()));
- // mService.getContentResolver().insert(Messages.CONTENT_URI, values);
- // }
- //
- // /**
- // * {@inheritDoc}
- // */
- // @Override
- // public void stateChanged(Chat chat, ChatState state) {
- // }
- //
- // }
- @Override
- public void connectionClosed() {
- Log.d(TAG, "closing connection");
- Intent intent = new Intent(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED);
- intent.putExtra("message", mService.getString(R.string.BeemBroadcastReceiverDisconnect));
- intent.putExtra("normally", true);
- mService.sendBroadcast(intent);
- mService.stopSelf();
- mApplication.setConnected(false);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void connectionClosedOnError(Exception exception) {
- Log.d(TAG, "connectionClosedOnError");
- Intent intent = new Intent(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED);
- intent.putExtra("message", exception.getMessage());
- mService.sendBroadcast(intent);
- mService.stopSelf();
- mApplication.setConnected(false);
- }
-
- /**
- * Connection failed callback.
- * @param errorMsg smack failure message
- */
- public void connectionFailed(String errorMsg) {
- Log.d(TAG, "Connection Failed");
- final int n = mRemoteConnListeners.beginBroadcast();
-
- for (int i = 0; i < n; i++) {
- IBeemConnectionListener listener = mRemoteConnListeners.getBroadcastItem(i);
- try {
- if (listener != null)
- listener.connectionFailed(errorMsg);
- } catch (RemoteException e) {
- // The RemoteCallbackList will take care of removing the
- // dead listeners.
- Log.w(TAG, "Error while triggering remote connection listeners", e);
- }
- }
- mRemoteConnListeners.finishBroadcast();
- mService.stopSelf();
- mApplication.setConnected(false);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void reconnectingIn(int arg0) {
- Log.d(TAG, "reconnectingIn");
- final int n = mRemoteConnListeners.beginBroadcast();
-
- for (int i = 0; i < n; i++) {
- IBeemConnectionListener listener = mRemoteConnListeners.getBroadcastItem(i);
- try {
- if (listener != null)
- listener.reconnectingIn(arg0);
- } catch (RemoteException e) {
- // The RemoteCallbackList will take care of removing the
- // dead listeners.
- Log.w(TAG, "Error while triggering remote connection listeners", e);
- }
- }
- mRemoteConnListeners.finishBroadcast();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void reconnectionFailed(Exception arg0) {
- Log.d(TAG, "reconnectionFailed");
- final int r = mRemoteConnListeners.beginBroadcast();
-
- for (int i = 0; i < r; i++) {
- IBeemConnectionListener listener = mRemoteConnListeners.getBroadcastItem(i);
- try {
- if (listener != null)
- listener.reconnectionFailed();
- } catch (RemoteException e) {
- // The RemoteCallbackList will take care of removing the
- // dead listeners.
- Log.w(TAG, "Error while triggering remote connection listeners", e);
- }
- }
- mRemoteConnListeners.finishBroadcast();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void reconnectionSuccessful() {
- Log.d(TAG, "reconnectionSuccessful");
- mApplication.setConnected(true);
- PacketFilter filter = new PacketFilter() {
-
- @Override
- public boolean accept(Packet packet) {
- if (packet instanceof Presence) {
- Presence pres = (Presence) packet;
- if (pres.getType() == Presence.Type.subscribe)
- return true;
- }
- return false;
- }
- };
-
- mAdaptee.addPacketListener(new PacketListener() {
-
- @Override
- public void processPacket(Packet packet) {
- String from = packet.getFrom();
- Notification notif = new Notification(android.R.drawable.stat_notify_more, mService.getString(
- R.string.AcceptContactRequest, from), System.currentTimeMillis());
- notif.flags = Notification.FLAG_AUTO_CANCEL;
- Intent intent = new Intent(mService, Subscription.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).putExtra("from", from);
- notif.setLatestEventInfo(mService, from,
- mService.getString(R.string.AcceptContactRequestFrom, from),
- PendingIntent.getActivity(mService, 0, intent, PendingIntent.FLAG_ONE_SHOT));
- int id = packet.hashCode();
- mService.sendNotification(id, notif);
- }
- }, filter);
-
- final int n = mRemoteConnListeners.beginBroadcast();
-
- for (int i = 0; i < n; i++) {
- IBeemConnectionListener listener = mRemoteConnListeners.getBroadcastItem(i);
- try {
- if (listener != null)
- listener.reconnectionSuccessful();
- } catch (RemoteException e) {
- // The RemoteCallbackList will take care of removing the
- // dead listeners.
- Log.w(TAG, "Error while triggering remote connection listeners", e);
- }
- }
- mRemoteConnListeners.finishBroadcast();
- }
- }
-
- /**
- * This PacketListener will set a notification when you got a subscribtion request.
- * @author Da Risk <da_risk@elyzion.net>
- */
- private class SubscribePacketListener implements PacketListener {
-
- /**
- * Constructor.
- */
- public SubscribePacketListener() {
- }
-
- @Override
- public void processPacket(Packet packet) {
- Log.e(TAG, "suscribe packet" + packet.getClass().toString());
- if (packet instanceof Presence) {
- Presence p = (Presence) packet;
- if (p.getType() != Presence.Type.subscribe)
- return;
- String from = p.getFrom();
- Notification notification = new Notification(android.R.drawable.stat_notify_more, mService.getString(
- R.string.AcceptContactRequest, from), System.currentTimeMillis());
- notification.flags = Notification.FLAG_AUTO_CANCEL;
- Intent intent = new Intent(mService, Subscription.class);
- intent.setData(makeXmppUri(from));
- notification.setLatestEventInfo(mService, from,
- mService.getString(R.string.AcceptContactRequestFrom, from),
- PendingIntent.getActivity(mService, 0, intent, PendingIntent.FLAG_ONE_SHOT));
- int id = p.hashCode();
- mService.sendNotification(id, notification);
- } else if (packet instanceof Message) {
- Message message = (Message) packet;
-
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- // note that we don't have to add an id as our table set id as autoincrement
- ContentValues values = new ContentValues();
- values.put(Messages.FROM, message.getFrom());
- values.put(Messages.MESSAGE_ID, "message id");
- values.put(Messages.TO, message.getTo());
- values.put(Messages.TYPE, message.getType().toString());
- values.put(Messages.SUBJECT, "SUBJECT");
- values.put(Messages.BODY, message.getBody());
- values.put(Messages.THREAD, message.getThread());
- values.put(Messages.EXTRAS, "");
- values.put(Messages.IS_RECEIVE, true);
- values.put(Messages.DATE_RECEIVE, dateFormat.format(new Date()));
- values.put(Messages.DATE_READ, dateFormat.format(new Date()));
- mService.getContentResolver().insert(Messages.CONTENT_URI, values);
- }
- }
- }
-
- private class SubscribeRosterListener implements RosterListener {
-
- @Override
- public void entriesAdded(Collection<String> addresses) {
- Log.e(TAG, "entriesAdded");
- }
-
- @Override
- public void entriesUpdated(Collection<String> addresses) {
- Log.e(TAG, "entriesUpdated");
- }
-
- @Override
- public void entriesDeleted(Collection<String> addresses) {
- Log.e(TAG, "entriesDeleted");
- }
-
- @Override
- public void presenceChanged(Presence presence) {
- Log.e(TAG, "presenceChanged");
- }
-
- }
-
- /**
- * Make an xmpp uri for a spcific jid.
- * @param jid the jid to represent as an uri
- * @return an uri representing this jid.
- */
- public static Uri makeXmppUri(String jid) {
- StringBuilder build = new StringBuilder("xmpp:");
- String name = StringUtils.parseName(jid);
- build.append(name);
- if (!"".equals(name))
- build.append('@');
- build.append(StringUtils.parseServer(jid));
- String resource = StringUtils.parseResource(jid);
- if (!"".equals(resource)) {
- build.append('/');
- build.append(resource);
- }
- Uri u = Uri.parse(build.toString());
- return u;
- }
-
-}