Showing posts with label Service. Show all posts
Showing posts with label Service. Show all posts

Sunday, 15 January 2017

HB Blog 127: Creating A Custom Account Type.

So far we've talked about accessing Google APIs, which use accounts and users defined by Google. If you have your own online service, though, it won't have Google accounts or users, so what do you do? It turns out to be relatively straightforward to install new account types on a user's device. This tutorial explains how to create a custom account type that works the same way as the built-in accounts do.
The first thing you'll need is a way to get credentials from the user. This may be as simple as a dialog box that asks for a name and a password. Or it may be a more exotic procedure like a one-time password or a biometric scan. Either way, it's your responsibility to implement the code that:
  1. Collects credentials from the user
  2. Authenticates the credentials with the server
  3. Stores the credentials on the device
Refer the below link for complete sample code:-

Download Sample Code

You need to setup multiple components to be able to create an account programmatically. You need:
  •     an AccountAuthenticator
  •     a Service to provide access to the AccountAuthenticator
  •     some permissions
The Authenticator
The authenticator is an object that will make the mapping between the account type and the autority (i.e. the linux-user) that have rights to manage it.

Declaring an authenticator
is done in xml :
create a file res/xml/authenticator.xml with the following content :
1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
    android:accountType="com.example.harshalbenake.accountsetting.DEMOACCOUNT"
    android:icon="@drawable/ic_launcher"
    android:smallIcon="@drawable/ic_launcher"
android:label="@string/app_name"/>
Note the accountType : it must be reused in code when you create the Account. The icons and label will be used by the "Settings" app to display the accounts of that type.

Implementing the AccountAuthenticator
You must extends AbstractAccountAuthenticator to do that. This will be use by third party app to access Account data.
The following sample don't allow any access to 3rd-party app and so the implementation of each method is trivial.
 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
import android.accounts.AbstractAccountAuthenticator;
import android.accounts.Account;
import android.accounts.AccountAuthenticatorResponse;
import android.accounts.NetworkErrorException;
import android.content.Context;
import android.os.Bundle;

public class CustomAuthenticator extends AbstractAccountAuthenticator {

    public CustomAuthenticator(Context context) {
        super(context);
    }

