Free file sharing
REST API SOAP API My Application

Java

CreateFolderDemo.java
DeleteFileDemo.java
Demo.java
DownloadDemo.java
EnumerateItemsDemo.java
EnumerateItemsDemo2.java
LoginDemo.java
RecycleBinDemo.java
RenameDemo.java
SignupDemo.java
StringUtils.java
UploadDemo.java

PHP

File upload process:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Upload</title>
</head>

<body>

 <form action="<?echo $PHP_SELF;?>" method="post" enctype="multipart/form-data">
 <input name="myfile" type="file" /><br />
 <input name="submit" type="submit" value="Upload to 4shared" />
 </form>

 <?
 //User credentials on 4shared
 $user_login = "a5642551@nepwk.com";
 $user_password = "123123";

 if (isset ($_POST['submit'])) {

 $fileLocal = $_FILES['myfile']['tmp_name']; // This is the entire file that was uploaded to a temp location.
 $fileName = $_FILES['myfile']['name'];
 $fileSize = $_FILES['myfile']['size'];

 $client = new SoapClient("https://api.4shared.com/jax3/DesktopApp?wsdl", array(
  "cache_wsdl" => WSDL_CACHE_DISK,
  "trace" => 1,
  "exceptions" => 0
  )
  );

 $client->yourFunction();

 //Let's look if we have enough free space in user's account
 $freeSpace = $client->getFreeSpace($user_login, $user_password);

 //Check upload limit for user
 $maxSize = $client->getMaxFileSize($user_login, $user_password);

 if ($fileSize > $maxSize) die("<b>Error: Your file is too big</b>");
 else if ($fileSize > $freeSpace) die("<b>Error: Not enough space in account</b>");

 //Get Session Key for file upload. -1 means uploading file into root folder
 $session = $client->createUploadSessionKey($user_login, $user_password, -1);

 //Get datacenter
 $datacenter = $client->getNewFileDataCenter($user_login, $user_password, -1);
 if ($datacenter <= 0) die("<b>Error: Something went wrong</b>");

 //Get Upload Url
 $uploadUrl = $client->getUploadFormUrl($datacenter, $session);

 //Reserve fileId for our upload
 $fileId = $client->uploadStartFile($user_login, $user_password, -1, $fileName, $fileSize);

 //Send file and params via post request

  $post_params = array(
  'resumableFileId' => $fileId,
  'resumableFirstByte' => 0,
  'FilePart' => '@'.$fileLocal
  );

  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $uploadUrl);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $post_params);
  $req = curl_exec($ch);
  curl_close($ch);

 $finish = $client->uploadFinishFile($user_login, $user_password, $fileId, md5_file($fileLocal));

 if($finish == "") {echo "File uploaded";}

 }

 ?>

</body>
</html>

iOS

Every application in iOS can use 4s.io service. The client can interact with 4s.io server via SOAP protocol, by means of calling up 4s.io API functions. These functions may be used to request for the content of your account, get the necessary links to files, and edit the file structure and the directory properties on the server. The full description of the api is provided here. The SOAP-protocol may be checked here.

To call up 4s.io api-function, it's necessary to send the XML-message to server http://api.4shared.com/jax3/DesktopApp SOAP.

The common template for the message is the following:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" <br>xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>

  <function xmlns="http://api.soap.shared.pmstation.com/">
   <arg0 xmlns="">login</arg0>
   <arg1 xmlns="">password</arg1>
   <arg2 xmlns="">arg1</arg2>
   ...
  </function>
 </soapenv:Body>
</soapenv:Envelope>

- where "function" is the name of the called function.

Having indicated the function, one should enlist its arguments. There're only 2 arguments in almost all 4s.io api-functions - these are login and password.

In response to the call, 4s.io server will return the results of the function, the SOAP-message in XML-format:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <ns2:functionResponse xmlns:ns2="http://api.soap.shared.pmstation.com/">
   <return>
    result
   </return>
  </ns2: functionResponse>
 </S:Body>
</S:Envelope>

- where "result" is the result of calling up the "function".

As an example, we need to get the content of the directory. To do this, we need to call the function "getItems".

Its first 2 arguments are, as usual, login and password. The 3rd one is the ID of the requested directory.

The body of the relative SOAP-message will be as follows:

