Category Archives: Android

MTP Mode is enabled

Last night I just updated my HTC One to version 4.3 Jelly Bean. When I connected it to my computer I saw “MTP Mode is enabled”. So it seems this is already there since the version 3.0 Honeycomb but I didn’t notice it back than. At least it was not so obvious.
And what does it stand for? MTP simply stands for Media Transfer Protocol.

mtp-mode-is-enabled

If you want to read some more details go to the androidcentral link.

Manipulating SharePoint list items with Android (JAVA) and NTLM Authentication

Android LogoRegarding to my previous post about manipulation of SharePoint list items with PHP I have been struggling with the same problem to connect SharePoint Web Services to Android even longer. I was able to come up with a solution quite fast but the SharePoint site had to be enabled for anonious access. And another issue here: you can just read the SharePoint Web Service. Don’t forget to include KSOAP2 library as external JAR.

I was browsing for some kind of a solution for quite some time. And if there were some kind of directions towards a probable solution I was not developer enough to figure it out on my own.

The sample without the need of authentication I was able to figure out with help from article in stackoverflow.com. If you google a bit you will find quite a bunch of articles about changing temparature or about the halloworld webservice. Both of them hosted in http://tempuri.org. The article is talking about calling a .NET WebService to change Celsius to Farenheit and vice versa. Anyways… was a very good start.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.balavec.ws;

import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.widget.TextView;

public class wsActivity extends Activity {
    /** Called when the activity is first created. */
   
    TextView tv;
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        tv = (TextView)findViewById(R.id.textView1);
        tv.setMovementMethod(ScrollingMovementMethod.getInstance());
       
       
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost("http://localhost/_vti_bin/Lists.asmx");

        try {
            StringEntity se = new StringEntity( "<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><GetListItems xmlns="http://schemas.microsoft.com/sharepoint/soap/"><listName>quotes</listName><rowLimit>50</rowLimit></GetListItems></soap:Body></soap:Envelope>", HTTP.UTF_8);
            se.setContentType("text/xml");
            httppost.setEntity(se);

            HttpResponse httpresponse = httpclient.execute(httppost);
            HttpEntity resEntity = httpresponse.getEntity();
            tv.setText("Status OK: \n" + EntityUtils.toString(resEntity));

        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            tv.setText("Status NOT OK: \n" + e.getMessage());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            tv.setText("Status NOT OK: \n" + e.getMessage());
        }
       
    }
}

But if you want to lock your Web Services (SharePoint Lists) behind NTLM (windows) authentication, you will have to include KSOAP2 and JCIFS library.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package com.balavec.ws;

import java.io.IOException;
import jcifs.ntlmssp.Type1Message;
import jcifs.ntlmssp.Type2Message;
import jcifs.ntlmssp.Type3Message;
import jcifs.util.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.auth.NTLMScheme;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.widget.TextView;
import org.apache.http.auth.AuthScheme;
import org.apache.http.auth.AuthSchemeFactory;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.NTCredentials;
import org.apache.http.impl.auth.NTLMEngine;
import org.apache.http.impl.auth.NTLMEngineException;

public class wsActivity extends Activity {
    /** Called when the activity is first created. */
       
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
           
        TextView tv = (TextView)findViewById(R.id.textView1);
        tv.setMovementMethod(ScrollingMovementMethod.getInstance());
               
        HttpClient httpclient = new DefaultHttpClient();        
        ((AbstractHttpClient) httpclient).getAuthSchemes().register("ntlm",new NTLMSchemeFactory());

        NTCredentials creds = new NTCredentials("username", "password", "", "domain");

        ((AbstractHttpClient) httpclient).getCredentialsProvider().setCredentials(AuthScope.ANY, creds);
        HttpConnectionParams.setConnectionTimeout(httpclient.getParams(), 5000);
       
        HttpPost httppost = new HttpPost("http://localhost/_vti_bin/Lists.asmx");
        httppost.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
       
        try {
            StringEntity se = new StringEntity( "<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><GetListItems xmlns="http://schemas.microsoft.com/sharepoint/soap/"><listName>quotes</listName><rowLimit>50</rowLimit></GetListItems></soap:Body></soap:Envelope>", HTTP.UTF_8);
            se.setContentType("text/xml");
            httppost.setEntity(se);

            HttpResponse httpresponse = httpclient.execute(httppost);
            HttpEntity resEntity = httpresponse.getEntity();

            tv.setText("Status OK: \n" + EntityUtils.toString(resEntity));
   
        } catch (ClientProtocolException e) {
            e.printStackTrace();
            tv.setText("Status NOT OK: \n" + e.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
            tv.setText("Status NOT OK: \n" + e.getMessage());
        }
    }
 
    // JCIFSEngine
    public class JCIFSEngine implements NTLMEngine {

        public String generateType1Msg(
                String domain,
                String workstation) throws NTLMEngineException {

            Type1Message t1m = new Type1Message(
                    Type1Message.getDefaultFlags(),
                    domain,
                    workstation);
            return Base64.encode(t1m.toByteArray());
        }

        public String generateType3Msg(
                String username,
                String password,
                String domain,
                String workstation,
                String challenge) throws NTLMEngineException {
            Type2Message t2m;
            try {
                t2m = new Type2Message(Base64.decode(challenge));
            } catch (IOException ex) {
                throw new NTLMEngineException("Invalid Type2 message", ex);
            }
            Type3Message t3m = new Type3Message(
                    t2m,
                    password,
                    domain,
                    username,
                    workstation, 0);
            return Base64.encode(t3m.toByteArray());
        }

    }

    //NTLM Scheme factory
    public class NTLMSchemeFactory implements AuthSchemeFactory {

        public AuthScheme newInstance(final HttpParams params) {
            return new NTLMScheme(new JCIFSEngine());
        }
       
    }

}