    @Override
    public Bundle addAccount(AccountAuthenticatorResponse accountAuthenticatorResponse, String s, String s2, String[] strings, Bundle bundle) throws NetworkErrorException {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public Bundle editProperties(AccountAuthenticatorResponse accountAuthenticatorResponse, String s) {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public Bundle confirmCredentials(AccountAuthenticatorResponse accountAuthenticatorResponse, Account account, Bundle bundle) throws NetworkErrorException {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public Bundle getAuthToken(AccountAuthenticatorResponse accountAuthenticatorResponse, Account account, String s, Bundle bundle) throws NetworkErrorException {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public String getAuthTokenLabel(String s) {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public Bundle updateCredentials(AccountAuthenticatorResponse accountAuthenticatorResponse, Account account, String s, Bundle bundle) throws NetworkErrorException {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public Bundle hasFeatures(AccountAuthenticatorResponse accountAuthenticatorResponse, Account account, String[] strings) throws NetworkErrorException {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }
}

The Service exposing the Account Type

Create a Service to manipulate the Accounts of that type :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class AuthenticatorService extends Service {
    @Override
    public IBinder onBind(Intent intent) {
        CustomAuthenticator authenticator = new CustomAuthenticator(this);
        return authenticator.getIBinder();
    }
}

Declare the service in your manifest :
1
2
3
4
5
6
7
8
  <service android:name=".AuthenticatorService" android:exported="false">
  <intent-filter>
  <action android:name="android.accounts.AccountAuthenticator"/>
  </intent-filter>
  <meta-data
                android:name="android.accounts.AccountAuthenticator"
                android:resource="@xml/authenticator"/>
</service>
Here, the filter and the meta-data referring to the xml resource declaring the authenticator are the key points.

The permissions
In your manifest be sure to declare the following permissions
1
2
3
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/>
(not all required for the sample code presented in this post, but you will probably have some more code about account management and at the end all of them will be useful)

Create an account in code
Now that everything is ready you create an account with the following code. Note the boolean returned by addAccountExplicitly informing you about the success or failure.
 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
import android.accounts.Account;
import android.accounts.AccountManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        AccountManager accountManager = AccountManager.get(this);
        Account account = new Account("HBAccount","com.example.harshalbenake.accountsetting.DEMOACCOUNT");
        boolean success = accountManager.addAccountExplicitly(account,"password",null);
        if(success){
            Toast.makeText(MainActivity.this,"Account created",Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(MainActivity.this,"Account creation failed. Look at previous logs to investigate",Toast.LENGTH_SHORT).show();
        }

        Account[] accounts = AccountManager.get(this).getAccounts();
        for (Account account1 : accounts) {
            Toast.makeText(MainActivity.this, "Name: " + account1.name+" Type: " + account1.type,Toast.LENGTH_SHORT).show();
        }
    }
}

Friday, 2 September 2016

HB Blog 118: Cell Broadcast - The Mobile Technology For Mass Message Broadcast.

Cell Broadcast (CB) is a mobile technology that allows messages (currently of up to 15 pages of up to 93 characters) to be broadcast to all mobile handsets and similar devices within a designated geographical area. The broadcast range can be varied, from a single cell to the entire network.
This technology is used in deploying location-based subscriber services, such as regional auctions, local weather, traffic conditions and 'nearest' services (like requesting the nearest service station or restaurant).
It is designed for simultaneous delivery of messages to multiple users in a specified area. Whereas the Short Message Service (SMS) is a one-to-one and one-to-a-few service, It is one-to-many geographically focused service.
It enables messages to be communicated to multiple mobile phone customers who are located within a given part of its network coverage area at the time the message is broadcast. Cell Broadcast is more akin to other mass distribution media such as teletext or Radio Data System (RDS).
It  is a technology that allows a text or binary message to be defined and distributed to all mobile terminals connected to a set of cells. Whereas SMS messages are sent point-to-point, Cell Broadcast (SMS-CB) messages are sent point-to-area. This means that one SMS-CB message can reach a huge number of terminals at once. In other words, SMS-CB messages are directed to radio cells, rather than to a specific terminal. SMS-CB is an unconfirmed push service, meaning that the originator of the message does not know who has received the message, allowing for services based on anonymity.

A Cell Broadcast Entity (CBE) is a multi-user front-end that allows the definition and control of SMS-CB messages. A CBE can be located at the site of a content provider. At the site of the operator a so-called Cell Broadcast Centre (CBC) is located. The CBC is the heart of the Cell Broadcast System and acts as a server for all CBE clients. It takes care of the administration of all SMS-CB messages it receives from the CBEs and does the communication towards the GSM network. The GSM network itself takes care of delivering the SMS-CB messages to the mobile terminals.
Cell Broadcast can be used for a number of different services and has been de-ployed by several network operators.

Early Warning System (EWS) for citizen alert
Cell Broadcast on mobile telephones can be used for Early Warning Systems (EWS) by Governments. A few countries in the world have already adopted this technique, in addition to older and already existing forms of communication like siren, or radio and TV. The advantage of this system is that it allows sending messages without having to know the phone numbers of the users in the region. Instead of sending a message to a specific known mobile phone you can send a text to all mobile phones in a specific zone. Mass communication, very fast, in case it really matters.

Advertising
Retail outlets in certain areas would be interested in sending customers and potential customers information about special offers and attractions such as sales, special offers, extended opening times and so on. Shopping centers, exhibition halls, airports and sports stadiums are the kinds of location that could be targeted for Cell Broadcast based services.

Information Services
Cell Broadcast is ideal for delivering local or regional information which is suited to all the people in that area, rather than just one or a few people. Examples include hazard warnings, cinema programs, local weather, flight or bus delays, tourist information, parking and traffic information. Cell Broadcast can also be used for managing and communicating with a remote but local team such as emergency services or airport staff. The emergency services could send an encrypted message out to all officers or other staff in a certain area to respond to an incident. This is particularly useful for standby workers who only need to be called in and present in a certain place when certain events occur.

SMS versus Cell Broadcast: -

Short Message Service (SMS)
Characteristic
Cell Broadcast (CELL BROADCAST)
Messages sent point-to-point
Transmission type
Messages sent point-to-area
Required. Requires specific phone numbers to be known
Mobile Number dependency
Independent. Does not require phone numbers to be known
No. Only pre-registered numbers will be notified; message will be received regardless of actual location
Location based targeting
Yes. All phones within a targeted geographical area (cells) will be notified.
Static messages will be sent to pre-registered numbers.
Message type
Location specific. Tailored messages can be sent to different areas.
Direct. Users can receive messages and respond directly to the sender via SMS.
Bi-directionality
Indirect. The message should contain a URL or number to reply.
Subject to network congestion. Delivery is queued. Congestion can occur
Congestion and delay
CELL BROADCAST is always available.
140-160 characters. Longer 'concatenated' messages are supported.
Message length
93 characters. Longer 'multiple page’ messages are supported.
Poor authenticity. The source of the message cannot be verified.
Security
Good security. Only the mobile operator can broadcast messages.
No barring.
Service barring
Yes. Users can turn off CELL BROADCAST reception or a specific channel.
By default. When phone is turned on messages can be received.
Reception
Requires action. CELL BROADCAST needs to be turned on in order to receive messages.
Yes. Senders can request delivery confirmation.
Delivery confirmation
No. Confirmation of delivery to the handset is not available, however actual broadcast in the network is.
No repetition rate.
Repetition rate
Yes. Can be repeated between 2 seconds and 32 minutes.
No. Identical to all receivers.
Language selection
Yes. Messages can be broadcasted in subscriber’s preferred language
Yes.
Message storage
Handset dependant.

Monday, 1 August 2016

HB Blog 116: Security With HTTPS And SSL.

The Secure Sockets Layer (SSL) technically known as Transport Layer Security (TLS) is a common building block for encrypted communications between clients and servers. It's possible that an application might use SSL incorrectly such that malicious entities may be able to intercept an app's data over the network. To help you ensure that this does not happen to your app, this article highlights the common pitfalls when using secure network protocols and addresses some larger concerns about using Public-Key Infrastructure (PKI).
In a typical SSL usage scenario, a server is configured with a certificate containing a public key as well as a matching private key. As part of the handshake between an SSL client and server, the server proves it has the private key by signing its certificate with public-key cryptography.However, anyone can generate their own certificate and private key, so a simple handshake doesn't prove anything about the server other than that the server knows the private key that matches the public key of the certificate. One way to solve this problem is to have the client have a set of one or more certificates it trusts. If the certificate is not in the set, the server is not to be trusted.
There are several downsides to this simple approach. Servers should be able to upgrade to stronger keys over time ("key rotation"), which replaces the public key in the certificate with a new one. Unfortunately, now the client app has to be updated due to what is essentially a server configuration change. This is especially problematic if the server is not under the app developer's control, for example if it is a third party web service. This approach also has issues if the app has to talk to arbitrary servers such as a web browser or email app.
In order to address these downsides, servers are typically configured with certificates from well known issuers called Certificate Authorities (CAs). The host platform generally contains a list of well known CAs that it trusts. Android currently contains over 100 CAs that are updated in each release. Similar to a server, a CA has a certificate and a private key. When issuing a certificate for a server, the CA signs the server certificate using its private key. The client can then verify that the server has a certificate issued by a CA known to the platform.
However, while solving some problems, using CAs introduces another. Because the CA issues certificates for many servers, you still need some way to make sure you are talking to the server you want. To address this, the certificate issued by the CA identifies the server either with a specific name such as gmail.com or a wildcarded set of hosts such as *.google.com.

The following example will make these concepts a little more concrete. In the snippet below from a command line, the openssl tool's s_client command looks at Wikipedia's server certificate information. It specifies port 443 because that is the default for HTTPS. The command sends the output of openssl s_client to openssl x509, which formats information about certificates according to the X.509 standard. Specifically, the command asks for the subject, which contains the server name information, and the issuer, which identifies the CA.
1
2
3
$ openssl s_client -connect wikipedia.org:443 | openssl x509 -noout -subject -issuer
subject= /serialNumber=sOrr2rKpMVP70Z6E9BT5reY008SJEdYv/C=US/O=*.wikipedia.org/OU=GT03314600/OU=See www.rapidssl.com/resources/cps (c)11/OU=Domain Control Validated - RapidSSL(R)/CN=*.wikipedia.org
issuer= /C=US/O=GeoTrust, Inc./CN=RapidSSL CA
You can see that the certificate was issued for servers matching *.wikipedia.org by the RapidSSL CA.

Assuming you have a web server with a certificate issued by a well known CA, you can make a secure request with code as simple this:
1
2
3
4
URL url = new URL("https://wikipedia.org");
URLConnection urlConnection = url.openConnection();
InputStream in = urlConnection.getInputStream();
copyInputStreamToOutputStream(in, System.out);

Suppose instead of receiving the content from getInputStream(), it throws an exception:
This can happen for several reasons, including:
  •     The CA that issued the server certificate was unknown
  •     The server certificate wasn't signed by a CA, but was self signed
  •     The server configuration is missing an intermediate CA
Here is the example in full using an organizational CA from the University of Washington:
 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
// Load CAs from an InputStream
// (could be from a resource or ByteArrayInputStream or ...)
CertificateFactory cf = CertificateFactory.getInstance("X.509");
// From https://www.washington.edu/itconnect/security/ca/load-der.crt
InputStream caInput = new BufferedInputStream(new FileInputStream("load-der.crt"));
Certificate ca;
try {
    ca = cf.generateCertificate(caInput);
    System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
    caInput.close();
}

// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);

// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);

// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);

// Tell the URLConnection to use a SocketFactory from our SSLContext
URL url = new URL("https://certs.cac.washington.edu/CAtest/");
HttpsURLConnection urlConnection =
    (HttpsURLConnection)url.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
InputStream in = urlConnection.getInputStream();
copyInputStreamToOutputStream(in, System.out);

Saturday, 16 July 2016

HB Blog 115: Chat Head Floating View Tutorial.

Android is an open source mobile operating system so, it can be modified it as per the needs.
Android SDK provides us with few in-built component views but, we need our own custom UI views for Android users.
Recently, Facebook came up with an attractive chat head UI view.
In this post, I will show how to create similar view that will run in background using our Android services and drag and drop events.
Refer the below link for complete sample code:-

Download Sample Code

Have a look on few code snippets,

//MainActivity.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class MainActivity extends Activity {
    Button startService,stopService;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startService=(Button)findViewById(R.id.startService);
        stopService=(Button)findViewById(R.id.stopService);
        startService.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                startService(new Intent(getApplication(), ChatHeadService.class));
            }
        });
        stopService.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                stopService(new Intent(getApplication(), ChatHeadService.class));
            }
        });}}