<getItems xmlns="http://api.soap.shared.pmstation.com/">
 <arg0 xmlns="">username@server.com</arg0>
 <arg1 xmlns="">*********</arg1>
 <arg2 xmlns="">123456789</arg2>
</getItems>

In response, 4s.io server will return the array with the elements of directory:

<item>
 <date>(date of file creation)</date>
 <directory>(true - if file is a directory, otherwise - false)</directory>
 <downloadCount>(the number of file downloads)</downloadCount>
 <downloadLink>(link for the file-download from 4shared-server)</downloadLink>
 <id>(file ID)</id>
 <md5>(md5-hash)</md5>
 <name>(name)</name>
 <parentId>(parent directory ID)</parentId>
 <size>(size)</size>
 ...
</item>

Let's consider the example of the simple application, which allows the user to browse the content of his/her account.

The 1st thing, which should be done, when starting the program, is to authorize (login) on 4s.io server by means of calling up the function "login".

If authorization is passed successfully, the next step will be the request for the root account directory by means of calling up the function "getRoot". The calling result will be the structure "item", described above.

To store received information, I've created subclass File:

@interface File : NSObject
{
 NSUInteger _id;
 NSUInteger _parentId;
 NSString *_name;
 NSUInteger _size;
 NSString *_link;
 BOOL _dir;

 NSArray *_content;
}

...

@end

Now that we have the root directory ID, we can use the function "getItems", to get its content, and then the content of any subdirectory.

To create the XML-formatted message and the parsing of received result, it's possible to use any XML - parser. In the demo-sample, I've used GDataXML-parser from Google Data APIs Objective-C Client Library.

The function to generate the message may be as follows:

+ (NSURLRequest*)soapRequestWithFunction:(NSString*)function andParams:(NSArray*)params
{
 GDataXMLElement *xmlFunction = [GDataXMLNode elementWithName:function];
 GDataXMLNode *xmlNS = [GDataXMLNode namespaceWithName:nil stringValue:@"http://api.soap.shared.pmstation.com/"];
 [xmlFunction addNamespace:xmlNS];

 for (NSUInteger i = 0; i < [params count]; i++)
 {
  NSString *elementName = [NSString stringWithFormat:@"arg%lu", i];
  GDataXMLElement *arg = [GDataXMLNode elementWithName:elementName];
  NSString *param = (NSString*)[params objectAtIndex:i];
  [arg setStringValue:(NSString*) param];
  GDataXMLNode *attrib = [GDataXMLNode attributeWithName:@"xmlns" stringValue:@""];
  [arg addAttribute:attrib];
  [xmlFunction addChild:arg];
 }

 GDataXMLElement *body = [GDataXMLNode elementWithName:@"soapenv:Body"];
 [body addChild:xmlFunction];

 GDataXMLElement *soapEnvelope = [GDataXMLNode elementWithName:@"soapenv:Envelope"];
 GDataXMLNode *soapNS1 = [GDataXMLNode namespaceWithName:@"soapenv" stringValue:@"http://schemas.xmlsoap.org/soap/envelope/"];
 GDataXMLNode *soapNS2 = [GDataXMLNode namespaceWithName:@"xsd" stringValue:@"http://www.w3.org/2001/XMLSchema"];
 GDataXMLNode *soapNS3 = [GDataXMLNode namespaceWithName:@"xsi" stringValue:@"http://www.w3.org/2001/XMLSchema-instance"];
 [soapEnvelope setNamespaces:[NSArray arrayWithObjects:soapNS1, soapNS2, soapNS3, nil]];
 [soapEnvelope addChild:body];

 GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithRootElement:soapEnvelope];
 [doc setVersion:@"1.0"];
 [doc setCharacterEncoding:@"UTF-8"];
 NSData *data = [doc XMLData];
 [doc release];
 NSString *dataLen = [NSString stringWithFormat:@"%lu", [data length]];

 NSURL *url = [NSURL URLWithString:@"http://api.4shared.com/jax3/DesktopApp"];
 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
 [request addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
 [request addValue:@"" forHTTPHeaderField:@"SOAPAction"];
 [request addValue:dataLen forHTTPHeaderField:@"Content-Length"];
 [request setHTTPMethod:@"POST"];
 [request setHTTPBody: data];

 return request;
}

The content of the directory is shown in the table (class FilesViewController). I show its name and size in the cell, related to the file accordingly:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
 ...
 cell.accessoryType = file.isDir ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;
 cell.imageView.image = file.isDir ? [UIImage imageNamed:@"dir.png"] : nil;
 cell.textLabel.text = file.name;
 cell.detailTextLabel.text = file.isFile ? [NSString stringWithFormat:@"%.2f Kb", (CGFloat) file.size / 1024.0] : nil;
 ...
}

All content is opened via tap in the cell with directory. The page with the following link is opened in the browser via tap on the file:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
 ...
 if (file.isDir)
 {
  FilesViewController *fvc = [[FilesViewController alloc] initWithFile:file];
   [self.navigationController pushViewController:fvc animated:YES];
   [fvc release];
 }
 else
 {
   [[UIApplication sharedApplication] openURL:[NSURL URLWithString:file.link]];
 }
 ...
}

The demo-sample can be downloaded here.

To start the sample application, enter demo-Prefix.pch in the file, enter your login and password from the site 4s.io (macros LOGIN and PASSWORD).

Symbian (QT)

Every application can interact with 4s.io server via SOAP protocol, by means of calling up 4s.io API functions.

These functions may be used to request for the content of your account, get the necessary links to files, and edit the file structure and the directory properties on the server.

The full description of the api is provided here.

The SOAP-protocol may be checked here.

As an SDK for creating applications for mobile devices, let's take ""okia Qt SDK 1.0", which can be got here. This package also includes IDE "Qt Creator", which we will use.

In the beginning, let's create the new project with type "Mobile application Qt" and name it 4s.io. In the visual editor we'll add "List widget" in the main window, which will include the elements of the root catalogue, downloaded from 4s.io server. In the class MainWindow constructor, in a line
- setCentralWidget(ui->listWidget); - stretch listWidget to the full screen.

To work with SOAP protocol in a more convenient way, we'll take initial codes from the library QtSOAP and insert them into the project, as this library isn't included into mobile version.

In addition to that, in order to make the application work with network in Symbian devices, it's necessary to add the following line in the file 4s.io.pro in the part, devoted to the specific Symbian settings:

-
Symbian {
 ...
 TARGET.CAPABILITY += NetworkServices
 ...
}
-

Then, we'll add and initialize members in class MainWindow:

-
class MainWindow : public QMainWindow
{
 ...
 QNetworkAccessManager nam;
 QtSoapHttpTransport http;
 ...
};

MainWindow::MainWindow(QWidget *parent) :
 ...
 nam(this),
 http(this),
 ...
{
 ...
 connect(&http, SIGNAL(responseReady()), SLOT(getResponse()));

 http.setNetworkAccessManager(&nam);
 http.setAction("");
 http.setHost("api.4shared.com", 80);
 ...
}
-

- which realize (implement) the transfer of our future requests.

The slot getResponse() will be invoked, when the answers to our requests are received.

To download the list of files and subdirectories of the root directory, it's necessary to perform 3 requests in series:

  1. isExistsLoginPassword - authentication
  2. getRoot - receipt of information about the root directory
  3. getItems - receipt of the list of elements in the defined directory (in our case - root directory)
-
class MainWindow : public QMainWindow
{
 ...
private slots:
 void getResponse();

private:
 QtSoapMessage initStdSoapMessage(const QString &methodName);

 void authorize();
 void authorizeHandler(const QtSoapType &res);

 void getRoot();
 void getRootHandler(const QtSoapType &res);

 void getItems(long id);
 void getItemsHandler(const QtSoapType &res);

 enum Operation {unknown, authorize_op, getRoot_op, getItems_op};

private:
 ...

 Operation operation;

 QString login, password;

 long rootId;
};

void MainWindow::getResponse()
{
 Operation op = operation;
 operation = unknown;

 // Get the response, check for error.
 const QtSoapMessage &resp = http.getResponse();
 if(resp.isFault()) {
  QMessageBox::warning(NULL, "Warning", "SOAP: query failed (" + resp.faultString().value().toString() + ")");
  return;
 }

 // Extract the return value from this method response, check for errors.
 const QtSoapType &res = resp.returnValue();
 if(!res.isValid()) {
  QMessageBox::warning(NULL, "Warning", "SOAP: invalid return value");
  return;
 }

 switch(op)
 {
 case authorize_op:
  authorizeHandler(res);
  break;
 case getRoot_op:
  getRootHandler(res);
  break;
 case getItems_op:
  getItemsHandler(res);
  break;
 case unknown:
  break;
 }
}