//ChatHeadService.java
 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
import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.Toast;

/**
 * Created by harshal.benake on 08-09-2015.
 */
public class ChatHeadService extends Service {

    private WindowManager windowManager;
    private ImageView chatHead;
    WindowManager.LayoutParams params;

    @Override
    public void onCreate() {
        super.onCreate();

        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

        chatHead = new ImageView(this);
        chatHead.setImageResource(R.drawable.ic_launcher);
        params= new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_PHONE,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT);

        params.gravity = Gravity.TOP | Gravity.LEFT;
        params.x = 0;
        params.y = 100;

        //this code is for dragging the chat head
        chatHead.setOnTouchListener(new View.OnTouchListener() {
            private int initialX;
            private int initialY;
            private float initialTouchX;
            private float initialTouchY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        initialX = params.x;
                        initialY = params.y;
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();
                        Toast.makeText(getApplicationContext(),"Comming soon",Toast.LENGTH_SHORT).show();
                        return true;
                    case MotionEvent.ACTION_UP:
                        return true;
                    case MotionEvent.ACTION_MOVE:
                        params.x = initialX+ (int) (event.getRawX() - initialTouchX);
                        params.y = initialY  + (int) (event.getRawY() - initialTouchY);
                        windowManager.updateViewLayout(chatHead, params);
                        return true;
                }
                return false;
            }
        });
        windowManager.addView(chatHead, params);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (chatHead != null)
            windowManager.removeView(chatHead);
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }
}
 
//AndroidManifest.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.chathead_as" >
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".ChatHeadService" >
        </service>
    </application>

</manifest>