QtSoapMessage MainWindow::initStdSoapMessage(const QString &methodName)
{
 QtSoapMessage request;
 request.setMethod(QtSoapQName(methodName, "http://api.soap.shared.pmstation.com/"));
 request.addMethodArgument("arg0", "", login);
 request.addMethodArgument("arg1", "", password);
 return request;
}

void MainWindow::authorize()
{
 QtSoapMessage request = initStdSoapMessage("isExistsLoginPassword");
 operation = authorize_op;
 http.submitRequest(request, "/jax3/DesktopApp");
}

void MainWindow::authorizeHandler(const QtSoapType &res)
{
 bool auth = res.value().toBool();
 if(auth)
 {
  // QMessageBox::information(NULL, "Authorization", "Authorized");
  getRoot();
 }
 else
  QMessageBox::warning(NULL, "Warning", "Invalid user name or password");
}

void MainWindow::getRoot()
{
 QtSoapMessage request = initStdSoapMessage("getRoot");
 operation = getRoot_op;
 http.submitRequest(request, "/jax3/DesktopApp");
}

void MainWindow::getRootHandler(const QtSoapType &res)
{
 rootId = res["id"].toInt();
 getItems(rootId);
}

void MainWindow::getItems(long id)
{
 QtSoapMessage request = initStdSoapMessage("getItems");
 request.addMethodArgument("arg2", "", id);
 operation = getItems_op;
 http.submitRequest(request, "/jax3/DesktopApp");
}

void MainWindow::getItemsHandler(const QtSoapType &res)
{
 for(int i=0; i<res.count(); i++)
 {
  const QtSoapType &item = res[i];

  if(item["removed"].toBool())
   continue;

  QString name;
  if(item["directory"].toBool())
   name = " <dir> ";
  name += item["name"].toString();

  QListWidgetItem *itm = new QListWidgetItem(name);
  itm->setSizeHint(QSize(0, 50));
  ui->listWidget->addItem(itm);
 }
}
-

Demo-sample can be downloaded here.

To start the sample application, insert your login and password from 4s.io in the file MainWindow.cpp (variable login and password).

Android

  1. 4shared API.
  2. Service 4s.io is a usual web-service, WSDL description of which is here: https://api.4shared.com/jax3/DesktopApp?wsdl.

    You can read more about web-services and WSDL' here: http://ru.wikipedia.org/wiki/%D0%92%D0%B5%D0%B1-%D1%81%D0%BB%D1%83%D0%B6%D0%B1%D0%B0, http://ru.wikipedia.org/wiki/WSDL.

    Short description of API functions can found here: API documentation.

    To work with SOAP API, you can use direct SOAP-calling, but it's more convenient to use another library for request parsing. For instance, you can use free library: http://code.google.com/p/ksoap2-android/.

  3. Tools for Development.
  4. Development of applications for Android is possible on any platform, which allows Andrid SDK setup. System requirements can be checked here: http://developer.android.com/sdk/requirements.html.

    You can download Android SDK here: http://developer.android.com/sdk/index.html, setup instructions are available here: http://developer.android.com/sdk/installing.html.

    The recommended environment for development is Eclipse (http://www.eclipse.org/downloads/), with the plugin for Android (http://developer.android.com/sdk/eclipse-adt.html). Any device with OS Android, or an emulator of the device, included into Android SDK, is suitable for starting the developed application.

    Detailed instruction for beginners in app development can be found here: http://developer.android.com/guide/developing/index.html.

  5. Step-by-Step Instruction.
  6. Resource http://developer.android.com/index.html comprises all necessary information for developers.

    The most essential (fundamental) notions are described in the article: http://developer.android.com/guide/topics/fundamentals.html.

    Step-by-step instruction of the simple app for 4s.io is displayed below.

    1) Install a Platform (http://developer.android.com/resources/tutorials/hello-world.html).

    2) Create an AVD (http://developer.android.com/resources/tutorials/hello-world.html).

    3) Create a New Android Project (http://developer.android.com/resources/tutorials/hello-world.html).

    4) To insert changes, needed to make the minimum 4s.io-application work.

    To link the ksoap2 library to the project, it's necessary to create subcatalog libs in the catalogue Hello4s.io and place jar-archive of this library there. Then, choose Project > Options in menu Eclipse, and after that select subsection Java Build Path and tab Libraries. Press the button Add JARs and display the path to the library.

    With the help of menu File > New > Class, let's create 2 subclasses: AccountItem, representing the user's file or catalogue on 4s.io server, and ForSharedService, with the help of which 4s.io API remote methods are called up.

    AccountItem is used to desereal data from the network and provides convenient methods to receive information about the file/catalogue, for example, getName() and getDownloadLink() return the filename and the download link accordingly.

    package com.example.hello4shared;

    import org.ksoap2.serialization.SoapPrimitive;

    /**
    * 4shared account item, representing a file or a directory description data.
    * Implementation includes network serialization functionality.
    */
    public class AccountItem {
     private long id;
     private String name;
     private boolean directory;

     public AccountItem() {
     }

     public long getId() {
      return id;  }

     public String getName() {
      return name;
     }

     public boolean isDirectory() {
      return directory;
     }

     public String toString() {
      return directory ? "[" + name + "]" : name;
     }

     public void setProperty(String propName, Object value) {
      if (value == null) {
      return;
      }
      if (value instanceof SoapPrimitive) {
      value = ((SoapPrimitive) value).toString();
      }

      if (propName.equals("id")) {
      if (value instanceof Long)
       id = ((Long) value).longValue();
      else
       id = Long.parseLong(value.toString());
      }
      if (propName.equals("directory")) {
      directory = convertBoolean(value);
      }
      else if (propName.equals("name")) {
      name = convertString(value);
      }
     }

     private boolean convertBoolean(Object val) {
      if (val == null)
      return false;

      if (val.toString().toLowerCase().equals("true"))
      return true;
      else
      return false;
     }

     private String convertString(Object str) {
      if (!(str instanceof String))
      return null;

      if (((String) str).equals("String{}"))
      return "";
      else
      return (String) str;
     }
    }

    ForSharedService is the interlayer for the convenient call of remote methods and hides the code of interaction with technology SOAP.

    package com.example.hello4shared;

    import org.ksoap2.SoapEnvelope;
    import org.ksoap2.serialization.PropertyInfo;
    import org.ksoap2.serialization.SoapObject;
    import org.ksoap2.serialization.SoapSerializationEnvelope;
    import org.ksoap2.transport.AndroidHttpTransport;
    import org.ksoap2.transport.Transport;

    import java.util.Hashtable;
    import java.util.Vector;

    /**
    * 4shared API local layer
    */
    public class ForSharedService {
     private String mUsername;
     private String mPassword;
     private static final String SERVICE_URL = "http://api.4shared.com/jax3/DesktopApp";
     private static final String SERVICE_NAMESPACE = "http://api.soap.shared.pmstation.com/";

     /**
      * Constructs this object for an account
      * @param username Username of the account
      * @param password Password of the account
      */
     public ForSharedService(String username, String password) {
      mUsername = username;
      mPassword = password;
     }

     /**
      * Login with current account
      */
     public void login() throws Exception {
      String methodName = "login";
      SoapObject rpc = getRpc(methodName);
      SoapSerializationEnvelope envelope = getEnvelope(rpc);
      Transport ht = getHttpTransport();

      String result;

      ht.call(SERVICE_URL + "/" + methodName, envelope);
      result = (envelope.getResponse()).toString();

      if (!isEmptyString(result))
      throw new Exception(result);
     }

     /**
      * Get account's root folder
      * @return Item representing the root directory
      */
     public AccountItem getRoot() throws Exception {
      String soapAction = SERVICE_URL + "/getRoot";

      SoapObject rpc = getRpc("getRoot");
      SoapSerializationEnvelope envelope = getEnvelope(rpc);
      Transport ht = getHttpTransport();

      ht.call(soapAction, envelope);
      return getAccountItem((SoapObject) envelope.getResponse());
     }

     /**
      * Get contents of a directory
      * @param dirId Directory's identifier
      * @return Array of items representing contents of the directory
      */
     public AccountItem[] getItems(long dirId) throws Exception {
      String methodName = "getItems";

      SoapObject rpc = getRpc(methodName);
      rpc.addProperty("arg2", new Long(dirId));
      SoapSerializationEnvelope envelope = getEnvelope(rpc);

      Transport ht = getHttpTransport();

      ht.call(SERVICE_URL + "/" + methodName, envelope);
      Object result = envelope.getResponse();

      return getAccountItems(result);
     }

     private Transport getHttpTransport() {
      Transport ht = new AndroidHttpTransport(SERVICE_URL);
      ht.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
      ht.debug = true;

      return ht;
     }

     private SoapObject getRpc(String methodName) {
      SoapObject rpc = new SoapObject(SERVICE_NAMESPACE, methodName);
      rpc.addProperty("arg0", mUsername);
      rpc.addProperty("arg1", mPassword);

      return rpc;
     }

     private SoapSerializationEnvelope getEnvelope(SoapObject rpc) {
      SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);

      envelope.bodyOut = rpc;
      envelope.encodingStyle = SoapSerializationEnvelope.XSD;

      return envelope;
     }

     private AccountItem getAccountItem(SoapObject item) {
      return deserialize(new AccountItem(), item);
     }

     @SuppressWarnings("unchecked")
     private AccountItem[] getAccountItems(Object response) {
      if (response == null)
      return null;

      if (!(response instanceof SoapObject))
      return null;

      Vector items = new Vector();

      for (int i = 0; i < ((SoapObject) response).getPropertyCount(); i++) {
       Object item = ((SoapObject) response).getProperty(i);
       if (item instanceof SoapObject) {
        items.addElement(deserialize(new AccountItem(), (SoapObject) item));
       }
      }

      AccountItem[] accountItems = new AccountItem[items.size()];
      items.copyInto(accountItems);

      return accountItems;
     }

     @SuppressWarnings( {
      "unchecked", "deprecation"
     })
     private AccountItem deserialize(AccountItem newItem, SoapObject item) {
      Hashtable ht = new Hashtable();
      PropertyInfo propInfo = new PropertyInfo();
      for (int n = 0; n < item.getPropertyCount(); n++) {
      item.getPropertyInfo(n, ht, propInfo);
      newItem.setProperty(propInfo.name, item.getProperty(n));
      }

      return newItem;
     }

     private static boolean isEmptyString(String string) {
      return (string == null || string.equals("")
       || string.toLowerCase().equals("string{}")
       || string.toLowerCase().equals("anytype{}"));
     }
    }

    The classes SoapObject, SoapSerializationEnvelope, AndroidHttpTransport - are included into the library ksoap2.

    SoapObject, SoapSerializationEnvelope serve to parse soap-requests, whereas AndroidHttpTransport provides transport to call up the requests.

    The call up of the function itself is realized by the method call (), of the class AndroidHttpTransport.

    The service's answer can be received by means of calling up the method getResponse() of the class SoapSerializationEnvelope.

    The functions, transferred to the service, are defined by calling up the method addProperty of the class SoapObject as a pair "parameter name - value".

    Let's create a window (activity) to display the list of user's files and catalogues from 4s.io server.

    To do that, let's create the new class (File > New > Class), derivative from ListActivity, in Eclipse environment, and call it AccountContents.

    Let's edit AccountContents.java, by redefining the method onCreate, called up by means of initializing the window (activity).

    protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);

     // Use a ListAdapter that will map an array of account's root folder items to TextViews
     setListAdapter(new ArrayAdapter<AccountItem>(this,
      android.R.layout.simple_list_item_1, Hello4shared.rootContents));
    }

    The class ArrayAdapter establishes accordance (correspondence) between the list elements of the user's interface and the list of files and catalogues on 4s.io server, which will be uploaded into the static variable rootContents of the class Hello4s.io.

    In the method onCreate of the main window (activity) of the application, the code of which is in the file Hello4s.io.java, let's create the elements of the user's interface for insertion and transfer of the user's name (login) and 4s.io account password to the server.

    public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);

     // Prepare vertical linear layout
     LinearLayout mainLayout = new LinearLayout(this);
     mainLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
     mainLayout.setOrientation(LinearLayout.VERTICAL);

     // Create views
     TextView loginView = new TextView(this);
     loginView.setText("login:");
     TextView passwordView = new TextView(this);
     passwordView.setText("password:");

     final EditText loginEdit = new EditText(this);
     final EditText passwordEdit = new EditText(this);
     passwordEdit.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);

     Button loginButton = new Button(this);
     loginButton.setText("Submit");
     loginButton.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
       String username = loginEdit.getText().toString();
       String password = passwordEdit.getText().toString();

       // If username and password entered correctly
       if (username.length() != 0 && password.length() != 0) {
        // Start login procedure
        login(username, password);
       }
      }
     });

     // Add views to layout
     mainLayout.addView(loginView);
     mainLayout.addView(loginEdit);
     mainLayout.addView(passwordView);
     mainLayout.addView(passwordEdit);
     mainLayout.addView(loginButton);

     // Set the layout as activity main layout
     setContentView(mainLayout);
    }

    The handler of the press-button loginButton checks the properness of inserted data and, if succeeds, calls up the method login (), which starts the process of checking the user's data on 4s.io server, and also requests the list of files and catalogues of the account root catalogue.

    private void login(final String username, final String password) {
     mProgressDialog = ProgressDialog.show(this, "", "Please wait...", true);
     mProgressDialog.setCancelable(false);

     // We should call network calls on separate thread not to freeze the application UI
     new Thread() {
      @Override
      public void run() {
       // Create 4shared API local layer to call remote methods
       ForSharedService fss = new ForSharedService(username, password);
       try {
        // Call login procedure
        fss.login();
        // Get account's root folder
        AccountItem rootItem = fss.getRoot();
        // Request contents of the root folder
        rootContents = fss.getItems(rootItem.getId());

        // If we are here, this means all the operations succeeded
        loginSucceeded();
       } catch (Exception e) {
        // One of the operations has failed
        loginFailed(e.getMessage());
       }
      }
     }.start();
    }

    If the name (login) and password correspond to the account in 4s.io database, and network connection has been set successfully, the call up of the method loginSucceeded () opens the window (en. activity), which displays the list of user's files and catalogues, which has been stored into the static variable rootContents.

    private void loginSucceeded() {
     // Application UI transitions should be performed on the main thread
     mHandler.post(new Runnable() {
      @Override
      public void run() {
       mProgressDialog.dismiss();
       // Move to next activity to show list of account's root folder contents
       Intent intent = new Intent(Hello4shared.this, AccountContents.class);
       startActivity(intent);
      }
     });
    }

    The last thing, which should be changed is the configuration of the project in the file AndroidManifest.xml.

    In the section <manifest> let's request the permit to get the access of the application to the Internet:

     <uses-permission android:name="android.permission.INTERNET"></uses-permission>
    In the section <application>, let's add the window(activity) AccountContents:
     <activity android:name=".AccountContents"
      android:label="@string/app_name">
    </activity>
    and define the portrait orientation for the window (activity) Hello4shared:
      android:configChanges="keyboardHidden|orientation"
      android:screenOrientation="portrait"

    The full code of the demo-application is attached (http://dc243.4shared.com/download/l8R381Nw/androidsamples.zip).

  7. Run the Application (http://developer.android.com/resources/tutorials/hello-world.html).

Blackberry

System requirements:

- 32-bit Windows® XP, Windows Vista® or Windows 7 (64-bit versions require 32-bit Java® and Eclipse)

- Eclipse 3.6 Helios

- PC with processor Intel® Pentium® 4 or higher (2.5 GHz or higher, 2 GB RAM, 1.5 GB free space on hard drive)

- Java SE Development Kit (JDK) 6, update 10 or newer.

Setup:

- Download and install 32-bit version of JAVA (http://www.java.com/ru/download/).

- Download and install 32-bit version of Eclipse (http://www.eclipse.org/downloads/packages/eclipse-classic-362/heliossr2).

- Download and install Blackberry plugin for Eclipse (http://us.blackberry.com/developers/javaappdev/javaplugin.jsp).

- Install Blackberry SDK. To do this, to start Eclipse and check menu Help - Install New Software... In a line with the software address to insert http://www.blackberry.com/developers/jar/3.6/java/.

  1. Description of 4s.io Service
  2. Service 4s.io is a usual web-service, WSDL description of which is here: https://api.4shared.com/jax3/DesktopApp?wsdl.

    You can read more about web-services and WSDL here: http://ru.wikipedia.org/wiki/%D0%92%D0%B5%D0%B1-%D1%81%D0%BB%D1%83%D0%B6%D0%B1%D0%B0, http://ru.wikipedia.org/wiki/WSDL.

    Short description of API functions can found here: API documentation.

    To work with SOAP API, you can use direct SOAP-calling, but it's more convenient to use another library for request parsing. For instance, you can use free library: (http://code.google.com/p/ksoap2-android/), which uses Java Microedition, working on Blackberry OS).

  3. Demo Application
  4. In the beginning, it's necessary to create the new project in Eclipse (menu File-New-Project, in the list of project types - select Blackberry Project) and call it Hello4Shared.

    In addition to that, for the right setup on the device of library ksoap2, you should create the 2nd project, where to place the library. You should define the type of the 2nd project Library and add the link to this project in the main application.

    To work with the service, it's necessary to add subclass ForSharedService.

    The standard call of the function 4s.io API will be the following:

    protected static final String SERVICE_URL = "http://api.4shared.com/jax3/DesktopApp";
    protected static final String SERVICE_NAMESPACE = "http://api.soap.shared.pmstation.com/";

    /**
    * Enter check of the already existing user
    * @param username - user name
    * @param password - password
    * @throws Exception
    */
    public void login(String username, String password) throws Exception
    {
     String methodName = "login";
      SoapObject rpc = new SoapObject(SERVICE_NAMESPACE, methodName);
      rpc.addProperty("arg0", userName);
      rpc.addProperty("arg1", password);

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);

      envelope.bodyOut = rpc;
      envelope.encodingStyle = SoapSerializationEnvelope.XSD;

      HttpTransport ht = new HttpTransport(SERVICE_URL);
     ht.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
     ht.debug = true;

      String result;

      ht.call(SERVICE_URL + "/" + methodName, envelope);
     result = (envelope.getResponse()).toString();

      if (!isEmptyString(result))
       throw new Exception(result);
    }

    The classes SoapObject, SoapSerializationEnvelope, HttpTransport - are included in the library ksoap2.

    SoapObject, SoapSerializationEnvelope serve to parse soap-requests, whereas HttpTransport provides transport for the call of requests. The call of service functions itself is established by the method), of the class HttpTransport. The service answer can be received by means of calling the method getResponse() of the class SoapSerializationEnvelope. The parameters of functions, transferred to the service, are defined by calling up the method addProperty of the class SoapObject as a pair "parameter name - value". Now, let's add the class of the main screen into the app, where we will place 2 text fields to enter the user's name (login) and password, and the button to call up the method login of service, used to enter: public class MainAppScreen extends MainScreen implements FieldChangeListener.

    {
     /**
      * Window Title
      */
     private LabelField _title;

     /**
      * Enter-Login Field
      */
     private EmailAddressEditField _userNameField;

     /**
      * Enter-Password Field
      */
     private PasswordEditField _passwordField;

     /**
      * Enter Button
      */
     private ButtonField _loginButton;

     /**
      * Constructor
      */
     public MainAppScreen()
     {
      super();

      _title = new LabelField("Hello4Shared");
      setTitle(_title);

      _userNameField = new EmailAddressEditField("Login or email: ", "");
      add(_userNameField);
      _passwordField = new PasswordEditField("Password: ", "");
      add(_passwordField);

      _loginButton = new ButtonField("Login", Field.FOCUSABLE);
      _loginButton.setChangeListener(this);
      add(_loginButton);
     }
    }

    After that, let's add the handler of the press-button in the following way:

    /*
    * The Handler of the Press-Button
    */
    public void fieldChanged(Field field, int context)
    {
     if (field == _loginButton)
     {
      login();
     }
    }

    And the exact request to 4s.io service in the method login, by means of using the class ForSharedService, described above:

    private void login(){
    ForSharedService service = new ForSharedService(_userNameField.getText(), _passwordField.getText());

     // Logging into account
     try
     {
      service.login();
     }catch (Exception e)
     {
      Dialog.alert(e.getMessage());
     }
    }

    In case of invalid login or password, the user will receive the error report.

    The full code of the demo-application is attached (http://dc315.4shared.com/download/bjixhTFj/blackberrysamples.zip).